避免手动操作的配置更改 [英] Avoiding manually handling configuration changes

查看:213
本文介绍了避免手动操作的配置更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这项目是可以在Android中Studio中发现了主/流模板的延伸。不同的是,本申请中使用单个活动和管理三个片段一个ViewPager。第三个片段是硕士(名单)片段,其中包含一个可点击的RecycleView。当单击列表项,它切换与儿童(细节)片段片段。

虽然项目工程,我想尽量避免使用的android:configChanges =方向|屏幕尺寸| keyboardHidden在清单。我应该怎么办呢?

如果该属性被删除,mListener在ItemListFragment与ItemFragmentList旋转时,但重新创建ItemListFragment时从未重新创建沿着销毁。这导致没有在人像模式一个列表项点击时发生。

我最初的解决办法是手动覆盖配置更改的处理,这意味着旋转屏幕时ItemListFragment都没有被破坏。 onConfigurationChanged() populateViewForOrientation()添加到重新膨胀的布局。当然还有比手动覆盖配置处理一个更好的解决方案。

在项目可供选择: https://github.com/lukeallison/ViewPagerMasterDetail
视频: http://tinypic.com/r/1zltyeq/9

BaseFragment.java

 公共类BaseFragment扩展片段{    公桥mBridget;    @覆盖
    公共无效onAttach(活动活动){
        super.onAttach(活动);
        mBridget =(MainActivity)getActivity();
    }
}

接口:Bridge.java

 公共接口大桥{
    抽象无效onBack();
}

ItemListFragment.java

 公共类ItemListFragment扩展BaseFragment {    私人布尔mTwoPane = FALSE;
    私人PageFragmentListener mListener;    公共静态的newInstance ItemListFragment(PageFragmentListener监听){
        ItemListFragment片段=新ItemListFragment();
        fragment.mListener =侦听器;
        返回片段;
    }    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,捆绑savedInstanceState){
        查看根= inflater.inflate(R.layout.fragment_item_list,集装箱,FALSE);
        InitLayout在(根);
        返回根;
    }    @覆盖
    公共无效onConfigurationChanged(配置NEWCONFIG){
        super.onConfigurationChanged(NEWCONFIG);        LayoutInflater充气= LayoutInflater.from(getActivity());
        populateViewForOrientation(充气,(的ViewGroup)getView());
    }    私人无效populateViewForOrientation(LayoutInflater吹气,ViewGroup中的ViewGroup){
        viewGroup.removeAllViewsInLayout();
        查看子视图= inflater.inflate(R.layout.fragment_item_list,ViewGroup中);        InitLayout在(子视图);
    }    公共无效InitLayout在(查看根){
        查看recyclerView = root.findViewById(R.id.item_list);        mTwoPane = FALSE;
        如果(root.findViewById(R.id.item_detail_container)!= NULL){// R.layout.list_item位于布局,布局土地..
            mTwoPane = TRUE; //当前加载布局土地/ LIST_ITEM。风景模式
        }        工具条工具栏=(栏)root.findViewById(R.id.toolbar);
        ((AppCompatActivity)getActivity())setSupportActionBar(工具栏)。
        toolbar.setTitle(列表);
        断言recyclerView!= NULL;
        SETU precyclerView((RecyclerView)recyclerView);
    }    私人无效SETU precyclerView(RecyclerView recyclerView){
        recyclerView.setAdapter(新SimpleItemRecyclerViewAdapter(DummyContent.ITEMS));
    }    公共类SimpleItemRecyclerViewAdapter
            扩展RecyclerView.Adapter< SimpleItemRecyclerViewAdapter.ViewHolder> {        私人最终名单< D​​ummyContent.DummyItem> mValues​​;        公共SimpleItemRecyclerViewAdapter(列表< D​​ummyContent.DummyItem>项目){
            mValues​​ =物品;
        }        @覆盖
        公共ViewHolder onCreateViewHolder(ViewGroup中的父母,INT viewType){
            查看查看= LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_list_content,父母,假);
            返回新ViewHolder(视图);
        }        @覆盖
        公共无效onBindViewHolder(最终ViewHolder持有人,INT位置){
            holder.mItem = mValues​​.get(位置);
            holder.mIdView.setText(mValues​​.get(位置).ID);
            holder.mContentView.setText(mValues​​.get(位置).content);            //列表中的一个排。定义click事件
            holder.mView.setOnClickListener(新View.OnClickListener(){
                @覆盖
                公共无效的onClick(视图v){
                    如果(mTwoPane){//风景模式
                        捆绑参数=新包();
                        arguments.putString(Constants.ARG_ITEM_ID,holder.mItem.id);
                        ItemTwoDetailFragment片段= ItemTwoDetailFragment.newInstance();
                        fragment.setArguments(参数);                        //显示细节片段屏幕的右侧
                        getActivity()。getSupportFragmentManager()调用BeginTransaction()
                                .replace(R.id.item_detail_container,片段)
                                。承诺();
                    }其他{//肖像模式
                        如果(mListener!= NULL)
                            mListener.onSwitchToNextFragment(holder.mItem.id); //开关细节片段
                    }
                }
            });
        }        @覆盖
        公众诠释getItemCount(){
            返回mValues​​.size();
        }        公共类ViewHolder扩展RecyclerView.ViewHolder {
            公众最终视图MView的;
            公众最终的TextView mIdView;
            公众最终的TextView mContentView;
            公共DummyContent.DummyItem MITEM;            公共ViewHolder(查看视图){
                超(视图);
                MVIEW =视图。
                mIdView =(TextView中)view.findViewById(R.id.id);
                mContentView =(TextView中)view.findViewById(R.id.content);
            }            @覆盖
            公共字符串的toString(){
                返回super.toString调用()+'+ mContentView.getText()+';
            }
        }
    }}

