Domanda

I've an activity with two attributes:

  • private Fragment firstFragment;
  • private Fragment secondFragment;

In onCreate method:

    adapter = new MyPagerAdapter(getSupportFragmentManager());
    pager = (ViewPager) findViewById(R.id.pager);
    pager.setAdapter(adapter);
    pager.setOffscreenPageLimit(6);
    pager.setSaveEnabled(true);

where MyPagerAdapter extends FragmentStatePagerAdapter class. Into getItem() method:

    @Override
    public Fragment getItem(int position) {

        Bundle args = new Bundle();

        switch (position) {
            case FIRST:
                secondFragment = new FirstFragment();
                secondFragment.setArguments(args);
                return secondFragment;
            case SECOND:
                secondFragment = new SecondFragment();
                secondFragment.setArguments(args);
                return secondFragment;
        }
    }

and all works correctly.

But, when I change the screen orientation, the private attributes is set to null and I lost the reference of two fragments. So i've tried to serialized this fragment with:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, FirstFragment.class.getName(), firstFragment);
    getSupportFragmentManager().putFragment(outState, SecondFragment.class.getName(), secondFragment);
}

and load them into onCreate method with:

    if (savedInstanceState != null) {
        firstFragment = (FirstFragment) getSupportFragmentManager().getFragment(savedInstanceState, FirstFragment.class.getName());
        secondFragment = (SecondFragment) getSupportFragmentManager().getFragment(savedInstanceState, SecondFragment.class.getName());
    }

My questions:

1. Is it the correct way to serialized fragment into activity screen orientation changes?

2. Sometimes I've the error: "Unmarshalling unknown type code 55 at offset 448", is it possible that it has caused by fragment serialization?"

EDIT:

I need to have the fragments as activity attributes because I've a listener interface into activity that:

@Override
public void executeTask(String what) {
    secondFragment.executeTask(what);
}

this method was invoked into firstFragment. So the FirstFragment can execute a method of SecondFragment.

È stato utile?

Soluzione

I'm not sure what may be the cause of the problem but I'll give you a hint that may help.

I don't think that you should reference the Fragments in the Adapter from the Activity. Mainly due to the fact that it's pretty hard to synchronize the Activity life-cycle, Fragment lifecycle and ViewPager children life-cycles. And if any bugs emerge the debugging can be really painful. Believe me, been there, done that...

By the way - is there a reason why you need references to Fragments in your Activity ?

EDIT

I don't think you should pass the information between the Fragments this way. In general the FragmentManager handles (creates, deletes) Fragments on it's own and you cannot be sure that these Fragments will be available at any time.

I think that the best way would be to move your data to separate model (database entry, SharedPreference or a singelton class) and then letting know the Adapter that data has changed (by a DataObserver in Fragments or simply notify the Adapter to update children data by calling notifyDataChanged).

EXAMPLE

FragmentA --->listener (reloadData())--->Activity--->adapter.notifyDataChanged()-----> fragmentB gets updated

This way if you ever want to add a ThirdFragment or in fact any number of Fragments that will use the Data you will not have to worry about updating data in any of these - just let the Adapter worry about it.

Altri suggerimenti

If your using same layout for portrait and landscape then When orientation change you can avoid activity recreate. change your manifest as...

     <activity android:name=".activity.MainActivity"
        android:configChanges="keyboardHidden|orientation|screenSize">
     </activity>

and then override onConfigurationChanged() in activity ...

    @Override
     public void onConfigurationChanged(Configuration        newConfig)
    {
      super.onConfigurationChanged(newConfig);
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top