Fix config change layout. (Part 2)

- Fixing issue where the initial state was not correct after rotating
  the screen.  We needed to update the layout, but that could only be 
  done after the task stack view is laid out.  Now we set a flag to 
  update the initial state of the layout on configuration change, and 
  only scrolling to the front when it makes sense.

Change-Id: I2586b90d1e869708b97bcd1a4446f4d87fa521cc
This commit is contained in:
Winson
2016-03-25 16:12:35 -07:00
parent f9357d9b31
commit 619e40cd56
7 changed files with 90 additions and 34 deletions

View File

@@ -415,13 +415,13 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
// Update the nav bar for the current orientation
updateNavBarScrim(false /* animateNavBarScrim */, AnimationProps.IMMEDIATE);
EventBus.getDefault().send(new ConfigurationChangedEvent());
EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */));
}
@Override
public void onMultiWindowChanged(boolean inMultiWindow) {
super.onMultiWindowChanged(inMultiWindow);
EventBus.getDefault().send(new ConfigurationChangedEvent());
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */));
if (mRecentsView != null) {
// Reload the task stack completely

View File

@@ -708,7 +708,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
TaskStackViewScroller stackScroller = stackView.getScroller();
stackView.updateLayoutAlgorithm(true /* boundScroll */);
stackView.updateToInitialState();
stackView.updateToInitialState(true /* scrollToInitialState */);
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
@@ -775,7 +775,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
// Get the transform for the running task
stackView.updateLayoutAlgorithm(true /* boundScroll */);
stackView.updateToInitialState();
stackView.updateToInitialState(true /* scrollToInitialState */);
mTmpTransform = stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask,
stackView.getScroller().getStackScroll(), mTmpTransform, null);
return mTmpTransform;

View File

@@ -22,5 +22,10 @@ import com.android.systemui.recents.events.EventBus;
* This is sent when the Recents activity configuration has changed.
*/
public class ConfigurationChangedEvent extends EventBus.AnimatedEvent {
// Simple event
public final boolean fromMultiWindow;
public ConfigurationChangedEvent(boolean fromMultiWindow) {
this.fromMultiWindow = fromMultiWindow;
}
}

View File