ItemOneDetailFragment.java

  / **
 *片段重新presenting单个项目的细节画面。
 *在手机上。
 * /
公共类ItemOneDetailFragment扩展BaseFragment {    私人DummyContent.DummyItem MITEM;    / *
    监听器开关片段
     * /
    私人PageFragmentListener mListener;    公共静态的newInstance ItemOneDetailFragment(PageFragmentListener监听){
        ItemOneDetailFragment片段=新ItemOneDetailFragment();
        fragment.mListener =侦听器;
        返回片段;
    }    公共ItemOneDetailFragment(){
    }    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);        如果(getArguments()。的containsKey(Constants.ARG_ITEM_ID)){
            MITEM = DummyContent.ITEM_MAP.get(getArguments()的getString(Constants.ARG_ITEM_ID)); //获取选择项ID显示细节
        }
    }    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
                             捆绑savedInstanceState){        查看rootView = inflater.inflate(R.layout.fragment_item_one_detail,集装箱,FALSE);        //显示虚拟内容作为一个TextView文本。
        如果(MITEM!= NULL){            工具条工具栏=(栏)rootView.findViewById(R.id.detail_toolbar);
            toolbar.setTitle(mItem.content);
            toolbar.setNavigationIcon(R.drawable.ic_ab_back_material);
            toolbar.setNavigationOnClickListener(新View.OnClickListener(){
                @覆盖
                公共无效的onClick(视图v){
                    mBridget.onBack();
                }
            });            ((的TextView)rootView.findViewById(R.id.item_detail))的setText(mItem.details); //显示详细信息
        }        返回rootView;
    }}

ItemTwoDetailFragment.java

  //为横向
公共类ItemTwoDetailFragment扩展BaseFragment {    私人DummyContent.DummyItem MITEM;
    公共静态的newInstance ItemTwoDetailFragment(){
        返回新ItemTwoDetailFragment();
    }    公共ItemTwoDetailFragment(){
    }    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);        如果(getArguments()。的containsKey(Constants.ARG_ITEM_ID)){
            MITEM = DummyContent.ITEM_MAP.get(getArguments()的getString(Constants.ARG_ITEM_ID)); //获取选定的项目,以显示细节
        }
    }    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
                             捆绑savedInstanceState){
        查看rootView = inflater.inflate(R.layout.fragment_item_two_detail,集装箱,FALSE);        //显示虚拟内容作为一个TextView文本。
        如果(MITEM!= NULL){
            ((的TextView)rootView.findViewById(R.id.item_detail))的setText(mItem.details); //显示详细信息
        }
        返回rootView;
    }
}

