【问题标题】:onCreateOptionsMenu called twice on configuration changeonCreateOptionsMenu 在配置更改时调用了两次
【发布时间】:2016-05-02 21:54:56
【问题描述】:

我的应用有两个fragments,一个是列表,一个是详细视图,它们都以横向模式显示,只有列表以纵向显示。在配置更改时,如果我在两个fragmentsonCreateOptionsMenu 中放置一个断点,它们将被击中两次并且Actionbar 中的菜单项被复制。

我尝试在不同的事件中设置invalidateOptionsMenu,例如onResumeonActivityCreated,但这似乎没有帮助。我不确定是什么导致onCreateOptionsMenu 被击中两次。

我注意到有一个解决方案 here,但这对我不起作用。它会在Activity 上的onStart 中导致java.lang.IllegalArgumentException No view found for for fragment

更新

我在肖像模式下使用ViewPager 加载fragments

public class Main extends SherlockFragmentActivity
{
    private static List<Fragment> fragments;

    @Override
    public void onCreate(final Bundle icicle)
    {    
        setContentView(R.layout.main);
    }

    @Override
    public void onResume()
    { 
        mViewPager = (ViewPager)findViewById(R.id.viewpager);

               if (mViewPager != null)
               {

                  fragments = new ArrayList<Fragment>();

                  fragments.add(new MyListFragment());

                  fragments.add(MyDetailFragment.newInstance(0));
                  fragments.add(MyDetailFragment.newInstance(1));
                  fragments.add(MyDetailFragment.newInstance(2));

                  mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
                  mViewPager.setAdapter(mMyFragmentPagerAdapter);
               }
    }

    private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter  {  

        public MyFragmentPagerAdapter(FragmentManager fm) {  
             super(fm);  
        }  

        @Override  
        public Fragment getItem(int index) {
            return fragments.get(index);
        }  

        @Override
        public int getCount() {  
             return 4;  
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }
   }
}

在横向模式下,我正在通过 XML 添加fragments。这是layout-land 文件夹中的 main.xml 文件:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:weightSum="3"
>
    <fragment android:name="com.app.ListingFragment"
            android:id="@+id/fragmentDetails"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
     />

    <fragment android:name="com.app.DetailFragment" 
            android:id="@+id/fragmentDetails"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="fill_parent"
     />

</LinearLayout>

这是layout 文件夹中的 XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
     />

 </RelativeLayout>

【问题讨论】:

  • 请发布您的片段的解码代码。您是否在每个片段中添加不同的操作?是每个片段被调用两次(总共 4 次)还是每个片段只被调用一次?
  • 我会仔细检查您在布局中添加片段的部分。确保您的片段没有添加两次。
  • @RobertEstivill @rciovati 抱歉,我在添加fragments 的位置添加了代码。在横向模式下,我通过 XML 添加它们,在纵向模式下,我通过ViewPager 添加它们。我知道 ViewPager 下一个 fragment 已加载,出于性能考虑,这会导致问题吗?每个fragment 都被调用两次,一次用于列表,一次用于详细信息,即使在景观中也是如此。

标签: android android-fragments android-actionbar actionbarsherlock


【解决方案1】:

问题是您在布局文件中添加片段,并通过调用构造函数/newInstance 方法手动实例化它们。

如果你在布局上添加一个片段,android 框架会为你实例化它。在您发布的代码中,您总共有 4 个详细信息片段和 2 个列表片段实例,即使您可能无法全部看到它们。

您应该通过调用FragmentManager.getFragmentById 来检索它的实例,而不是手动实例化片段,并改用该实例。

对于细节片段,我会用一个普通布局替换它,而不是在布局上声明一个片段,你可以用它来添加你的寻呼机适配器

【讨论】:

  • 我不确定您所说的“将它们添加到布局文件并手动实例化它们”是什么意思?布局文件方式仅用于横向模式(它位于layout-land 文件夹中),而手动设置它们仅在纵向模式下发生。不是说要分开处理吗?我是新来使用fragmentsviewpagers 所以我可能只是误解了一些基本的东西。
  • 没有。无论设备处于什么方向,都会实例化该活动。您的代码中没有任何内容表明该活动仅在纵向上运行。如果您向布局文件添加任何内容,框架将为您实例化它,您不必调用它的构造函数,只需获取对已创建实例的引用即可。就像在布局中添加一个 TextView。您无需在 Activity 上再次实例化 TextView,您只需使用 findViewById 获取引用即可开始使用它。片段也会发生同样的事情。
  • 我知道混乱在哪里。我遗漏了检查viewpager 是否为activity 中的null 的代码。因此,如果设备处于纵向模式,它将使用包含viewpager 的布局。如果它是横向的,那么它使用的布局不包含viewpager,所以不应该进行双重实例化。我将更新 OP。对此感到抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多