1

My app has two fragments, one a listing and one a detail view, which are both shown in landscape mode and only the listing is shown in portait. On configuration change, if I put a breakpoint in onCreateOptionsMenu of both fragments, they are being hit twice and the menu items in the Actionbar are being duplicated.

I tried setting invalidateOptionsMenu in different events, like onResume and onActivityCreated, but that doesn't seem to help. I'm not sure what would cause onCreateOptionsMenu to be hit twice.

I noticed there was a solution here, but that doesn't work for me. It causes a java.lang.IllegalArgumentException No view found for for fragment in onStart on the Activity.

UPDATE

I am using a ViewPager to load the fragments when in portait mode:

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;
        }
   }
}

and it landscape mode I am adding the fragments via XML. This is the main.xml file in a layout-land folder:

<?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>

This is the XML in the layout folder:

<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>
Community
  • 1
  • 1
Kris B
  • 3,436
  • 9
  • 64
  • 106
  • 1
    Please post de code of your fragments. Are you adding different actions in each of the fragments? are they being called twice each ( 4 times in total ) or just one time each of the fragments? – Robert Estivill Feb 03 '13 at 02:00
  • I would double check the part where you add your fragment in you layout. Make sure your fragments are not added twice. – rciovati Feb 03 '13 at 09:12
  • @RobertEstivill @rciovati Sorry, I added the code where I'm adding the `fragments`. In landscape mode I'm adding them via XML and in portrait I'm adding them via a `ViewPager`. I know with a `ViewPager` the next `fragment` is loaded, for performance, could that be causing the issue? Each `fragment` is called twice, once for the listing and once for the details, even in landcape. – Kris B Feb 03 '13 at 18:01

1 Answers1

2

The problem is that you are adding the fragments on the layout file, and also instantiating them manually by calling the constructor/newInstance method.

If you add a fragment on the layout, the android framework will instantiate it for you. In the code you posted, you are having 4 Details fragment and 2 list fragments instances total, even though you might not be able to see them all.

Instead of instantiating the fragments manually, you should retrieve it's instance by calling FragmentManager.getFragmentById and use that instance instead.

For the details fragments, instead of having one fragment declaration on the layout, i would replace it with a normal layout that you can use to add your pager adapter

Robert Estivill
  • 12,369
  • 8
  • 43
  • 64
  • I'm not sure what you mean by "adding them on the layout file and also instantiating them manually"? The layout file way is only used in landscape mode (it's in a `layout-land` folder), while the instatiating them manually happen in portait mode only. Wouldn't that mean they are handled separately? I'm new to using `fragments` and `viewpagers` so I may just be misunderstanding something basic. – Kris B Feb 04 '13 at 14:43
  • No. The activity is instantiated no matter what orientation the device is in. There's nothing on your code that points to the fact that the activity only runs on portrait. If you add anything to a layout file, the framework will instantiate it for you, you don't have to call it's constructor, just get the reference to the already created instance. Is like adding a TextView to the layout. You don't instantiate the TextView again on your activity, you just get the reference with findViewById to start working with it. The same thing happens with fragments. – Robert Estivill Feb 04 '13 at 15:04
  • I see where the confusion is. I left out code where I'm checking if the `viewpager` is `null` in the `activity`. So if the device is in portrait mode it's using the layout that contains the `viewpager`. If it's in landscape, then it's using the layout that doesn't contain the `viewpager`, so there shouldn't be the double-instantiating going on. I will update the OP. Sorry about that. – Kris B Feb 04 '13 at 16:41