MainActivity.java

 公共类MainActivity扩展AppCompatActivity实现大桥{    私人ViewPager viewPager = NULL;
    私人MyAdapter mAdapter;
    PageChangeListener mListener =新PageChangeListener();    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        viewPager =(ViewPager)findViewById(R.id.pager);
        viewPager.setOnPageChangeListener(mListener); //改换监听器        mAdapter =新MyAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);        //显示操作栏中的向上按钮。
        动作条动作条= getSupportActionBar();
        如果(动作条!= NULL){
            actionBar.setDisplayHomeAsUpEnabled(真);
        }
    }    @覆盖
    公共无效onBack pressed(){
        如果(mListener.getCurrentPage()== 2及和放大器; mAdapter.mFragment的instanceof ItemOneDetailFragment){//当前页面制表3,当前片段的细节片段
            mAdapter.mListener.onSwitchToNextFragment(0); //显示列表片段
            返回; // prevent完成的应用程序。
        }        super.onBack pressed();
    }    //做同样的事情,后退按钮 - 回到ItemListFragment
    //只有在ItemOneDetailFragment时
    @覆盖
    公共布尔onOptionsItemSelected(菜单项项){
        INT ID = item.getItemId();
        如果(ID == android.R.id.home){
            如果(mListener.getCurrentPage()== 2及和放大器; mAdapter.mFragment的instanceof ItemOneDetailFragment){//当前页面制表3,当前片段的细节片段
                mAdapter.mListener.onSwitchToNextFragment(0); //显示列表片段
//返回; // prevent完成的应用程序。
            }
        }
        返回super.onOptionsItemSelected(项目);
    }    @覆盖
    公共无效onBack(){
        onBack pressed();
    }
}类PageChangeListener扩展ViewPager.SimpleOnPageChangeListener {
    私人诠释当前页;    @覆盖
    公共无效使用onPageSelected(INT位置){
        当前是=位置; //当前选定的页面
    }    公众最终诠释getCurrentPage(){
        返回当前页;
    }
}/ **
 *片段页适配器
 * /
类MyAdapter扩展FragmentPagerAdapter {    私人最终FragmentManager mFragmentManager;
    公共BaseFragment mFragment;    / **
     * PageFragmentListener切换片段。
     * /
    公共PageFragmentListener mListener =新PageFragmentListener(){
        @覆盖
        公共无效onSwitchToNextFragment(最后弦乐ID){
            。mFragmentManager.beginTransaction()删除(mFragment).commit();
            如果(mFragment的instanceof ItemListFragment){//当前片段列表片段
                捆绑参数=新包();
                arguments.putString(Constants.ARG_ITEM_ID,身份证); //选定的项目编号
                mFragment = ItemOneDetailFragment.newInstance(mListener); //开关细节片段
                mFragment.setArguments(参数);
            }其他{// DetailFragment
                mFragment = ItemListFragment.newInstance(mListener); // =>开关列表片段
            }            notifyDataSetChanged(); //更改通知
        }
    };    公共MyAdapter(FragmentManager FM){
        超(FM);
        mFragmentManager =调频;
    }    @覆盖
    公共片段的getItem(INT位置){
        如果(位置== 0)//制表1
            返回FragmentA.newInstance();        如果(位置== 1)//制表2
            返回FragmentB.newInstance();        如果(位置== 2){//制表3
            如果(mFragment == NULL)//第一次= GT;创建列表片段
                mFragment = ItemListFragment.newInstance(mListener);            返回mFragment;
        }        返回null;
    }
    @覆盖
    公共CharSequence的getPageTitle(INT位置){
        如果(位置== 0){//制表1
            返回标签1;
        }
        如果(位置== 1){//制表2
            返回选项卡2;
        }
    如果(位置== 2){//制表3
            返回标签3;
        }
        返回null;
    }    @覆盖
    标签的公众诠释的getCount(){//计数
        返回3;
    }    @覆盖
    公众诠释getItemPosition(Object对象){
        Log.i(适配器,ItemPosition>>>中+ object.toString());
        如果(对象的instanceof ItemListFragment&放大器;&安培; mFragment的instanceof ItemOneDetailFragment){//改变片段
            返回POSITION_NONE;
        }        如果(对象的instanceof ItemOneDetailFragment&放大器;&安培; mFragment的instanceof ItemListFragment){//改变片段
            返回POSITION_NONE;
        }        返回POSITION_UNCHANGED;
    }
}

