Merge "Prevent alpha transitions from clipping out-of-bounds clocks" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5623c50b66
@@ -25,7 +25,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:layout_gravity="center_horizontal|top">
|
||||
<FrameLayout
|
||||
<com.android.keyguard.KeyguardClockFrame
|
||||
android:id="@+id/lockscreen_clock_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/small_clock_height"
|
||||
@@ -34,7 +34,7 @@
|
||||
android:clipChildren="false"
|
||||
android:paddingStart="@dimen/clock_padding_start"
|
||||
android:visibility="invisible" />
|
||||
<FrameLayout
|
||||
<com.android.keyguard.KeyguardClockFrame
|
||||
android:id="@+id/lockscreen_clock_view_large"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
android:clipChildren="false"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout
|
||||
<com.android.keyguard.KeyguardStatusContainer
|
||||
android:id="@+id/status_view_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -48,5 +48,5 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/qs_media_padding"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</com.android.keyguard.KeyguardStatusContainer>
|
||||
</com.android.keyguard.KeyguardStatusView>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.android.keyguard
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
|
||||
class KeyguardClockFrame(
|
||||
context: Context,
|
||||
attrs: AttributeSet,
|
||||
) : FrameLayout(context, attrs) {
|
||||
private var drawAlpha: Int = 255
|
||||
|
||||
protected override fun onSetAlpha(alpha: Int): Boolean {
|
||||
drawAlpha = alpha
|
||||
return true
|
||||
}
|
||||
|
||||
protected override fun dispatchDraw(canvas: Canvas) {
|
||||
val restoreTo = saveCanvasAlpha(this, canvas, drawAlpha)
|
||||
super.dispatchDraw(canvas)
|
||||
canvas.restoreToCount(restoreTo)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun saveCanvasAlpha(view: View, canvas: Canvas, alpha: Int): Int {
|
||||
var (x, y) =
|
||||
run {
|
||||
val locationOnScreen = IntArray(2)
|
||||
view.getLocationOnScreen(locationOnScreen)
|
||||
Pair(locationOnScreen[0].toFloat(), locationOnScreen[1].toFloat())
|
||||
}
|
||||
|
||||
return canvas.saveLayerAlpha(-1f * x, -1f * y, x + view.width, y + view.height, alpha)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,11 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
@@ -69,12 +69,13 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
/**
|
||||
* Frame for small/large clocks
|
||||
*/
|
||||
private FrameLayout mSmallClockFrame;
|
||||
private FrameLayout mLargeClockFrame;
|
||||
private KeyguardClockFrame mSmallClockFrame;
|
||||
private KeyguardClockFrame mLargeClockFrame;
|
||||
private ClockController mClock;
|
||||
|
||||
private View mStatusArea;
|
||||
private int mSmartspaceTopOffset;
|
||||
private int mDrawAlpha = 255;
|
||||
|
||||
/**
|
||||
* Maintain state so that a newly connected plugin can be initialized.
|
||||
@@ -121,6 +122,19 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
onDensityOrFontScaleChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSetAlpha(int alpha) {
|
||||
mDrawAlpha = alpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
int restoreTo = KeyguardClockFrame.saveCanvasAlpha(this, canvas, mDrawAlpha);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restoreToCount(restoreTo);
|
||||
}
|
||||
|
||||
public void setLogBuffer(LogBuffer logBuffer) {
|
||||
mLogBuffer = logBuffer;
|
||||
}
|
||||
|
||||
@@ -178,20 +178,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set alpha directly to mView will clip clock, so we set alpha to clock face instead
|
||||
*/
|
||||
public void setAlpha(float alpha) {
|
||||
ClockController clock = getClock();
|
||||
if (clock != null) {
|
||||
clock.getLargeClock().getView().setAlpha(alpha);
|
||||
clock.getSmallClock().getView().setAlpha(alpha);
|
||||
}
|
||||
if (mStatusArea != null) {
|
||||
mStatusArea.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach the controller to the view it relates to.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.android.keyguard
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.util.AttributeSet
|
||||
import android.widget.LinearLayout
|
||||
|
||||
class KeyguardStatusContainer(
|
||||
context: Context,
|
||||
attrs: AttributeSet,
|
||||
) : LinearLayout(context, attrs) {
|
||||
private var drawAlpha: Int = 255
|
||||
|
||||
protected override fun onSetAlpha(alpha: Int): Boolean {
|
||||
drawAlpha = alpha
|
||||
return true
|
||||
}
|
||||
|
||||
protected override fun dispatchDraw(canvas: Canvas) {
|
||||
val restoreTo = KeyguardClockFrame.saveCanvasAlpha(this, canvas, drawAlpha)
|
||||
super.dispatchDraw(canvas)
|
||||
canvas.restoreToCount(restoreTo)
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.android.keyguard;
|
||||
import static java.util.Collections.emptySet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.Build;
|
||||
import android.os.Trace;
|
||||
import android.util.AttributeSet;
|
||||
@@ -47,6 +48,7 @@ public class KeyguardStatusView extends GridLayout {
|
||||
private KeyguardSliceView mKeyguardSlice;
|
||||
private View mMediaHostContainer;
|
||||
|
||||
private int mDrawAlpha = 255;
|
||||
private float mDarkAmount = 0;
|
||||
|
||||
public KeyguardStatusView(Context context) {
|
||||
@@ -136,30 +138,16 @@ public class KeyguardStatusView extends GridLayout {
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clock content will be clipped when goes beyond bounds,
|
||||
* so we setAlpha for all views except clock
|
||||
*/
|
||||
public void setAlpha(float alpha, boolean excludeClock) {
|
||||
if (!excludeClock) {
|
||||
setAlpha(alpha);
|
||||
return;
|
||||
}
|
||||
if (alpha == 1 || alpha == 0) {
|
||||
setAlpha(alpha);
|
||||
}
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
View child = getChildAt(i);
|
||||
if (child == mStatusViewContainer) {
|
||||
for (int j = 0; j < mStatusViewContainer.getChildCount(); j++) {
|
||||
View innerChild = mStatusViewContainer.getChildAt(j);
|
||||
if (innerChild != mClockView) {
|
||||
innerChild.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
child.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected boolean onSetAlpha(int alpha) {
|
||||
mDrawAlpha = alpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
int restoreTo = KeyguardClockFrame.saveCanvasAlpha(this, canvas, mDrawAlpha);
|
||||
super.dispatchDraw(canvas);
|
||||
canvas.restoreToCount(restoreTo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,8 +180,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
*/
|
||||
public void setAlpha(float alpha) {
|
||||
if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
|
||||
mView.setAlpha(alpha, true);
|
||||
mKeyguardClockSwitchController.setAlpha(alpha);
|
||||
mView.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
||||
|
||||
private KeyguardClockSwitchController mController;
|
||||
private View mSliceView;
|
||||
private LinearLayout mStatusArea;
|
||||
private FakeExecutor mExecutor;
|
||||
|
||||
@Before
|
||||
@@ -196,8 +195,8 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
||||
|
||||
mSliceView = new View(getContext());
|
||||
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
|
||||
mStatusArea = new LinearLayout(getContext());
|
||||
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
|
||||
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(
|
||||
new LinearLayout(getContext()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -402,15 +401,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
||||
assertNull(mController.getClock());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAlpha_setClockAlphaForCLockFace() {
|
||||
mController.onViewAttached();
|
||||
mController.setAlpha(0.5f);
|
||||
verify(mLargeClockView).setAlpha(0.5f);
|
||||
verify(mSmallClockView).setAlpha(0.5f);
|
||||
assertEquals(0.5f, mStatusArea.getAlpha(), 0.0f);
|
||||
}
|
||||
|
||||
private void verifyAttachment(VerificationMode times) {
|
||||
verify(mClockRegistry, times).registerClockChangeListener(
|
||||
any(ClockRegistry.ClockChangeListener.class));
|
||||
|
||||
@@ -24,46 +24,33 @@ class KeyguardStatusViewTest : SysuiTestCase() {
|
||||
get() = keyguardStatusView.findViewById(R.id.status_view_media_container)
|
||||
private val statusViewContainer: ViewGroup
|
||||
get() = keyguardStatusView.findViewById(R.id.status_view_container)
|
||||
private val clockView: ViewGroup
|
||||
get() = keyguardStatusView.findViewById(R.id.keyguard_clock_container)
|
||||
private val childrenExcludingMedia
|
||||
get() = statusViewContainer.children.filter { it != mediaView }
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
keyguardStatusView = LayoutInflater.from(context)
|
||||
.inflate(R.layout.keyguard_status_view, /* root= */ null) as KeyguardStatusView
|
||||
keyguardStatusView =
|
||||
LayoutInflater.from(context).inflate(R.layout.keyguard_status_view, /* root= */ null)
|
||||
as KeyguardStatusView
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
|
||||
val translationY = 1234f
|
||||
|
||||
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */true)
|
||||
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */ true)
|
||||
|
||||
assertThat(mediaView.translationY).isEqualTo(0)
|
||||
|
||||
childrenExcludingMedia.forEach {
|
||||
assertThat(it.translationY).isEqualTo(translationY)
|
||||
}
|
||||
childrenExcludingMedia.forEach { assertThat(it.translationY).isEqualTo(translationY) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setChildrenTranslationYIncludeMediaView() {
|
||||
val translationY = 1234f
|
||||
|
||||
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */false)
|
||||
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */ false)
|
||||
|
||||
statusViewContainer.children.forEach {
|
||||
assertThat(it.translationY).isEqualTo(translationY)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setAlphaExcludeClock() {
|
||||
keyguardStatusView.setAlpha(0.5f, /* excludeClock= */true)
|
||||
assertThat(statusViewContainer.alpha).isNotEqualTo(0.5f)
|
||||
assertThat(mediaView.alpha).isEqualTo(0.5f)
|
||||
assertThat(clockView.alpha).isNotEqualTo(0.5f)
|
||||
statusViewContainer.children.forEach { assertThat(it.translationY).isEqualTo(translationY) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user