Merge "PIP: Apply the latest Recents row animation when PIP control is focused" into nyc-dev
am: 4b12df6
* commit '4b12df6f7ec1684c4ae5218668ad26d0e8cf81d7':
PIP: Apply the latest Recents row animation when PIP control is focused
Change-Id: Ib162a6a5764cfb9920dea8d8e0b3a1af7931df58
This commit is contained in:
@@ -19,8 +19,20 @@
|
|||||||
<item android:state_focused="true">
|
<item android:state_focused="true">
|
||||||
<layer-list>
|
<layer-list>
|
||||||
<item android:drawable="@drawable/tv_pip_button_focused" />
|
<item android:drawable="@drawable/tv_pip_button_focused" />
|
||||||
<item android:drawable="@drawable/ic_close_white" />
|
<item android:drawable="@drawable/ic_close_white"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
|
</layer-list>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layer-list>
|
||||||
|
<item android:drawable="@drawable/ic_close_white"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
</layer-list>
|
</layer-list>
|
||||||
</item>
|
</item>
|
||||||
<item android:drawable="@drawable/ic_close_white" />
|
|
||||||
</selector>
|
</selector>
|
||||||
|
|||||||
@@ -19,8 +19,20 @@
|
|||||||
<item android:state_focused="true">
|
<item android:state_focused="true">
|
||||||
<layer-list>
|
<layer-list>
|
||||||
<item android:drawable="@drawable/tv_pip_button_focused" />
|
<item android:drawable="@drawable/tv_pip_button_focused" />
|
||||||
<item android:drawable="@drawable/ic_fullscreen_white_24dp" />
|
<item android:drawable="@drawable/ic_fullscreen_white_24dp"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
|
</layer-list>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layer-list>
|
||||||
|
<item android:drawable="@drawable/ic_fullscreen_white_24dp"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
</layer-list>
|
</layer-list>
|
||||||
</item>
|
</item>
|
||||||
<item android:drawable="@drawable/ic_fullscreen_white_24dp" />
|
|
||||||
</selector>
|
</selector>
|
||||||
|
|||||||
@@ -19,8 +19,20 @@
|
|||||||
<item android:state_focused="true">
|
<item android:state_focused="true">
|
||||||
<layer-list>
|
<layer-list>
|
||||||
<item android:drawable="@drawable/tv_pip_button_focused" />
|
<item android:drawable="@drawable/tv_pip_button_focused" />
|
||||||
<item android:drawable="@drawable/ic_pause_white_24dp" />
|
<item android:drawable="@drawable/ic_pause_white_24dp"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
|
</layer-list>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layer-list>
|
||||||
|
<item android:drawable="@drawable/ic_pause_white_24dp"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
</layer-list>
|
</layer-list>
|
||||||
</item>
|
</item>
|
||||||
<item android:drawable="@drawable/ic_pause_white_24dp" />
|
|
||||||
</selector>
|
</selector>
|
||||||
|
|||||||
@@ -19,8 +19,20 @@
|
|||||||
<item android:state_focused="true">
|
<item android:state_focused="true">
|
||||||
<layer-list>
|
<layer-list>
|
||||||
<item android:drawable="@drawable/tv_pip_button_focused" />
|
<item android:drawable="@drawable/tv_pip_button_focused" />
|
||||||
<item android:drawable="@drawable/ic_play_arrow_white_24dp" />
|
<item android:drawable="@drawable/ic_play_arrow_white_24dp"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
|
</layer-list>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layer-list>
|
||||||
|
<item android:drawable="@drawable/ic_play_arrow_white_24dp"
|
||||||
|
android:top="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:bottom="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:left="@dimen/tv_pip_button_icon_padding"
|
||||||
|
android:right="@dimen/tv_pip_button_icon_padding" />
|
||||||
</layer-list>
|
</layer-list>
|
||||||
</item>
|
</item>
|
||||||
<item android:drawable="@drawable/ic_play_arrow_white_24dp" />
|
|
||||||
</selector>
|
</selector>
|
||||||
|
|||||||
@@ -54,5 +54,7 @@
|
|||||||
|
|
||||||
<!-- Extra space around the PIP and its outline in PIP onboarding activity -->
|
<!-- Extra space around the PIP and its outline in PIP onboarding activity -->
|
||||||
<dimen name="tv_pip_bounds_space">3dp</dimen>
|
<dimen name="tv_pip_bounds_space">3dp</dimen>
|
||||||
|
<!-- Extra space around the PIP control button icon to match with the focused circle -->
|
||||||
|
<dimen name="tv_pip_button_icon_padding">5dp</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import com.android.systemui.recents.model.RecentsTaskLoadPlan;
|
|||||||
import com.android.systemui.recents.model.RecentsTaskLoader;
|
import com.android.systemui.recents.model.RecentsTaskLoader;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
import com.android.systemui.recents.tv.animations.FocusAnimationHolder;
|
|
||||||
import com.android.systemui.recents.tv.views.RecentsTvView;
|
import com.android.systemui.recents.tv.views.RecentsTvView;
|
||||||
import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
|
import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
|
||||||
import com.android.systemui.statusbar.BaseStatusBar;
|
import com.android.systemui.statusbar.BaseStatusBar;
|
||||||
@@ -79,7 +78,6 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
|||||||
private boolean mIgnoreAltTabRelease;
|
private boolean mIgnoreAltTabRelease;
|
||||||
|
|
||||||
private RecentsTvView mRecentsView;
|
private RecentsTvView mRecentsView;
|
||||||
private FocusAnimationHolder mRecentsFocusAnimationHolder;
|
|
||||||
private View mPipView;
|
private View mPipView;
|
||||||
private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
|
private TaskStackHorizontalViewAdapter mTaskStackViewAdapter;
|
||||||
private FinishRecentsRunnable mFinishLaunchHomeRunnable;
|
private FinishRecentsRunnable mFinishLaunchHomeRunnable;
|
||||||
@@ -133,13 +131,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
|||||||
new View.OnFocusChangeListener() {
|
new View.OnFocusChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
public void onFocusChange(View v, boolean hasFocus) {
|
||||||
if (hasFocus) {
|
handlePipViewFocusChange(hasFocus);
|
||||||
mRecentsFocusAnimationHolder.startFocusLoseAnimation();
|
|
||||||
mPipRecentsOverlayManager.requestFocus(
|
|
||||||
mTaskStackViewAdapter.getItemCount() > 0);
|
|
||||||
} else {
|
|
||||||
mRecentsFocusAnimationHolder.startFocusGainAnimation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -288,11 +280,10 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
|||||||
mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||||
mRecentsFocusAnimationHolder = new FocusAnimationHolder(mRecentsView);
|
|
||||||
|
|
||||||
mPipView = findViewById(R.id.pip);
|
mPipView = findViewById(R.id.pip);
|
||||||
// Place mPipView at the PIP bounds for fine tuned focus handling.
|
// Place mPipView at the PIP bounds for fine tuned focus handling.
|
||||||
Rect pipBounds = mPipManager.getPipBounds();
|
Rect pipBounds = mPipManager.getRecentsFocusedPipBounds();
|
||||||
LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
|
LayoutParams lp = (LayoutParams) mPipView.getLayoutParams();
|
||||||
lp.width = pipBounds.width();
|
lp.width = pipBounds.width();
|
||||||
lp.height = pipBounds.height();
|
lp.height = pipBounds.height();
|
||||||
@@ -513,11 +504,30 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener {
|
|||||||
if (mPipManager.isPipShown()) {
|
if (mPipManager.isPipShown()) {
|
||||||
mPipView.setVisibility(View.VISIBLE);
|
mPipView.setVisibility(View.VISIBLE);
|
||||||
mPipView.setOnFocusChangeListener(mPipViewFocusChangeListener);
|
mPipView.setOnFocusChangeListener(mPipViewFocusChangeListener);
|
||||||
mPipView.requestFocus();
|
if (mPipView.hasFocus()) {
|
||||||
|
// This can happen only if the activity is resumed. Ask for reset.
|
||||||
|
handlePipViewFocusChange(true);
|
||||||
|
} else {
|
||||||
|
mPipView.requestFocus();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mPipView.setVisibility(View.GONE);
|
mPipView.setVisibility(View.GONE);
|
||||||
mPipRecentsOverlayManager.removePipRecentsOverlayView();
|
mPipRecentsOverlayManager.removePipRecentsOverlayView();
|
||||||
mRecentsFocusAnimationHolder.reset();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the PIP view's focus change.
|
||||||
|
* This starts the relevant recents row animation
|
||||||
|
* and give focus to the recents overlay if needed.
|
||||||
|
*/
|
||||||
|
private void handlePipViewFocusChange(boolean hasFocus) {
|
||||||
|
mRecentsView.startRecentsRowFocusAnimation(!hasFocus);
|
||||||
|
if (hasFocus) {
|
||||||
|
// When PIP view has focus, recents overlay view will takes the focus
|
||||||
|
// as if it's the part of the Recents UI.
|
||||||
|
mPipRecentsOverlayManager.requestFocus(
|
||||||
|
mTaskStackViewAdapter.getItemCount() > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package com.android.systemui.recents.tv.animations;
|
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.android.systemui.Interpolators;
|
|
||||||
import com.android.systemui.R;
|
|
||||||
import com.android.systemui.recents.tv.views.TaskCardView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collections of Recents row's animation depending on the PIP's focus.
|
|
||||||
*/
|
|
||||||
public class FocusAnimationHolder {
|
|
||||||
private final float DIM_ALPHA = 0.5f;
|
|
||||||
|
|
||||||
private View mRecentsRowView;
|
|
||||||
private int mCardYDelta;
|
|
||||||
private long mDuration;
|
|
||||||
|
|
||||||
public FocusAnimationHolder(View recentsRowView) {
|
|
||||||
mRecentsRowView = recentsRowView;
|
|
||||||
|
|
||||||
Resources res = recentsRowView.getResources();
|
|
||||||
mCardYDelta = res.getDimensionPixelOffset(R.dimen.recents_tv_dismiss_shift_down);
|
|
||||||
mDuration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startFocusGainAnimation() {
|
|
||||||
mRecentsRowView.animate()
|
|
||||||
.setDuration(mDuration)
|
|
||||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
|
||||||
.alpha(1f)
|
|
||||||
.translationY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startFocusLoseAnimation() {
|
|
||||||
mRecentsRowView.animate()
|
|
||||||
.setDuration(mDuration)
|
|
||||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
|
||||||
.alpha(DIM_ALPHA)
|
|
||||||
.translationY(mCardYDelta);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reset() {
|
|
||||||
mRecentsRowView.setTransitionAlpha(1f);
|
|
||||||
mRecentsRowView.setTranslationY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.android.systemui.recents.tv.animations;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.systemui.Interpolators;
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.recents.tv.views.TaskCardView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recents row's focus animation with PIP controls.
|
||||||
|
*/
|
||||||
|
public class RecentsRowFocusAnimationHolder {
|
||||||
|
private static final float DIM_ALPHA = 0.5f;
|
||||||
|
|
||||||
|
private View mView;
|
||||||
|
private View mTitleView;
|
||||||
|
|
||||||
|
private AnimatorSet mFocusGainAnimatorSet;
|
||||||
|
private AnimatorSet mFocusLoseAnimatorSet;
|
||||||
|
|
||||||
|
public RecentsRowFocusAnimationHolder(View view, View titleView) {
|
||||||
|
mView = view;
|
||||||
|
mTitleView = titleView;
|
||||||
|
|
||||||
|
Resources res = view.getResources();
|
||||||
|
int duration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration);
|
||||||
|
|
||||||
|
mFocusGainAnimatorSet = new AnimatorSet();
|
||||||
|
mFocusGainAnimatorSet.playTogether(
|
||||||
|
ObjectAnimator.ofFloat(mView, "alpha", 1f),
|
||||||
|
ObjectAnimator.ofFloat(mTitleView, "alpha", 1f));
|
||||||
|
mFocusGainAnimatorSet.setDuration(duration);
|
||||||
|
mFocusGainAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||||
|
|
||||||
|
mFocusLoseAnimatorSet = new AnimatorSet();
|
||||||
|
mFocusLoseAnimatorSet.playTogether(
|
||||||
|
ObjectAnimator.ofFloat(mView, "alpha", DIM_ALPHA),
|
||||||
|
ObjectAnimator.ofFloat(mTitleView, "alpha", 0f));
|
||||||
|
mFocusLoseAnimatorSet.setDuration(duration);
|
||||||
|
mFocusLoseAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Recents row's focus change animation.
|
||||||
|
*/
|
||||||
|
public Animator getFocusChangeAnimator(boolean hasFocus) {
|
||||||
|
return hasFocus ? mFocusGainAnimatorSet : mFocusLoseAnimatorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the views to the initial state immediately.
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
mView.setAlpha(1f);
|
||||||
|
mTitleView.setAlpha(1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ import com.android.systemui.recents.events.component.RecentsVisibilityChangedEve
|
|||||||
import com.android.systemui.recents.misc.SystemServicesProxy;
|
import com.android.systemui.recents.misc.SystemServicesProxy;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
|
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -52,6 +53,7 @@ public class RecentsTvView extends FrameLayout {
|
|||||||
private TaskStack mStack;
|
private TaskStack mStack;
|
||||||
private TaskStackHorizontalGridView mTaskStackHorizontalView;
|
private TaskStackHorizontalGridView mTaskStackHorizontalView;
|
||||||
private View mEmptyView;
|
private View mEmptyView;
|
||||||
|
private RecentsRowFocusAnimationHolder mEmptyViewFocusAnimationHolder;
|
||||||
private boolean mAwaitingFirstLayout = true;
|
private boolean mAwaitingFirstLayout = true;
|
||||||
private Rect mSystemInsets = new Rect();
|
private Rect mSystemInsets = new Rect();
|
||||||
private RecentsTvTransitionHelper mTransitionHelper;
|
private RecentsTvTransitionHelper mTransitionHelper;
|
||||||
@@ -77,6 +79,8 @@ public class RecentsTvView extends FrameLayout {
|
|||||||
LayoutInflater inflater = LayoutInflater.from(context);
|
LayoutInflater inflater = LayoutInflater.from(context);
|
||||||
mEmptyView = inflater.inflate(R.layout.recents_empty, this, false);
|
mEmptyView = inflater.inflate(R.layout.recents_empty, this, false);
|
||||||
addView(mEmptyView);
|
addView(mEmptyView);
|
||||||
|
mEmptyViewFocusAnimationHolder = new RecentsRowFocusAnimationHolder(mEmptyView, null);
|
||||||
|
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
mTransitionHelper = new RecentsTvTransitionHelper(mContext, mHandler);
|
mTransitionHelper = new RecentsTvTransitionHelper(mContext, mHandler);
|
||||||
}
|
}
|
||||||
@@ -94,7 +98,6 @@ public class RecentsTvView extends FrameLayout {
|
|||||||
mTaskStackHorizontalView.setStack(stack);
|
mTaskStackHorizontalView.setStack(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (stack.getStackTaskCount() > 0) {
|
if (stack.getStackTaskCount() > 0) {
|
||||||
hideEmptyView();
|
hideEmptyView();
|
||||||
} else {
|
} else {
|
||||||
@@ -134,33 +137,40 @@ public class RecentsTvView extends FrameLayout {
|
|||||||
public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
|
public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
|
||||||
if (mTaskStackHorizontalView != null) {
|
if (mTaskStackHorizontalView != null) {
|
||||||
// Iterate the stack views and try and find the given task.
|
// Iterate the stack views and try and find the given task.
|
||||||
List<TaskCardView> taskViews = mTaskStackHorizontalView.getTaskViews();
|
if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
|
||||||
int taskViewCount = taskViews.size();
|
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||||
for (int j = 0; j < taskViewCount; j++) {
|
ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
|
||||||
TaskCardView tv = taskViews.get(j);
|
return true;
|
||||||
if (tv.getTask() == task) {
|
|
||||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
|
||||||
ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the focus change animation.
|
||||||
|
*/
|
||||||
|
public void startRecentsRowFocusAnimation(boolean hasFocus) {
|
||||||
|
if (mEmptyView.getVisibility() == View.VISIBLE) {
|
||||||
|
mEmptyViewFocusAnimationHolder.getFocusChangeAnimator(hasFocus).start();
|
||||||
|
} else {
|
||||||
|
mTaskStackHorizontalView.startRecentsRowFocusAnimation(hasFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides the task stack and shows the empty view.
|
* Hides the task stack and shows the empty view.
|
||||||
*/
|
*/
|
||||||
public void showEmptyView() {
|
public void showEmptyView() {
|
||||||
mEmptyView.setVisibility(View.VISIBLE);
|
mEmptyView.setVisibility(View.VISIBLE);
|
||||||
mEmptyView.bringToFront();
|
mTaskStackHorizontalView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the task stack and hides the empty view.
|
* Shows the task stack and hides the empty view.
|
||||||
*/
|
*/
|
||||||
public void hideEmptyView() {
|
public void hideEmptyView() {
|
||||||
mEmptyView.setVisibility(View.INVISIBLE);
|
mEmptyView.setVisibility(View.GONE);
|
||||||
|
mTaskStackHorizontalView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.util.AttributeSet;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -31,6 +32,7 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.recents.tv.animations.DismissAnimationsHolder;
|
import com.android.systemui.recents.tv.animations.DismissAnimationsHolder;
|
||||||
|
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
|
||||||
import com.android.systemui.recents.tv.animations.ViewFocusAnimator;
|
import com.android.systemui.recents.tv.animations.ViewFocusAnimator;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
|
|
||||||
@@ -44,6 +46,7 @@ public class TaskCardView extends LinearLayout {
|
|||||||
|
|
||||||
private ViewFocusAnimator mViewFocusAnimator;
|
private ViewFocusAnimator mViewFocusAnimator;
|
||||||
private DismissAnimationsHolder mDismissAnimationsHolder;
|
private DismissAnimationsHolder mDismissAnimationsHolder;
|
||||||
|
private RecentsRowFocusAnimationHolder mRecentsRowFocusAnimationHolder;
|
||||||
|
|
||||||
public TaskCardView(Context context) {
|
public TaskCardView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -65,6 +68,8 @@ public class TaskCardView extends LinearLayout {
|
|||||||
mTitleTextView = (TextView) findViewById(R.id.card_title_text);
|
mTitleTextView = (TextView) findViewById(R.id.card_title_text);
|
||||||
mBadgeView = (ImageView) findViewById(R.id.card_extra_badge);
|
mBadgeView = (ImageView) findViewById(R.id.card_extra_badge);
|
||||||
mDismissAnimationsHolder = new DismissAnimationsHolder(this);
|
mDismissAnimationsHolder = new DismissAnimationsHolder(this);
|
||||||
|
View title = findViewById(R.id.card_info_field);
|
||||||
|
mRecentsRowFocusAnimationHolder = new RecentsRowFocusAnimationHolder(this, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(Task task) {
|
public void init(Task task) {
|
||||||
@@ -193,6 +198,10 @@ public class TaskCardView extends LinearLayout {
|
|||||||
mDismissAnimationsHolder.startDismissAnimation(listener);
|
mDismissAnimationsHolder.startDismissAnimation(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RecentsRowFocusAnimationHolder getRecentsRowFocusAnimationHolder() {
|
||||||
|
return mRecentsRowFocusAnimationHolder;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
|
|||||||
@@ -15,7 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.systemui.recents.tv.views;
|
package com.android.systemui.recents.tv.views;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorSet;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
import android.support.v17.leanback.widget.HorizontalGridView;
|
import android.support.v17.leanback.widget.HorizontalGridView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -36,10 +40,19 @@ import java.util.List;
|
|||||||
* Horizontal Grid View Implementation to show the Task Stack for TV.
|
* Horizontal Grid View Implementation to show the Task Stack for TV.
|
||||||
*/
|
*/
|
||||||
public class TaskStackHorizontalGridView extends HorizontalGridView implements TaskStackCallbacks {
|
public class TaskStackHorizontalGridView extends HorizontalGridView implements TaskStackCallbacks {
|
||||||
|
private static final int ANIMATION_DELAY_MS = 50;
|
||||||
|
private static final int MSG_START_RECENT_ROW_FOCUS_ANIMATION = 100;
|
||||||
|
private final Handler mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
if (msg.what == MSG_START_RECENT_ROW_FOCUS_ANIMATION) {
|
||||||
|
startRecentsRowFocusAnimation(msg.arg1 == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
private TaskStack mStack;
|
private TaskStack mStack;
|
||||||
private ArrayList<TaskCardView> mTaskViews = new ArrayList<>();
|
|
||||||
private Task mFocusedTask;
|
private Task mFocusedTask;
|
||||||
|
private AnimatorSet mRecentsRowFocusAnimation;
|
||||||
|
|
||||||
public TaskStackHorizontalGridView(Context context) {
|
public TaskStackHorizontalGridView(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -62,10 +75,18 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T
|
|||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
EventBus.getDefault().unregister(this);
|
EventBus.getDefault().unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets this view for reuse.
|
* Resets this view for reuse.
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
|
((TaskCardView) getChildAt(i)).getRecentsRowFocusAnimationHolder().reset();
|
||||||
|
}
|
||||||
|
if (mRecentsRowFocusAnimation != null && mRecentsRowFocusAnimation.isStarted()) {
|
||||||
|
mRecentsRowFocusAnimation.cancel();
|
||||||
|
}
|
||||||
|
mHandler.removeCallbacksAndMessages(null);
|
||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,10 +140,8 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T
|
|||||||
* @return Child view for given task
|
* @return Child view for given task
|
||||||
*/
|
*/
|
||||||
public TaskCardView getChildViewForTask(Task task) {
|
public TaskCardView getChildViewForTask(Task task) {
|
||||||
List<TaskCardView> taskViews = getTaskViews();
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
int taskViewCount = taskViews.size();
|
TaskCardView tv = (TaskCardView) getChildAt(i);
|
||||||
for (int i = 0; i < taskViewCount; i++) {
|
|
||||||
TaskCardView tv = taskViews.get(i);
|
|
||||||
if (tv.getTask() == task) {
|
if (tv.getTask() == task) {
|
||||||
return tv;
|
return tv;
|
||||||
}
|
}
|
||||||
@@ -130,12 +149,36 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TaskCardView> getTaskViews() {
|
/**
|
||||||
return mTaskViews;
|
* Starts the focus change animation.
|
||||||
|
*/
|
||||||
|
public void startRecentsRowFocusAnimation(final boolean hasFocus) {
|
||||||
|
if (getChildCount() == 0) {
|
||||||
|
// Animation request may happen before view is attached.
|
||||||
|
// Post again with small dealy so animation can be run again later.
|
||||||
|
if (getAdapter().getItemCount() > 0) {
|
||||||
|
mHandler.sendMessageDelayed(mHandler.obtainMessage(
|
||||||
|
MSG_START_RECENT_ROW_FOCUS_ANIMATION, hasFocus ? 1 : 0),
|
||||||
|
ANIMATION_DELAY_MS);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mRecentsRowFocusAnimation != null && mRecentsRowFocusAnimation.isStarted()) {
|
||||||
|
mRecentsRowFocusAnimation.cancel();
|
||||||
|
}
|
||||||
|
Animator animator = ((TaskCardView) getChildAt(0)).getRecentsRowFocusAnimationHolder()
|
||||||
|
.getFocusChangeAnimator(hasFocus);
|
||||||
|
mRecentsRowFocusAnimation = new AnimatorSet();
|
||||||
|
AnimatorSet.Builder builder = mRecentsRowFocusAnimation.play(animator);
|
||||||
|
for (int i = 1; i < getChildCount(); i++) {
|
||||||
|
builder.with(((TaskCardView) getChildAt(i)).getRecentsRowFocusAnimationHolder()
|
||||||
|
.getFocusChangeAnimator(hasFocus));
|
||||||
|
}
|
||||||
|
mRecentsRowFocusAnimation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStackTaskAdded(TaskStack stack, Task newTask){
|
public void onStackTaskAdded(TaskStack stack, Task newTask) {
|
||||||
getAdapter().notifyItemInserted(stack.getStackTasks().indexOf(newTask));
|
getAdapter().notifyItemInserted(stack.getStackTasks().indexOf(newTask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,9 +131,9 @@ public class PipRecentsOverlayManager {
|
|||||||
* Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
|
* Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity}
|
||||||
* is focused.
|
* is focused.
|
||||||
* This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
|
* This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}.
|
||||||
* @param hasRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task)
|
* @param allowRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task)
|
||||||
*/
|
*/
|
||||||
public void requestFocus(boolean hasRecentsFocusable) {
|
public void requestFocus(boolean allowRecentsFocusable) {
|
||||||
if (!mIsRecentsShown || mIsPipFocusedInRecent) {
|
if (!mIsRecentsShown || mIsPipFocusedInRecent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ public class PipRecentsOverlayManager {
|
|||||||
mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
|
mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams);
|
||||||
mPipControlsView.requestFocus();
|
mPipControlsView.requestFocus();
|
||||||
mPipControlsView.startFocusGainAnimation();
|
mPipControlsView.startFocusGainAnimation();
|
||||||
mRecentsView.setVisibility(hasRecentsFocusable ? View.VISIBLE : View.GONE);
|
mRecentsView.setVisibility(allowRecentsFocusable ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user