接口:PageFragmentListener.java

 公共接口PageFragmentListener {
    无效onSwitchToNextFragment(字符串ID);
}

日志:通过属性添加到的Manifest.xml

 第一个实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onCreate()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onCreateView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onBindViewHolderClickItem
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onClick():单窗格
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:删除的片段
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:是列表片段实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemOneDetailFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> FragmentB {41dd3810#1 ID = 0x7f0c0069安卓切换:2131492969:1}
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> ItemListFragment {41df1528#2 ID = 0x7f0c0069安卓切换:2131492969:2}
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onStop()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onDestroyView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onDestroy()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()背部
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:删除的片段
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:是详细片段实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> FragmentB {41dd3810#1 ID = 0x7f0c0069安卓切换:2131492969:1}
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> ItemOneDetailFragment {41e896a8#2 ID = 0x7f0c0069安卓切换:2131492969:2}
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onCreate()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onCreateView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()旋转
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onConfigurationChanged
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:populateViewForOrientation
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onBindViewHolderClickItemLand
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onClick():mTwoPane旋转
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onConfigurationChanged
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:populateViewForOrientation
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onBindViewHolderClickIemPortrait
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onClick():单窗格
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:删除的片段
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:是列表片段实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemOneDetailFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> FragmentB {41dd3810#1 ID = 0x7f0c0069安卓切换:2131492969:1}
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> ItemListFragment {41ea8b68#2 ID = 0x7f0c0069安卓切换:2131492969:2}
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onStop()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onDestroyView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onDestroy()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()

日志:无属性。

 第一个实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onCreate()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onCreateView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onBindViewHolderClickItem
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onClick():单窗格
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:删除的片段
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:是列表片段实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemOneDetailFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> FragmentB {41dd4758#1 ID = 0x7f0c0069安卓切换:2131492969:1}
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> ItemListFragment {41ded998#2 ID = 0x7f0c0069安卓切换:2131492969:2}
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onStop()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onDestroyView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onDestroy()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()背部
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:删除的片段
03-16 ... / com.allison.viewpagermasterdetail D / MyAdapter:是详细片段实例
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的newInstance
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> FragmentB {41dd56b8#1 ID = 0x7f0c0069安卓切换:2131492969:1}
03-16 ... / com.allison.viewpagermasterdetail I /适配器:ItemPosition>>> ItemOneDetailFragment {41e830b8#2 ID = 0x7f0c0069安卓切换:2131492969:2}
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onCreate()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onCreateView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onBindViewHolder旋转
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onSaveInstanceState()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onStop()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onDestroyView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onDestroy()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onCreate()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onCreateView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()ClickItemLand
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onClick():mTwoPane旋转
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onSaveInstanceState()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onStop()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onDestroyView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onDestroy()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onPause()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:的onCreate()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onCreateView()
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:InitLayout在
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:SETU precyclerView()
03-16 ... / com.allison.viewpagermasterdetail E / ViewRootImpl:sendUserActionEvent()== MView的空
03-16 ... / com.allison.viewpagermasterdetail D / ItemListFragment:onBindViewHolderClickIemPortrait
// 什么都没发生


解决方案

您似乎有需要修复的几个问题。

首先,当活动被重新创建你的 SimpleItemRecyclerViewAdapter 链接 mListener 被打破。因此,你需要的活动被重建后恢复该连接。要做到这一点,你需要做以下修复。

主要活动

请外面的 PageFragmentListener 通过访问其声明为一个属性。

 公共类MainActivity扩展AppCompatActivity实现大桥{
    ...
    PageChangeListener mListener =新PageChangeListener();
    //保持侦听器的引用,需要从片段访问此
    PageFragmentListener mPageFragmentListener;
    ...    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        ...        mAdapter =新MyAdapter(getSupportFragmentManager());
        //设置监听器
        mPageFragmentListener = mAdapter.mListener;
        ....
    }}

ItemListFragment

ItemListFragment

覆盖 onActivityCreated 法和恢复 mListener 从活动访问它

 公共类ItemListFragment扩展BaseFragment {
    ...
    @覆盖
    公共无效onActivityCreated(捆绑savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        活动活动= getActivity();
        如果(的instanceof MainActivity活动){
            mListener =((MainActivity)活性).mPageFragmentListener;
    }
    ...
}

现在你的 mListener 将正确始终设置活动时被重建。但是,你要为更流畅的操作做一些更多的补丁。

MyAdapter 继续参考称为片段的实例 mFragment 。当活动重新您需要恢复该变量为好。因此,你需要如下修改 MyAdapter 构造。

 公共MyAdapter(FragmentManager FM){
    超(FM);
    mFragmentManager =调频;
    清单<片断>片段= fm.getFragments();
    如果(片段!= NULL){
        对于(片段F:片段){
            如果(F的instanceof ItemListFragment ||˚F的instanceof ItemOneDetailFragment){
                mFragment =(BaseFragment)F;
            }
        }
    }
}

在这一点上你的code应该工作。但是,当你旋转你的设备在查看列表项的细节就会崩溃。这是因为您直接从添加子片段活动您使用活动的 FragmentManager ItemListFragment 。而是使用childFragmentManager从片段本身。

  holder.mView.setOnClickListener(新View.OnClickListener(){
    @覆盖
    公共无效的onClick(视图v){
        如果(mTwoPane){//风景模式
        ...
        //显示细节片段屏幕的右侧
        getChildFragmentManager()调用BeginTransaction()
            .replace(R.id.item_detail_container,片段)
            。承诺();
        }其他{//肖像模式
            ...
        }
    }
});

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 ViewPager that manages three Fragments. The third Fragment is the Master (list) Fragment, which contains a clickable RecycleView. When a list item is clicked, it switches the Fragment with the Child (detail) Fragment.

While the project works, I'd like to avoid using android:configChanges= "orientation|keyboardHidden|screenSize" in the manifest. How should I do this?

If the attribute is removed, mListener in ItemListFragment is destroyed along with ItemFragmentList when rotating but is never re-created when ItemListFragment is re-created. This results in nothing happening when clicking on a List item in Portrait mode.

My initial solution was to manually override the configuration change handling, which meant ItemListFragment was not destroyed when rotating the screen. onConfigurationChanged() and populateViewForOrientation() were added to re-inflate the layout. Surely there is a better solution than to manually override configuration handling.

Project available at: https://github.com/lukeallison/ViewPagerMasterDetail, Video: http://tinypic.com/r/1zltyeq/9

BaseFragment.java

public class BaseFragment extends Fragment {

    public Bridge mBridget;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mBridget = (MainActivity) getActivity();
    }
}

Interface: Bridge.java

public interface Bridge {
    abstract void onBack();
}

ItemListFragment.java

public class ItemListFragment extends BaseFragment{

    private boolean mTwoPane = false;
    private PageFragmentListener mListener;

    public static ItemListFragment newInstance(PageFragmentListener listener) {
        ItemListFragment fragment = new ItemListFragment();
        fragment.mListener = listener;
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_item_list, container, false);
        initLayout(root);
        return root;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        LayoutInflater inflater = LayoutInflater.from(getActivity());
        populateViewForOrientation(inflater, (ViewGroup) getView());
    }

    private void populateViewForOrientation(LayoutInflater inflater, ViewGroup viewGroup) {
        viewGroup.removeAllViewsInLayout();
        View subview = inflater.inflate(R.layout.fragment_item_list, viewGroup);

        initLayout(subview);
    }

    public void initLayout(View root) {
        View recyclerView = root.findViewById(R.id.item_list);

        mTwoPane = false;
        if (root.findViewById(R.id.item_detail_container) != null) {        // R.layout.list_item is located "layout", "layout-land"..
            mTwoPane = true;            // currently loaded "layout-land/list_item".  landscape mode
        }

        Toolbar toolbar = (Toolbar) root.findViewById(R.id.toolbar);
        ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
        toolbar.setTitle("List");
        assert recyclerView != null;
        setupRecyclerView((RecyclerView) recyclerView);
    }

    private void setupRecyclerView(RecyclerView recyclerView) {
        recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(DummyContent.ITEMS));
    }

    public class SimpleItemRecyclerViewAdapter
            extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {

        private final List<DummyContent.DummyItem> mValues;

        public SimpleItemRecyclerViewAdapter(List<DummyContent.DummyItem> items) {
            mValues = items;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_list_content, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, int position) {
            holder.mItem = mValues.get(position);
            holder.mIdView.setText(mValues.get(position).id);
            holder.mContentView.setText(mValues.get(position).content);

            // One row of List.  define click event
            holder.mView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mTwoPane) {     // landscape mode
                        Bundle arguments = new Bundle();
                        arguments.putString(Constants.ARG_ITEM_ID, holder.mItem.id);
                        ItemTwoDetailFragment fragment = ItemTwoDetailFragment.newInstance();
                        fragment.setArguments(arguments);

                        // show detail fragment to right side of screen
                        getActivity().getSupportFragmentManager().beginTransaction()
                                .replace(R.id.item_detail_container, fragment)
                                .commit();
                    } else {    // portrait mode
                        if (mListener!=null)
                            mListener.onSwitchToNextFragment(holder.mItem.id);      // switch detail fragment
                    }
                }
            });
        }

        @Override
        public int getItemCount() {
            return mValues.size();
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
            public final View mView;
            public final TextView mIdView;
            public final TextView mContentView;
            public DummyContent.DummyItem mItem;

            public ViewHolder(View view) {
                super(view);
                mView = view;
                mIdView = (TextView) view.findViewById(R.id.id);
                mContentView = (TextView) view.findViewById(R.id.content);
            }

            @Override
            public String toString() {
                return super.toString() + " '" + mContentView.getText() + "'";
            }
        }
    }

}

ItemOneDetailFragment.java

/**
 * A fragment representing a single Item detail screen.
 * on handsets.
 */
public class ItemOneDetailFragment extends BaseFragment {

    private DummyContent.DummyItem mItem;

    /*
    Listener for switch fragment
     */
    private PageFragmentListener mListener;

    public static ItemOneDetailFragment newInstance(PageFragmentListener listener) {
        ItemOneDetailFragment fragment = new ItemOneDetailFragment();
        fragment.mListener = listener;
        return fragment;
    }

    public ItemOneDetailFragment() {
    }

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

        if (getArguments().containsKey(Constants.ARG_ITEM_ID)) {
            mItem = DummyContent.ITEM_MAP.get(getArguments().getString(Constants.ARG_ITEM_ID)); // Get selected Item ID to show details
        }
    }

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

        View rootView = inflater.inflate(R.layout.fragment_item_one_detail, container, false);

        // Show the dummy content as text in a TextView.
        if (mItem != null) {

            Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.detail_toolbar);
            toolbar.setTitle(mItem.content);
            toolbar.setNavigationIcon(R.drawable.ic_ab_back_material);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mBridget.onBack();
                }
            });

            ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.details);    // show details
        }

        return rootView;
    }

}

