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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user