方向改变后无法正确与Fragment通信

时间:2014-11-20 21:41:31

标签: java android android-fragments fragment fragmentpageradapter

在使用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天的原因,所以我想知道是否有人能够发现我出错的地方或指出我正确的方向,我可能会在哪里注意导致问题的原因?

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