ItemTwoDetailFragment.java

// for landscape orientation
public class ItemTwoDetailFragment extends BaseFragment {

    private DummyContent.DummyItem mItem;


    public static ItemTwoDetailFragment newInstance() {
        return new ItemTwoDetailFragment();
    }

    public ItemTwoDetailFragment() {
    }

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

        if (getArguments().containsKey(Constants.ARG_ITEM_ID)) {
            mItem = DummyContent.ITEM_MAP.get(getArguments().getString(Constants.ARG_ITEM_ID));     // Get selected item to show details
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_item_two_detail, container, false);

        // Show the dummy content as text in a TextView.
        if (mItem != null) {
            ((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.details);        // show details
        }
        return rootView;
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements Bridge{

    private ViewPager viewPager = null;
    private MyAdapter mAdapter;
    PageChangeListener mListener = new PageChangeListener();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager = (ViewPager) findViewById(R.id.pager);
        viewPager.setOnPageChangeListener(mListener);       // Page Change Listener

        mAdapter = new MyAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);

        // Show the Up button in the action bar.
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
    }

    @Override
    public void onBackPressed() {
        if (mListener.getCurrentPage()==2 && mAdapter.mFragment instanceof ItemOneDetailFragment) {     // current page is Tab-3, current fragment is detail fragment
            mAdapter.mListener.onSwitchToNextFragment("0");     // show List fragment
            return;     // prevent to finish app.
        }

        super.onBackPressed();
    }

