Avoiding manually handling configuration changes

后端 未结 2 1438
旧时难觅i
旧时难觅i 2020-12-22 03:44

This project is an extension of the Master/Detail flow template that can be found in Android Studio. The difference is that this application uses a single Activity and a Vie

相关标签:
2条回答
  • 2020-12-22 04:31

    Using the MVP pattern might help since Presenters can be created in a way such that they survive configuration changes. I recently came across a series of blog posts aimed at explaining such an implementation of the MVP pattern. I'm sure they'll be of help to you.

    Blogs posts: Part 1 Part 2

    0 讨论(0)
  • 2020-12-22 04:38

    You seem to have several issues needed to be fixed.

    First your link to mListener in SimpleItemRecyclerViewAdapter gets broken when activity is recreated. Hence you need to restore that connection after activity is recreated. To do that you need to do following fixes.

    Main Activity

    Make the PageFragmentListener accessible to outside by declaring it as a property

    public class MainActivity extends AppCompatActivity implements Bridge {
        ...
        PageChangeListener mListener = new PageChangeListener();
        //keep a reference to listener, need to access this from fragment
        PageFragmentListener mPageFragmentListener;
        ...
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ...
    
            mAdapter = new MyAdapter(getSupportFragmentManager());
            //set the listener
            mPageFragmentListener = mAdapter.mListener;
            ....
        }
    
    }
    

    ItemListFragment

    Override onActivityCreatedmethod in ItemListFragment and restore mListener by accessing it from the activity

    public class ItemListFragment extends BaseFragment{
        ...
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            Activity activity = getActivity();
            if(activity instanceof MainActivity) {
                mListener = ((MainActivity)activity).mPageFragmentListener;
        }
        ...
    }
    

    Now your mListener will be always set correctly when activity is recreated. But you have to do few more fixes for smoother operation.

    Your MyAdapter keep reference to an instance of fragment called mFragment. When activity recreated you need to restore this variable as well. Hence you need to modify your MyAdapter constructor as below.

    public MyAdapter(FragmentManager fm) {
        super(fm);
        mFragmentManager = fm;
        List<Fragment> fragments = fm.getFragments();
        if(fragments != null) {
            for (Fragment f : fragments) {
                if (f instanceof ItemListFragment || f instanceof ItemOneDetailFragment) {
                    mFragment = (BaseFragment) f;
                }
            }
        }
    }
    

    At this point your code should work. But it will crash when you rotate your device while viewing the detail of a list item. This happens because you add child fragments to the activity directly from your ItemListFragment using the Activity's FragmentManager. Instead use childFragmentManager from Fragment itself.

    holder.mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mTwoPane) {     // landscape mode
            ...
            // show detail fragment to right side of screen
            getChildFragmentManager().beginTransaction()
                .replace(R.id.item_detail_container, fragment)
                .commit();
            } else {    // portrait mode
                ...
            }
        }
    });
    
    0 讨论(0)
提交回复
热议问题