PIP: Show background scrim for PIP controls in Recents

Scrim will fade in after the PIP control's focus losing animation,
and will be gone immediately when PIP control gets focus.

Bug: 28041690
Change-Id: Ibb7fa0ce15ba1af13781a1bd5e87609fefa95cc0
This commit is contained in:
Jaewan Kim
2016-04-14 08:08:58 +09:00
parent 6d1a776c26
commit dded3aa8bd
9 changed files with 139 additions and 105 deletions

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="scaleX"
android:valueTo="0.7"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<objectAnimator
android:propertyName="scaleY"
android:valueTo="0.7"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
</set>

View File

@@ -14,8 +14,21 @@
limitations under the License.
-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationY"
android:valueTo="0dp"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="translationY"
android:valueTo="0dp"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<objectAnimator
android:propertyName="scaleX"
android:valueTo="1.0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<objectAnimator
android:propertyName="scaleY"
android:valueTo="1.0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
</set>

View File

@@ -14,8 +14,21 @@
limitations under the License.
-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="translationY"
android:valueTo="-57dp"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="translationY"
android:valueTo="-57dp"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<objectAnimator
android:propertyName="scaleX"
android:valueTo="0.7"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<objectAnimator
android:propertyName="scaleY"
android:valueTo="0.7"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
</set>

View File

@@ -14,16 +14,8 @@
limitations under the License.
-->
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:propertyName="scaleX"
android:valueTo="1.0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
<objectAnimator
android:propertyName="scaleY"
android:valueTo="1.0"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="@integer/recents_tv_pip_focus_anim_duration" />
</set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="alpha"
android:valueTo="1"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:duration="100" />

View File

@@ -0,0 +1,23 @@
<!--
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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#80000000"
android:endColor="#00000000"
android:angle="90"/>
</shape>

View File

@@ -16,14 +16,31 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="top|center_horizontal">
android:layout_height="wrap_content"
android:gravity="top|center_horizontal"
android:orientation="vertical">
<com.android.systemui.tv.pip.PipRecentsControlsView
android:id="@+id/pip_controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:clipToPadding="false">
<View
android:id="@+id/scrim"
android:layout_width="160dp"
android:layout_height="32dp"
android:translationY="-46dp"
android:layout_gravity="top|center_horizontal"
android:background="@drawable/tv_pip_recents_overlay_scrim" />
<com.android.systemui.tv.pip.PipControlsView
android:id="@+id/pip_control_contents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="top|center_horizontal" />
</com.android.systemui.tv.pip.PipRecentsControlsView>
<View
android:id="@+id/recents"

View File

@@ -52,9 +52,6 @@
<dimen name="recents_tv_dismiss_icon_bottom_margin">1dip</dimen>
<dimen name="recents_tv_dismiss_text_size">12sp</dimen>
<!-- Values for PIP in recents -->
<dimen name="recents_tv_pip_controls_margin_top">10dp</dimen>
<!-- Extra space around the PIP and its outline in PIP onboarding activity -->
<dimen name="tv_pip_bounds_space">3dp</dimen>

View File

