Избегайте ручного управления изменениями конфигурации

Этот проект является расширением шаблона потока Master/Detail, который можно найти в Android Studio. Разница в том, что в этом приложении используется одно действие и ViewPager, который управляет тремя фрагментами. Третий фрагмент - это фрагмент мастера (списка), который содержит интерактивный RecycleView. Когда элемент списка щелкнут, он переключает фрагмент с фрагментом Child (detail).

Пока проект работает, я бы хотел избежать использования android:configChanges= "orientation|keyboardHidden|screenSize" в манифесте. Как мне это сделать?

Если атрибут удален, mListener в ItemListFragment уничтожается вместе с ItemFragmentList при вращении, но никогда не воссоздается при воссоздании ItemListFragment. Это приводит к тому, что ничего не происходит при нажатии на элемент "Список" в режиме "Портрет".

Моим первоначальным решением было вручную переопределить обработку изменений конфигурации, что означало, что ItemListFragment не был разрушен при вращении экрана. onConfigurationChanged() и populateViewForOrientation() были добавлены для повторного раздувания макета. Разумеется, есть лучшее решение, чем ручное переопределение обработки конфигурации.

Проект доступен по адресу: https://github.com/lukeallison/ViewPagerMasterDetail, Видео: 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();
    }
}

Интерфейс: 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;
    }
}

Интерфейс: PageFragmentListener.java

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

Журнал: с атрибутом, добавленным в 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()

Журнал: без атрибута

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

Ответ 1

У вас, кажется, есть несколько проблем, которые необходимо устранить.

Сначала ваша ссылка на mListener в SimpleItemRecyclerViewAdapter ломается, когда активность воссоздана. Следовательно, вам необходимо восстановить это соединение после воссоздания активности. Для этого вам нужно выполнить следующие исправления.

Основная деятельность

Сделайте PageFragmentListener доступным для внешнего доступа, объявив его как свойство

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

Переопределите метод onActivityCreated в ItemListFragment и восстановите mListener, обратившись к нему из действия

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

Теперь ваш mListener всегда будет правильно настроен, когда активность будет воссоздана. Но вам нужно сделать еще несколько исправлений для более плавной работы.

В вашем MyAdapter содержится ссылка на экземпляр фрагмента под названием mFragment. Когда активность воссоздана, вам также нужно восстановить эту переменную. Следовательно, вам нужно изменить конструктор MyAdapter, как показано ниже.

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

На этом этапе ваш код должен работать. Но при повороте устройства во время просмотра деталей элемента списка он будет сбой. Это происходит потому, что вы добавляете дочерние фрагменты к активности непосредственно из своего ItemListFragment с помощью Activity FragmentManager. Вместо этого используйте childFragmentManager из самого фрагмента.

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

Ответ 2

Использование шаблона MVP может помочь, поскольку презентаторы могут быть созданы таким образом, чтобы они сохраняли изменения конфигурации. Недавно я столкнулся с серией сообщений в блогах, направленных на объяснение такой реализации шаблона MVP. Я уверен, что они помогут вам.

Сообщения в блогах: Часть 1 Часть 2