在方向更改时,我无法让Fragment保留其实例。
活动类别
public class MyActivity extends Activity
{
private MyFragment fragment;
public void onCreate(Bundle savedInstanceState)
{
if(savedInstanceState == null)
{
fragment = new MyFragment();
}
//null pointer exception on this line of code. fragment not being retained.
getFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
}
}
碎片类
public class MyFragment extends Fragment
{
private View view;
private CustomListViewAdapter adapter;
public ArrayList<HashMap<String, String>> arrHashMap;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
view = inflater.inflate(R.layout.fragment_screen, container, false);
if(arrHashMap != null)
{
ListView lv = (ListView) view.findViewById(R.id.fragment_lv);
adapter = new CustomListViewAdapter( (MyActivity)getActivity() , arrHashMap);
lv.setAdapter(adapter);
lv.setOnItemClickListener((MyActivity)getActivity());
}
else
{
/* some code to create arrHashMap variable
*/
ListView lv = (ListView) view.findViewById(R.id.fragment_lv);
adapter = new CustomListViewAdapter( (MyActivity)getActivity() , arrHashMap);
lv.setAdapter(adapter);
lv.setOnItemClickListener((MyActivity)getActivity());
}
return(view);
}
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
}
}
尽管在onActivityCreated中设置了setRetainInstance(true),但MyFragment在方向更改时仍为null。创建MyActivity时,也总是重新创建MyFragment。此外,我知道setRetainInstance(true)不用于UI片段,但是,我没有使用保存的适配器或视图成员变量,我只是在方向更改时重用保留的arrHashMap变量,以便重新创建适配器并更改UI。
UPDATE:我决定根本不使用setRetainInstance(true),并使用ObjectInputStream和ObjectOutputStream类解决了问题,并将arrHashMap对象保存到MyActivity的onSaveInstanceState(Bundle-outState)方法中的文件中,并在MyActivity的onRestoreInstanceState(Bundle savedInstanceState)方法中从该文件中检索到arrHashMap对象。然后,我使用检索到的arrHashMap对象设置适配器。
作为补充说明,我将MyFragment的arrHashMap实例变量更改为静态变量,以便可以从MyActivity访问它。
保存代码:
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
try
{
File f = new File( this.getDir("myDir", Context.MODE_PRIVATE), "arrHashMap");
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(f));
os.writeObject(MyFragment.arrHashMap);
os.flush();
os.close();
}
catch(IOException e)
{
return;
}
}
恢复代码:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
ArrayList<HashMap<String,String>> arrHashMap;
try
{
File f = new File( this.getDir("myDir", Context.MODE_PRIVATE), "arrHashMap");
ObjectInputStream is = new ObjectInputStream(new FileInputStream(f));
arrHashMap = ((ArrayList<HashMap<String, String>>) is.readObject() );
is.close();
}
catch (Exception e)
{
arrHashMap = null;
}
if(arrHashMap != null)
{
ListView lv = (ListView)findViewById(R.id.fragment_lv);
CustomListViewAdapter adapter = new CustomListViewAdapter(this, arrHashMap);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
}
}
有点晚了,我希望这对你将来有帮助,但你的问题是
if(savedInstanceState == null)
{
fragment = new MyFragment();
}
getFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit();
setRetainInstance
意味着当应用程序被旋转时,片段将不会被重新创建,活动仍将被重新创建并且不会保存对它的引用
因此,当活动循环并检查savedInstanceState == null
时,它将不会创建片段,因此没有对其的引用
如果你想回去修复它,它应该是这样的(这是我的想法,所以可能存在一些错误)
首先创建一个表示片段的常量字符串,如下所示:
private static final String FRAGMENT = "myFragmentTag";
然后在初始化时
if (savedInstanceState == null) {
fragment = new MyFragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container,fragment,FRAGMENT).commit()
} else
fragment = getFragmentManager().findFragmentByTag(FRAGMENT)
基本上,当你创建活动时,你会生成片段,当你旋转它时,你可以从片段管理器