@@ -57,9 +57,9 @@ public class PipControlsView extends LinearLayout {
final PipManager mPipManager = PipManager.getInstance();
Listener mListener;
PipControlButtonView mFullButtonView;
PipControlButtonView mCloseButtonView;
PipControlButtonView mPlayPauseButtonView;
private PipControlButtonView mFullButtonView;
private PipControlButtonView mCloseButtonView;
private PipControlButtonView mPlayPauseButtonView;
private boolean mHasFocus;
private OnFocusChangeListener mOnChildFocusChangeListener;

View File

@@ -18,14 +18,15 @@ package com.android.systemui.tv.pip;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.widget.FrameLayout;
import com.android.systemui.R;
@@ -34,9 +35,9 @@ import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_PAUSED;
import static com.android.systemui.tv.pip.PipManager.PLAYBACK_STATE_UNAVAILABLE;
/**
* An extended version of {@link PipControlsView} that supports animation in Recents.
* An FrameLayout that contains {@link PipControlsView} with its scrim.
*/
public class PipRecentsControlsView extends PipControlsView {
public class PipRecentsControlsView extends FrameLayout {
/**
* An interface to listen user action.
*/
@@ -47,7 +48,11 @@ public class PipRecentsControlsView extends PipControlsView {
abstract void onBackPressed();
}
private AnimatorSet mFocusGainAnimatorSet;
final PipManager mPipManager = PipManager.getInstance();
private Listener mListener;
private PipControlsView mPipControlsView;
private View mScrim;
private Animator mFocusGainAnimator;
private AnimatorSet mFocusLoseAnimatorSet;
public PipRecentsControlsView(Context context) {
@@ -71,26 +76,20 @@ public class PipRecentsControlsView extends PipControlsView {
public void onFinishInflate() {
super.onFinishInflate();
int buttonsFocusGainAnim = R.anim.tv_pip_controls_buttons_in_recents_focus_gain_animation;
mFocusGainAnimatorSet = new AnimatorSet();
mFocusGainAnimatorSet.playTogether(
loadAnimator(this, R.anim.tv_pip_controls_in_recents_focus_gain_animation),
loadAnimator(mFullButtonView,buttonsFocusGainAnim),
loadAnimator(mPlayPauseButtonView, buttonsFocusGainAnim),
loadAnimator(mCloseButtonView, buttonsFocusGainAnim));
mPipControlsView = (PipControlsView) findViewById(R.id.pip_control_contents);
mScrim = findViewById(R.id.scrim);
mFocusGainAnimator = loadAnimator(mPipControlsView,
R.anim.tv_pip_controls_in_recents_focus_gain_animation);
int buttonsFocusLoseAnim = R.anim.tv_pip_controls_buttons_in_recents_focus_lose_animation;
mFocusLoseAnimatorSet = new AnimatorSet();
mFocusLoseAnimatorSet.playTogether(
loadAnimator(this, R.anim.tv_pip_controls_in_recents_focus_lose_animation),
loadAnimator(mFullButtonView, buttonsFocusLoseAnim),
loadAnimator(mPlayPauseButtonView, buttonsFocusLoseAnim),
loadAnimator(mCloseButtonView, buttonsFocusLoseAnim));
mFocusLoseAnimatorSet.playSequentially(
loadAnimator(mPipControlsView,
R.anim.tv_pip_controls_in_recents_focus_lose_animation),
loadAnimator(mScrim, R.anim.tv_pip_controls_in_recents_scrim_fade_in_animation));
Rect pipBounds = mPipManager.getRecentsFocusedPipBounds();
int pipControlsMarginTop = getContext().getResources().getDimensionPixelSize(
R.dimen.recents_tv_pip_controls_margin_top);
setPadding(0, pipBounds.bottom + pipControlsMarginTop, 0, 0);
setPadding(0, pipBounds.bottom, 0, 0);
}
private Animator loadAnimator(View view, int animatorResId) {
@@ -103,44 +102,53 @@ public class PipRecentsControlsView extends PipControlsView {
* Starts focus gaining animation.
*/
public void startFocusGainAnimation() {
if (mFocusLoseAnimatorSet.isStarted()) {
mFocusLoseAnimatorSet.cancel();
}
mFocusGainAnimatorSet.start();
// Hides the scrim view as soon as possible, before the PIP resize animation starts.
// If we don't, PIP will be moved down a bit and a gap between the scrim and PIP will be
// shown at the bottom of the PIP.
mScrim.setAlpha(0);
startAnimator(mFocusGainAnimator, mFocusLoseAnimatorSet);
}
/**
* Starts focus losing animation.
*/
public void startFocusLoseAnimation() {
if (mFocusGainAnimatorSet.isStarted()) {
mFocusGainAnimatorSet.cancel();
}
mFocusLoseAnimatorSet.start();
startAnimator(mFocusLoseAnimatorSet, mFocusGainAnimator);
}
/**
* Resets the view to the initial state. (i.e. end of the focus gain)
*/
public void reset() {
if (mFocusGainAnimatorSet.isStarted()) {
mFocusGainAnimatorSet.cancel();
}
if (mFocusLoseAnimatorSet.isStarted()) {
mFocusLoseAnimatorSet.cancel();
}
cancelAnimator(mFocusGainAnimator);
cancelAnimator(mFocusLoseAnimatorSet);
// Reset to initial state (i.e. end of focused)
requestFocus();
setTranslationY(0);
setScaleXY(mFullButtonView, 1);
setScaleXY(mPlayPauseButtonView, 1);
setScaleXY(mCloseButtonView, 1);
mPipControlsView.setTranslationY(0);
mPipControlsView.setScaleX(1);
mPipControlsView.setScaleY(1);
mScrim.setAlpha(0);
}
private void setScaleXY(View view, float scale) {
view.setScaleX(scale);
view.setScaleY(scale);
private static void startAnimator(Animator animator, Animator previousAnimator) {
cancelAnimator(previousAnimator);
if (!animator.isStarted()) {
animator.start();
}
}
private static void cancelAnimator(Animator animator) {
if (animator.isStarted()) {
animator.cancel();
}
}
/**
* Sets listeners.
*/
public void setListener(Listener listener) {
mPipControlsView.setListener(listener);
}
@Override
@@ -148,8 +156,8 @@ public class PipRecentsControlsView extends PipControlsView {
if (!event.isCanceled()
&& event.getKeyCode() == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_UP) {
if (mListener != null) {
((PipRecentsControlsView.Listener) mListener).onBackPressed();
if (mPipControlsView.mListener != null) {
((PipRecentsControlsView.Listener) mPipControlsView.mListener).onBackPressed();
}
return true;
}