    // Do the same thing as the back button - go back to ItemListFragment
    // Only when in ItemOneDetailFragment
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == android.R.id.home) {
            if (mListener.getCurrentPage() == 2 && mAdapter.mFragment instanceof ItemOneDetailFragment) {     // current page is Tab-3, current fragment is detail fragment
                mAdapter.mListener.onSwitchToNextFragment("0");     // show List fragment
//                return;     // prevent to finish app.
            }
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onBack() {
        onBackPressed();
    }
}

class PageChangeListener extends ViewPager.SimpleOnPageChangeListener {
    private int currentPage;

    @Override
    public void onPageSelected(int position) {
        currentPage = position;     // current selected page
    }

    public final int getCurrentPage() {
        return currentPage;
    }
}

/**
 * Fragment Page Adapter
 */
class MyAdapter extends FragmentPagerAdapter{

    private final FragmentManager mFragmentManager;
    public BaseFragment mFragment;

    /**
     *  PageFragmentListener for switching fragment.
     */
    public PageFragmentListener mListener = new PageFragmentListener() {
        @Override
        public void onSwitchToNextFragment(final String id) {
            mFragmentManager.beginTransaction().remove(mFragment).commit();
            if (mFragment instanceof ItemListFragment){     // current fragment is List Fragment
                Bundle arguments = new Bundle();
                arguments.putString(Constants.ARG_ITEM_ID, id);     // selected item id
                mFragment = ItemOneDetailFragment.newInstance(mListener);       // switch detail fragment
                mFragment.setArguments(arguments);
            }else{      // DetailFragment
                mFragment = ItemListFragment.newInstance(mListener);    // => switch list fragment
            }

            notifyDataSetChanged();     // notify changes
        }
    };

