Split RecyclerViewFragment#getAdapter() into getAdapter() and onCreateAdapter()
This commit is contained in:
parent
b1ac2e60dd
commit
ca2da0ad66
@ -47,11 +47,18 @@ public abstract class RecyclerViewFragment<
|
||||
protected abstract void onScrolledToStableId(long id, int position);
|
||||
|
||||
/**
|
||||
* @return the adapter to set on the RecyclerView. SUBCLASSES MUST OVERRIDE THIS, BECAUSE THE
|
||||
* DEFAULT IMPLEMENTATION WILL ALWAYS RETURN AN UNINITIALIZED ADAPTER INSTANCE.
|
||||
* @return the adapter to set on the RecyclerView. Called in onCreateView().
|
||||
* @param savedInstanceState the same Bundle used to save out and restore state for this Fragment
|
||||
* when the configuration is changed. Implementors may find this useful
|
||||
* if their ViewHolder type(s) require saving and restoring state across
|
||||
* configurations.
|
||||
*/
|
||||
@Nullable
|
||||
protected A getAdapter() {
|
||||
protected abstract A onCreateAdapter(Bundle savedInstanceState);
|
||||
|
||||
/**
|
||||
* @return the adapter instance created from {@link #onCreateAdapter(Bundle)}
|
||||
*/
|
||||
protected final A getAdapter() {
|
||||
return mAdapter;
|
||||
}
|
||||
|
||||
@ -69,7 +76,7 @@ public abstract class RecyclerViewFragment<
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
mList.setLayoutManager(getLayoutManager());
|
||||
mList.setAdapter(mAdapter = getAdapter());
|
||||
mList.setAdapter(mAdapter = onCreateAdapter(savedInstanceState));
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
@ -136,11 +135,8 @@ public class AlarmsFragment extends RecyclerViewFragment<
|
||||
dialog.show(getFragmentManager(), TAG_TIME_PICKER);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected AlarmsCursorAdapter getAdapter() {
|
||||
if (super.getAdapter() != null)
|
||||
return super.getAdapter();
|
||||
protected AlarmsCursorAdapter onCreateAdapter(Bundle savedInstanceState) {
|
||||
// Create a new adapter. This is called before we can initialize mAlarmController,
|
||||
// so right now it is null. However, after super.onCreate() returns, it is initialized, and
|
||||
// the reference variable will be pointing to an actual object. This assignment "propagates"
|
||||
@ -262,7 +258,43 @@ public class AlarmsFragment extends RecyclerViewFragment<
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(KEY_EXPANDED_POSITION, getAdapter().getExpandedPosition());
|
||||
/*
|
||||
* From Fragment#onSaveInstanceState():
|
||||
* - This is called "at any time before onDestroy()".
|
||||
* - "This corresponds to Activity.onSaveInstanceState(Bundle) and most of the discussion
|
||||
* there applies here as well".
|
||||
* From Activity#onSaveInstanceState():
|
||||
* - "If called, this method will occur before {@link #onStop}
|
||||
* [which follows onPause() in the lifecycle]. There are
|
||||
* no guarantees about whether it will occur before or after {@link #onPause}."
|
||||
*
|
||||
* isResumed() is true "for the duration of onResume() and onPause()".
|
||||
* From the results of a few trials, this never seemed to call through, so i'm assuming
|
||||
* isResumed() returned false every time.
|
||||
*/
|
||||
if (/*isResumed() && */getAdapter() != null) {
|
||||
// Normally when we scroll far enough away from this Fragment, *its view* will be
|
||||
// destroyed, i.e. the maximum point in its lifecycle is onDestroyView(). However,
|
||||
// if the configuration changes, onDestroy() is called through, and then this Fragment
|
||||
// and all of its members will be destroyed. This is not
|
||||
// a problem if the page in which the configuration changed is this page, because
|
||||
// the Fragment will be recreated from onCreate() to onResume(), and any
|
||||
// member initialization between those points occurs as usual.
|
||||
//
|
||||
// However, when the page in which the configuration changed
|
||||
// is far enough away from this Fragment, there IS a problem. The Fragment
|
||||
// *at that page* is recreated, but this Fragment will NOT be; the ViewPager's
|
||||
// adapter will not reinstantiate this Fragment because it exceeds the
|
||||
// offscreen page limit relative to the initial page in the new configuration.
|
||||
//
|
||||
// As such, we should only save state if this Fragment's members (i.e. its RecyclerView.Adapter)
|
||||
// are not destroyed
|
||||
// because that indicates the Fragment is both registered in the adapter AND is within the offscreen
|
||||
// page limit, so its members have been initialized (recall that a Fragment in a ViewPager
|
||||
// does not actually need to be visible to the user for onCreateView() to onResume() to
|
||||
// be called through).
|
||||
outState.putInt(KEY_EXPANDED_POSITION, getAdapter().getExpandedPosition());
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -259,11 +259,8 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
||||
updateAllFabs();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected LapsAdapter getAdapter() {
|
||||
if (super.getAdapter() != null)
|
||||
return super.getAdapter();
|
||||
protected LapsAdapter onCreateAdapter(Bundle savedInstanceState) {
|
||||
return new LapsAdapter();
|
||||
}
|
||||
|
||||
|
||||
@ -83,11 +83,8 @@ public class TimersFragment extends RecyclerViewFragment<
|
||||
startActivityForResult(intent, REQUEST_CREATE_TIMER);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected TimersCursorAdapter getAdapter() {
|
||||
if (super.getAdapter() != null)
|
||||
return super.getAdapter();
|
||||
protected TimersCursorAdapter onCreateAdapter(Bundle savedInstanceState) {
|
||||
// Create a new adapter. This is called before we can initialize mAsyncTimersTableUpdateHandler,
|
||||
// so right now it is null. However, after super.onCreate() returns, it is initialized, and
|
||||
// the reference variable will be pointing to an actual object. This assignment "propagates"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user