在使用FragmentPagerAdapter时,我在查找片段之间的正确通信方式时遇到了一些麻烦。
对于某些上下文,我有一个Activity,它使用FragmentPagerAdapter来托管两个片段。片段A有一个按钮,按下它时会更改片段B中的文本。
一切都按预期工作,除非我在方向更改后按下按钮,我在EditText上得到一个空指针异常我在片段B中更改。经过几天的调试后,它看起来就像我在片段B中调用方法时那样更改文本,它可能是片段的旧实例。
以下是代码:
FragmentPagerAdapter,它是我的Activity中的内部类:
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter (FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int i) {
switch (i) {
case 0:
return fragmentA;
case 1:
return fragmentB;
}
return null;
}
@Override
public int getCount() {
return tabs.length;
}
@Override
public CharSequence getPageTitle(int position) {
return tabs[position];
}
}
Fragments在Activities onCreate方法中实例化,如下所示:
FragmentA fragmentA; //Declared outside of onCreate
FragmentB fragmentB; //Declared outside of onCreate
fragmentA = FragmentA.newInstance();
fragmentB = FragmentB.newInstance();
在片段中,我按下按钮,我按如下方式设置界面:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
testTextInterface = (TestTextInterface) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement testTextInterface");
}
}
然后当我按下按钮时,我有一个触发以下代码的OnClickListener:
testTextInterface.onTextChanged("Some test text");
反过来调用Activity中的以下方法:
@Override
public void onTextChanged(String testText) {
fragmentB.updateText(testText);
}
最后在FragmentB中使用该方法:
private void updateText(String incomingText){
myEditText.setText(incomingText);
}
就是这样,在我旋转设备导致重新创建活动之前,这非常有效。然后,当我按下按钮时,updateText方法中的FragmentB中的myEditText视图为空。
我一直试图找出为期2天的原因,所以我想知道是否有人能够发现我出错的地方或指出我正确的方向,我可能会在哪里注意导致问题的原因?
答案 0 :(得分:1)
问题在于,当您旋转时,Android会为您创建片段的新实例,但您没有获得对这些新实例的引用。如果不在活动中保留对片段的引用会更安全,而是在需要时使用findFragmentByTag。
@Override
public void onTextChanged(String testText) {
Fragment fragmentB = getFragmentManager().findFragmentByTag("FragmentB");
fragmentB.updateText(testText);
}
当然,请确保以XML或代码设置片段的标记。
答案 1 :(得分:1)
我同意布鲁斯的意见,但如果你确实需要在活动中保留对片段的引用,你可以这样做:
在您的活动中,实施一种方法,让我们说'setFragmentInstance'。
在您的片段中,覆盖onActivityCreated方法,您可以在其中将活动强制转换为活动(如果片段始终保留在该活动中)并调用该setFragmentInstance方法,或者您也可以在片段中添加接口,实现它活动并调用onActivityCreated中的接口方法来设置片段实例。
之前我曾问过一个类似的问题,但在此之后我很清楚,请参阅DialogFragment members becomes null after screen rotation