@@ -852,7 +852,7 @@ public class TaskStackLayoutAlgorithm {
// in screen space
float tmpP = (mMinScrollP - stackScroll) / mNumStackTasks;
int centerYOffset = (mStackRect.top - mTaskRect.top) +
(mStackRect.height() - mTaskRect.height()) / 2;
(mStackRect.height() - mSystemInsets.bottom - mTaskRect.height()) / 2;
y = centerYOffset + getYForDeltaP(tmpP, 0);
z = mMaxTranslationZ;
dimAlpha = 0f;

View File

@@ -22,6 +22,7 @@ import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
@@ -87,6 +88,8 @@ import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
@@ -116,6 +119,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
private static final ArraySet<Task.TaskKey> EMPTY_TASK_SET = new ArraySet<>();
// The actions to perform when resetting to initial state,
@Retention(RetentionPolicy.SOURCE)
@IntDef({INITIAL_STATE_UPDATE_NONE, INITIAL_STATE_UPDATE_ALL, INITIAL_STATE_UPDATE_LAYOUT_ONLY})
public @interface InitialStateAction {}
/** Do not update the stack and layout to the initial state. */
private static final int INITIAL_STATE_UPDATE_NONE = 0;
/** Update both the stack and layout to the initial state. */
private static final int INITIAL_STATE_UPDATE_ALL = 1;
/** Update only the layout to the initial state. */
private static final int INITIAL_STATE_UPDATE_LAYOUT_ONLY = 2;
LayoutInflater mInflater;
TaskStack mStack = new TaskStack();
@ViewDebug.ExportedProperty(deepExport=true, prefix="layout_")
@@ -150,6 +164,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
@ViewDebug.ExportedProperty(category="recents")
boolean mAwaitingFirstLayout = true;
@ViewDebug.ExportedProperty(category="recents")
@InitialStateAction
int mInitialState = INITIAL_STATE_UPDATE_ALL;
@ViewDebug.ExportedProperty(category="recents")
boolean mInMeasureLayout = false;
@ViewDebug.ExportedProperty(category="recents")
boolean mEnterAnimationComplete = false;
@@ -307,6 +324,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// Since we always animate to the same place in (the initial state), always reset the stack
// to the initial state when resuming
mAwaitingFirstLayout = true;
mInitialState = INITIAL_STATE_UPDATE_ALL;
requestLayout();
}
@@ -329,8 +347,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
/**
* Updates this TaskStackView to the initial state.
*/
public void updateToInitialState() {
mStackScroller.setStackScrollToInitialState();
public void updateToInitialState(boolean scrollToInitialState) {
if (scrollToInitialState) {
mStackScroller.setStackScrollToInitialState();
}
mLayoutAlgorithm.updateToInitialState(mStack.getStackTasks());
}
@@ -1199,11 +1219,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// If this is the first layout, then scroll to the front of the stack, then update the
// TaskViews with the stack so that we can lay them out
// TODO: The second check is a workaround for wacky layouts that we get while docking via
// long pressing the recents button
if (mAwaitingFirstLayout ||
(mStackScroller.getStackScroll() == mLayoutAlgorithm.mInitialScrollP)) {
updateToInitialState();
if (mAwaitingFirstLayout || mInitialState != INITIAL_STATE_UPDATE_NONE) {
updateToInitialState(mInitialState != INITIAL_STATE_UPDATE_LAYOUT_ONLY);
mInitialState = INITIAL_STATE_UPDATE_NONE;
}
// Rebind all the views, including the ignore ones
@@ -1916,8 +1934,23 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
public final void onBusEvent(ConfigurationChangedEvent event) {
mStableLayoutAlgorithm.reloadOnConfigurationChange(getContext());
mLayoutAlgorithm.reloadOnConfigurationChange(getContext());
mLayoutAlgorithm.initialize(mWindowRect, mStackBounds,
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(mStack));
// Notify the task views of the configuration change so they can reload their resources
if (!event.fromMultiWindow) {
mTmpTaskViews.clear();
mTmpTaskViews.addAll(getTaskViews());
mTmpTaskViews.addAll(mViewPool.getViews());
int taskViewCount = mTmpTaskViews.size();
for (int i = 0; i < taskViewCount; i++) {
mTmpTaskViews.get(i).onConfigurationChanged();
}
}
// Trigger a new layout and scroll to the initial state
mInitialState = event.fromMultiWindow
? INITIAL_STATE_UPDATE_ALL
: INITIAL_STATE_UPDATE_LAYOUT_ONLY;
requestLayout();
}
/**

View File

@@ -24,6 +24,7 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Paint;
@@ -237,6 +238,13 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
}
/**
* Update the task view when the configuration changes.
*/
void onConfigurationChanged() {
mHeaderView.onConfigurationChanged();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

View File

@@ -250,25 +250,7 @@ public class TaskViewHeader extends FrameLayout
mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);
// Update the dimensions of everything in the header. We do this because we need to use
// resources for the display, and not the current configuration.
Resources res = getResources();
mHeaderBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height_tablet_land,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height_tablet_land);
mHeaderButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding_tablet_land,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding_tablet_land);
updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
mDismissButton);
onConfigurationChanged();
}
/**
@@ -302,6 +284,34 @@ public class TaskViewHeader extends FrameLayout
mHeaderButtonPadding);
}
/**
* Update the header view when the configuration changes.
*/
void onConfigurationChanged() {
// Update the dimensions of everything in the header. We do this because we need to use
// resources for the display, and not the current configuration.
Resources res = getResources();
mHeaderBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height_tablet_land,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height_tablet_land);
mHeaderButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding_tablet_land,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding_tablet_land);
updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
mDismissButton);
if (mAppOverlayView != null) {
updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);