问题是我有一个自定义 ListView 及其自己的适配器。但是当我改变屏幕方向时,该元素就会消失。我做了一些研究并尝试使用 onConfigurationChanged
但它对我不起作用。代码如下:
我无法将 android:configChanges="orientation|screenSize"
放入 AndroidManifest.xml 中,因为它是一个 fragment ,所以我将其放入 dataload_tab4.xml 中。
请不要关注其他代码。主要 ListView 初始化位于 InitView()
中。
Tab4.java(我有很多选项卡:D)
public class Tab4 extends Fragment {
private Button btnCertAdd, btnCertDel;
private ArrayList CertNames = new ArrayList(), CertNumbers= new ArrayList(), CertIssueDates= new ArrayList(), CertExpireDates= new ArrayList();
private ListViewAdapter listViewAdapter;
private FrameLayout frameLayout;
private ListView lv;
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
frameLayout = new FrameLayout(getActivity());
View view = inflater.inflate(R.layout.dataload_tab4, null);
InitView(view);
frameLayout.addView(view);
return frameLayout;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
frameLayout. removeAllViews();
LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.dataload_tab4, null);
listViewAdapter = new ListViewAdapter(this, CertNames, CertNumbers, CertIssueDates, CertExpireDates);
lv = view.findViewById(R.id.listview);
lv.setAdapter(listViewAdapter); // null - изначально ничего нет
frameLayout.addView(view);
}
private void InitView(View view)
{
btnCertAdd = view.findViewById(R.id.btnaddcert);
btnCertDel = view.findViewById(R.id.btndelcert);
listViewAdapter = new ListViewAdapter(this, CertNames, CertNumbers, CertIssueDates, CertExpireDates);
lv = view.findViewById(R.id.listview);
lv.setAdapter(listViewAdapter); // null - изначально ничего нет
}
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
}
只是为了形象化问题。 这是加载时的屏幕;我添加一些数据(从代码中删除它)
最佳答案
所以,我做了一些研究并自己找到了答案。
我没有找到正常方法来避免数据丢失,但我们仍然可以将其保存在savedInstanceState
中。
因此,我们需要将其添加到我们想要保存数据的 Fragment Activity 中。
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Here, you have to put some data in outState bundle, look below for an example
}
这是一个例子
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
int i = 0;
for (SailorExperience se:ExpsInfo) {
outState.putString(EXPINFO_KEY + String.valueOf(i) ,se.toString());
i++;
}
outState.putInt(savedInstanceExpCount_key, i);
i = 0;
for(String s:busyIDs){
outState.putString(BUSYIDS_KEY + String.valueOf(i),s);
i++;
}
outState.putInt(savedInstanceBusyIdsCount_key, i);
}
ExpsInfo
是我的自定义类的 ArrayList,
busyIds
是一个 String ArrayList
就我而言,我需要保存 ArrayList,因此我将此 ArrayList 的每个数据放入单个 .putString
中outState
bundle 。另外,我将此 ArrayList 的大小保存为另一个整数值。
完成所有操作后,您需要再次加载所有数据
因此您需要检查savedInstanceState
是否不null
。如果它不为空,则说明您已经保存了一些数据。 不要尝试传递一些私有(private)变量(它们不会被标记为已初始化,不知道它如何与公共(public)一起工作)。
例如,您需要在 onCreateView()
方法中添加以下代码:
if(savedInstanceState!=null){
for(int i = 0; i<savedInstanceState.getInt(savedInstanceExpCount_key); i++){
ExpsInfo.add(new SailorExperience(savedInstanceState.getString(EXPINFO_KEY + String.valueOf(i))));
}
for(int i=0; i<savedInstanceState.getInt(savedInstanceBusyIdsCount_key);i++){
busyIDs.add(savedInstanceState.getString(BUSYIDS_KEY + String.valueOf(i)));
}
}
我在主 UI 加载之前执行这部分代码。
如果我帮助解决了您的问题,请确保您留下了+代表。 ^_^
关于java - 自定义 ListView 在 Fragment 中旋转时消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49174237/