    public MyAdapter(FragmentManager fm) {
        super(fm);
        mFragmentManager = fm;
    }

    @Override
    public Fragment getItem(int position) {
        if (position == 0)      // Tab-1
            return FragmentA.newInstance();

        if (position == 1)      // Tab-2
            return FragmentB.newInstance();

        if (position == 2) {    // Tab-3
            if (mFragment==null)    // first time => create list fragment
                mFragment = ItemListFragment.newInstance(mListener);

            return mFragment;
        }

        return null;
    }


    @Override
    public CharSequence getPageTitle(int position) {
        if (position == 0) {    // Tab-1
            return "Tab 1";
        }
        if (position == 1) {    // Tab-2
            return "Tab 2";
        }
    if (position == 2) {        //Tab-3
            return "Tab 3";
        }
        return null;
    }

    @Override
    public int getCount() {     // Count of Tabs
        return 3;
    }

    @Override
    public int getItemPosition(Object object) {
        Log.i("Adapter", "ItemPosition>>>" + object.toString());
        if (object instanceof ItemListFragment && mFragment instanceof ItemOneDetailFragment) {     //  fragment changed
            return POSITION_NONE;
        }

        if (object instanceof ItemOneDetailFragment && mFragment instanceof ItemListFragment) {     // fragment changed
            return POSITION_NONE;
        }

        return POSITION_UNCHANGED;
    }
}

