强制让Android Fragment重新构建视图

14

我有一个简单的应用程序,其中有两个片段。在横向模式下,两个片段并排显示,在纵向模式下,我显示Fragment A,然后如果用户选择选项,启动一个Activity来显示Fragment B。我的问题是,当我处于纵向模式并显示Fragment B时,如果用户选择菜单选项,我想要刷新或重绘与Fragment B相关联的视图,但无法理解如何使其工作。我尝试了getView方法和getLayoutInflater方法,但屏幕没有变化,因为我认为我正在创建一个新视图。我还试图获取对Fragment A的引用,以为我可以调用它的例程来构建一个新片段并替换Fragment B,但无法获取对它的引用,因为它没有被显示。我真正需要做的就是强制再次调用onCreateView方法来填充新视图,但我尝试了几种方法来尝试这样做,但无法再次调用onCreateView。您有什么想法怎么做吗?

2个回答

9

您需要执行一个 FragmentTransaction 并使用 replace() 方法。

这并不难做,但答案取决于您的菜单位于哪里(即,您的 onOptionsItemSelected() 回调是否在父 Activity 中,还是在 A/B Fragment 中?)。

为了简单起见,假设您的菜单实现和 onOptionsItemSelected() 在父 Activity 中,并且您想在选择 menu_option1 时重新设置片段。代码如下:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
//...
switch (item.getItemId()) {
case R.id.menu_option1:
    //do something
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment newFragment = new YourFragmentClass();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.your_fragment_id, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
    return true;
case R.id.menu_option2:
    //do something else;
    return true;
default:
    return super.onOptionsItemSelected(item);
}
}

如果您的菜单是Fragment的子菜单(为了更方便地重用代码,应该这样设计),那么一种方法是要求托管Fragment的Activity实现由Fragment定义的接口,该接口可用作回调。在您的Fragment类中的onOptionsItemSelected()回调中,只需调用此回调方法即可。
虽然听起来很复杂,但实际上您只需要做几件事情。假设这是您的Fragment类。
public static class FragmentA extends ListFragment {
OnSelectedListener mListener;
// Container Activity must implement this interface
public interface OnSelectedListener {
    public void onSelected();
}
...
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    //This is to ensure that the Activity has implemented the interface we set up above
    try {
        mListener = (OnSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnSelectedListener");
    }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
//...
switch (item.getItemId()) {
case R.id.menu_option1:
    //do something
    getActivity().onSelected();
    return true;
case R.id.menu_option2:
    //do something else;
    return true;
default:
    return super.onOptionsItemSelected(item);
}
}
...
}

然后在Activity中,你会看到类似下面的东西:
public class MainActivity extends Activity implements FragmentA.onSelectedListener{
...
public void onSelected(){
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment newFragment = new YourFragmentClass();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.your_fragment_id, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}
}

7
如果你正在替换 R.id.your_fragment_id,那么你假设它是在 XML 中声明的。但是如果我的原始 fragment 是通过编程构建的呢? - IgorGanapolsky
1
@IgorGanapolsky 这将是该片段容器的ID。 - dmSherazi

1
如果用户选择了菜单选项,我想刷新或重绘与 Fragment B 相关联的视图,但不知道如何实现。
onOptionsItemSelected() 中,让活动调用片段上的一个方法,使其使用新内容更新其小部件。或者,让活动执行一个 FragmentTransaction 来替换片段(如果片段最初是通过 FragmentTransaction 设置的)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接