Kris B
Kris B

Reputation: 3578

Using findFragmentById with a ViewPager

My app has a list and detail view, where I allow the user to swipe between the different detail views, using a ViewPager in portrait. In landscape, I show both fragments on the screen.

I'm having an issue where, when the device is rotated, the icons are duplicating themselves over and over in the Actionbar. I've learned that I'm probably creating new fragments whenever the device is rotated and I should be checking if the fragment is in the FragmentManager and then create a new instance if it isn't.

I am able to do that easily using the landscape layout, however, I'm not sure how to check if the fragment exists in portrait mode, using the ViewPager. Do I do that in getItem() of the FragmentStatePagerAdapter?

This is the code I'm using:

public class Main extends SherlockFragmentActivity
{
    private static List<Integer> mIds;

    @Override
    public void onCreate(final Bundle icicle)
    {    
        super.onCreate(icicle);

        setContentView(R.layout.main);

        mViewPager = (ViewPager)findViewById(R.id.viewpager); //view pager exists, so we are using the portait layout

        if (mViewPager != null)
        {
            mIds = new ArrayList<Integer>();

            mIds.add(0);
            mIds.add(1);
            mIds.add(2);
        }
        else //in landscape
        {           
            ListFragment lf = (ListFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentList);

            if (lf == null)
                lf = new ListFragment();

            DetailFragment df = (DetailFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentDetail);

            if (df == null)
            {
                df = new DetailFragment();
                df.setArguments(getIntent().getExtras());   
            }

            getSupportFragmentManager().beginTransaction().add(R.id.fragmentList, lf).commit();
            getSupportFragmentManager().beginTransaction().add(R.id.fragmentDetail, df).commit();
        }
    }       

    private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter  {  

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

        @Override  
        public Fragment getItem(int index) {        
            //can't use getSupportFragmentManager().findFragmentById() here because I get a "Cannot make a static reference to the non-static method" error
            if (index == 0)
                return ListFragment.newInstance();
            else            
                return DetailFragment.newInstance(mIds.get(index-1));
        }  

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

Main Layout (portrait)

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

Main Layout (landscape)

<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"
>
    <FrameLayout 
        android:id="@+id/fragmentList"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
     />

    <FrameLayout 
        android:id="@+id/fragmentDetail"
        android:layout_width="0dp"
        android:layout_weight="2"
        android:layout_height="fill_parent"
     />

</LinearLayout>

List Fragment

public class ListFragment extends SherlockListFragment implements DialogKeywordAddListener
{
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setHasOptionsMenu(true);
    }

    public static ListFragment newInstance() {

        return new ListFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        return inflater.inflate(R.layout.listing, container, false);
    }
}

Detail Fragment

public class DetailFragment extends SherlockListFragment
{
    private int mId;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setHasOptionsMenu(true);
    }

    public static DetailFragment newInstance() {

        DetailFragment df = new DetailFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("id", id);
        df.setArguments(bundle);

        return df;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        if (getArguments() != null)
            mId = getArguments().getInt("id");

        return inflater.inflate(R.layout.detail, container, false);
    }
}

Upvotes: 3

Views: 2830

Answers (1)

Kris B
Kris B

Reputation: 3578

Well, this question's solution seemed to work for me. Just setting:

    super.onCreate(null);

in onCreate of the Activity solved my fragment issue.

Upvotes: 2

Related Questions