Interface: PageFragmentListener.java

public interface PageFragmentListener {
    void onSwitchToNextFragment(String id);
}

Log: With attribute added to Manifest.xml

First instantiation 
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreate()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreateView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onBindViewHolder

ClickItem
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onClick(): single pane
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: removed fragment
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: is instance of List Fragment
03-16 .../com.allison.viewpagermasterdetail D/ItemOneDetailFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>FragmentB{41dd3810 #1 id=0x7f0c0069 android:switcher:2131492969:1}
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>ItemListFragment{41df1528 #2 id=0x7f0c0069 android:switcher:2131492969:2}
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onStop()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroyView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroy()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()

Back
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: removed fragment
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: is instance of Detail Fragment
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>FragmentB{41dd3810 #1 id=0x7f0c0069 android:switcher:2131492969:1}
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>ItemOneDetailFragment{41e896a8 #2 id=0x7f0c0069 android:switcher:2131492969:2}
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreate()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreateView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()

Rotate
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onConfigurationChanged
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: populateViewForOrientation
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onBindViewHolder

ClickItemLand
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onClick(): mTwoPane

Rotate
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onConfigurationChanged
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: populateViewForOrientation
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onBindViewHolder

ClickIemPortrait
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onClick(): single pane
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: removed fragment
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: is instance of List Fragment
03-16 .../com.allison.viewpagermasterdetail D/ItemOneDetailFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>FragmentB{41dd3810 #1 id=0x7f0c0069 android:switcher:2131492969:1}
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>ItemListFragment{41ea8b68 #2 id=0x7f0c0069 android:switcher:2131492969:2}
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onStop()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroyView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroy()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()

Log: Without attribute

First instantiation 
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreate()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreateView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onBindViewHolder

ClickItem
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onClick(): single pane
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: removed fragment
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: is instance of List Fragment
03-16 .../com.allison.viewpagermasterdetail D/ItemOneDetailFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>FragmentB{41dd4758 #1 id=0x7f0c0069 android:switcher:2131492969:1}
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>ItemListFragment{41ded998 #2 id=0x7f0c0069 android:switcher:2131492969:2}
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onStop()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroyView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroy()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()

Back
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: removed fragment
03-16 .../com.allison.viewpagermasterdetail D/MyAdapter: is instance of Detail Fragment
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: newInstance
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>FragmentB{41dd56b8 #1 id=0x7f0c0069 android:switcher:2131492969:1}
03-16 .../com.allison.viewpagermasterdetail I/Adapter: ItemPosition>>>ItemOneDetailFragment{41e830b8 #2 id=0x7f0c0069 android:switcher:2131492969:2}
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreate()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreateView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onBindViewHolder

Rotate
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onSaveInstanceState()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onStop()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroyView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroy()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreate()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreateView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()

ClickItemLand
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onClick(): mTwoPane

Rotate
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onSaveInstanceState()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onStop()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroyView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onDestroy()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onPause()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreate()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onCreateView()
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: initLayout
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: setupRecyclerView()
03-16 .../com.allison.viewpagermasterdetail E/ViewRootImpl: sendUserActionEvent() mView == null
03-16 .../com.allison.viewpagermasterdetail D/ItemListFragment: onBindViewHolder

ClickIemPortrait
// nothing happens

解决方案

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

这篇关于避免手动操作的配置更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