Restore mini FABs and Activity FAB correctly on rotate
This commit is contained in:
parent
2daf03b754
commit
925424c882
@ -76,16 +76,11 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
mPauseDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.ic_pause_24dp);
|
mPauseDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.ic_pause_24dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Restore progress bar animator on rotate
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
// TODO: Apply size span on chronom
|
Log.d(TAG, "onCreateView()");
|
||||||
View view = super.onCreateView(inflater, container, savedInstanceState);
|
View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||||
// TODO: Any better alternatives?
|
|
||||||
// TOneverDO: Move to onCreate(). It is not called again on device rotation, so we will
|
|
||||||
// have a null reference.
|
|
||||||
mActivityFab = new WeakReference<>((FloatingActionButton) getActivity().findViewById(R.id.fab));
|
|
||||||
|
|
||||||
mChronometer.setApplySizeSpan(true);
|
mChronometer.setApplySizeSpan(true);
|
||||||
if (mStartTime > 0) {
|
if (mStartTime > 0) {
|
||||||
@ -96,18 +91,37 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
}
|
}
|
||||||
mChronometer.setBase(base);
|
mChronometer.setBase(base);
|
||||||
}
|
}
|
||||||
if (wasChronometerRunning()) {
|
if (isStopwatchRunning()) {
|
||||||
mChronometer.start();
|
mChronometer.start();
|
||||||
// Note: mChronometer.isRunning() will return false at this point and
|
// Note: mChronometer.isRunning() will return false at this point and
|
||||||
// in other upcoming lifecycle methods because it is not yet visible
|
// in other upcoming lifecycle methods because it is not yet visible
|
||||||
// (i.e. mVisible == false).
|
// (i.e. mVisible == false).
|
||||||
}
|
}
|
||||||
// Hides the mini fabs prematurely, so when we actually display this tab
|
// The primary reason we call this is to show the mini FABs after rotate,
|
||||||
// they won't show even briefly at all before hiding.
|
// if the stopwatch is running. If the stopwatch is stopped, then this
|
||||||
// updateButtonControls();
|
// would have hidden the mini FABs, if not for us already setting its
|
||||||
|
// visibility to invisible in XML. We haven't initialized the WeakReference to
|
||||||
|
// our Activity's FAB yet, so this call does nothing with the FAB.
|
||||||
|
updateMiniFabs();
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
// TODO: Any better alternatives?
|
||||||
|
// TOneverDO: Move to onCreate(). When the device rotates, onCreate() _is_ called,
|
||||||
|
// but trying to find the FAB in the Activity's layout will fail, and we would get back
|
||||||
|
// a null reference. This is probably because this Fragment's onCreate() is called
|
||||||
|
// BEFORE the Activity's onCreate.
|
||||||
|
mActivityFab = new WeakReference<>((FloatingActionButton) getActivity().findViewById(R.id.fab));
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
// This is a pretty good indication that we just rotated.
|
||||||
|
// updateMiniFabs(); // TODO: Do we need this?
|
||||||
|
updateFab();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the user navigates away, this is the furthest point in the lifecycle
|
* If the user navigates away, this is the furthest point in the lifecycle
|
||||||
* this Fragment gets to. Here, the view hierarchy returned from onCreateView()
|
* this Fragment gets to. Here, the view hierarchy returned from onCreateView()
|
||||||
@ -166,7 +180,7 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
//
|
//
|
||||||
// NOTE: If we just recreated ourselves due to rotation, mChronometer.isRunning() == false,
|
// NOTE: If we just recreated ourselves due to rotation, mChronometer.isRunning() == false,
|
||||||
// because it is not yet visible (i.e. mVisible == false).
|
// because it is not yet visible (i.e. mVisible == false).
|
||||||
if (mChronometer.isRunning() || wasChronometerRunning()) {
|
if (isStopwatchRunning()) {
|
||||||
startNewProgressBarAnimator();
|
startNewProgressBarAnimator();
|
||||||
} else {
|
} else {
|
||||||
// I verified the bar was visible already without this, so we probably don't need this,
|
// I verified the bar was visible already without this, so we probably don't need this,
|
||||||
@ -218,13 +232,13 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
// mProgressAnimator.resume();
|
// mProgressAnimator.resume();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
updateButtonControls();
|
updateAllFabs();
|
||||||
savePrefs();
|
savePrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPageSelected() {
|
public void onPageSelected() {
|
||||||
updateButtonControls();
|
updateAllFabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -284,19 +298,35 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
mProgressAnimator.end();
|
mProgressAnimator.end();
|
||||||
}
|
}
|
||||||
mProgressAnimator = null;
|
mProgressAnimator = null;
|
||||||
updateButtonControls();
|
|
||||||
savePrefs();
|
savePrefs();
|
||||||
|
// TOneverDO: Precede savePrefs(), or else we don't save false to KEY_CHRONOMETER_RUNNING
|
||||||
|
/// and updateFab will update the wrong icon.
|
||||||
|
updateAllFabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateButtonControls() {
|
private void updateAllFabs() {
|
||||||
|
updateMiniFabs();
|
||||||
|
updateFab();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMiniFabs() {
|
||||||
boolean started = mStartTime > 0;
|
boolean started = mStartTime > 0;
|
||||||
int vis = started ? View.VISIBLE : View.INVISIBLE;
|
int vis = started ? View.VISIBLE : View.INVISIBLE;
|
||||||
mNewLapButton.setVisibility(vis);
|
mNewLapButton.setVisibility(vis);
|
||||||
mStopButton.setVisibility(vis);
|
mStopButton.setVisibility(vis);
|
||||||
// TODO: We no longer call this method in lifecycle events where we aren't actually
|
}
|
||||||
// resumed/visible, so we can remove this check.
|
|
||||||
if (isVisible()) { // avoid changing the icon prematurely, esp. when we're not on this tab
|
private void updateFab() {
|
||||||
mActivityFab.get().setImageDrawable(mChronometer.isRunning() ? mPauseDrawable : mStartDrawable);
|
// Avoid changing the icon in premature cases.
|
||||||
|
// isVisible() is good for filtering out calls to this method when this Fragment
|
||||||
|
// isn't actually visible to the user; however, a side effect is it also filters
|
||||||
|
// out calls to this method when this Fragment is rotated.
|
||||||
|
// isMenuVisible() is good for the rotation case; however, a side effect is when you
|
||||||
|
// rotate on page 1 and scroll to page 2, the icon prematurely changes. Fortunately,
|
||||||
|
// for every page change after that, the icon no longer prematurely changes.
|
||||||
|
// TODO: If you can live with that, then move on.
|
||||||
|
if ((isVisible() || isMenuVisible()) && mActivityFab != null) {
|
||||||
|
mActivityFab.get().setImageDrawable(isStopwatchRunning() ? mPauseDrawable : mStartDrawable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,9 +399,14 @@ public class StopwatchFragment extends RecyclerViewFragment<
|
|||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean wasChronometerRunning() {
|
/**
|
||||||
return mPrefs.getBoolean(KEY_CHRONOMETER_RUNNING, false);
|
* @return the state of the stopwatch when we're in a resumed and visible state,
|
||||||
|
* or when we're going through a rotation
|
||||||
|
*/
|
||||||
|
private boolean isStopwatchRunning() {
|
||||||
|
return mChronometer.isRunning() || mPrefs.getBoolean(KEY_CHRONOMETER_RUNNING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================= DO NOT IMPLEMENT ============================
|
// ======================= DO NOT IMPLEMENT ============================
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user