Merge "Illumination hover state" into rvc-dev
This commit is contained in:
@@ -124,7 +124,7 @@
|
||||
android:layout_gravity="center"
|
||||
>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
@@ -132,7 +132,7 @@
|
||||
android:id="@+id/action0"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
@@ -140,7 +140,7 @@
|
||||
android:id="@+id/action1"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
android:gravity="center"
|
||||
>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
@@ -71,7 +71,7 @@
|
||||
android:id="@+id/action0"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
@@ -79,7 +79,7 @@
|
||||
android:id="@+id/action1"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center"
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
android:gravity="center"
|
||||
>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
@@ -207,7 +207,7 @@
|
||||
android:id="@+id/action0"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
@@ -217,7 +217,7 @@
|
||||
android:id="@+id/action1"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginStart="8dp"
|
||||
@@ -227,7 +227,7 @@
|
||||
android:id="@+id/action2"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
@@ -237,7 +237,7 @@
|
||||
android:id="@+id/action3"
|
||||
/>
|
||||
<ImageButton
|
||||
style="@android:style/Widget.Material.Button.Borderless.Small"
|
||||
style="@style/MediaPlayer.Button"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
|
||||
@@ -620,6 +620,10 @@
|
||||
<item name="rotateButtonScaleX">-1</item>
|
||||
</style>
|
||||
|
||||
<style name="MediaPlayer.Button" parent="@android:style/Widget.Material.Button.Borderless.Small">
|
||||
<item name="android:background">@null</item>
|
||||
</style>
|
||||
|
||||
<!-- Used to style charging animation AVD animation -->
|
||||
<style name="ChargingAnim" />
|
||||
|
||||
|
||||
@@ -12,11 +12,14 @@ import android.graphics.ColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.RadialGradient
|
||||
import android.graphics.Rect
|
||||
import android.graphics.Shader
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.AttributeSet
|
||||
import android.util.MathUtils
|
||||
import android.util.MathUtils.lerp
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import androidx.annotation.Keep
|
||||
import com.android.internal.graphics.ColorUtils
|
||||
import com.android.internal.graphics.ColorUtils.blendARGB
|
||||
@@ -26,6 +29,8 @@ import org.xmlpull.v1.XmlPullParser
|
||||
|
||||
private const val BACKGROUND_ANIM_DURATION = 370L
|
||||
private const val RIPPLE_ANIM_DURATION = 800L
|
||||
private const val RIPPLE_DOWN_PROGRESS = 0.05f
|
||||
private const val RIPPLE_CANCEL_DURATION = 200L
|
||||
private val GRADIENT_STOPS = floatArrayOf(0.2f, 1f)
|
||||
|
||||
private data class RippleData(
|
||||
@@ -50,7 +55,7 @@ class IlluminationDrawable : Drawable() {
|
||||
private var tmpHsl = floatArrayOf(0f, 0f, 0f)
|
||||
private var paint = Paint()
|
||||
|
||||
var backgroundColor = Color.TRANSPARENT
|
||||
private var backgroundColor = Color.TRANSPARENT
|
||||
set(value) {
|
||||
if (value == field) {
|
||||
return
|
||||
@@ -59,7 +64,52 @@ class IlluminationDrawable : Drawable() {
|
||||
animateBackground()
|
||||
}
|
||||
|
||||
private var rippleAnimation: AnimatorSet? = null
|
||||
/**
|
||||
* Draw a small highlight under the finger before expanding (or cancelling) it.
|
||||
*/
|
||||
private var pressed: Boolean = false
|
||||
set(value) {
|
||||
if (value == field) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
|
||||
if (value) {
|
||||
rippleAnimation?.cancel()
|
||||
rippleData.alpha = 1f
|
||||
rippleData.progress = RIPPLE_DOWN_PROGRESS
|
||||
} else {
|
||||
rippleAnimation?.cancel()
|
||||
rippleAnimation = ValueAnimator.ofFloat(rippleData.alpha, 0f).apply {
|
||||
duration = RIPPLE_CANCEL_DURATION
|
||||
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
||||
addUpdateListener {
|
||||
rippleData.alpha = it.animatedValue as Float
|
||||
invalidateSelf()
|
||||
}
|
||||
addListener(object : AnimatorListenerAdapter() {
|
||||
var cancelled = false
|
||||
override fun onAnimationCancel(animation: Animator?) {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
if (cancelled) {
|
||||
return
|
||||
}
|
||||
rippleData.progress = 0f
|
||||
rippleData.alpha = 0f
|
||||
rippleAnimation = null
|
||||
invalidateSelf()
|
||||
}
|
||||
})
|
||||
start()
|
||||
}
|
||||
}
|
||||
invalidateSelf()
|
||||
}
|
||||
|
||||
private var rippleAnimation: Animator? = null
|
||||
private var backgroundAnimation: ValueAnimator? = null
|
||||
|
||||
/**
|
||||
@@ -147,16 +197,10 @@ class IlluminationDrawable : Drawable() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws an animated ripple that expands from {@param x} and {@param y} fading away.
|
||||
*
|
||||
* @param x X position of gradient centroid.
|
||||
* @param y Y position of gradient centroid.
|
||||
* Draws an animated ripple that expands fading away.
|
||||
*/
|
||||
fun illuminate(x: Int, y: Int) {
|
||||
rippleData.x = x.toFloat()
|
||||
rippleData.y = y.toFloat()
|
||||
private fun illuminate() {
|
||||
rippleData.alpha = 1f
|
||||
rippleData.progress = 0f
|
||||
invalidateSelf()
|
||||
|
||||
rippleAnimation?.cancel()
|
||||
@@ -169,7 +213,7 @@ class IlluminationDrawable : Drawable() {
|
||||
rippleData.alpha = it.animatedValue as Float
|
||||
invalidateSelf()
|
||||
}
|
||||
}, ValueAnimator.ofFloat(0f, 1f).apply {
|
||||
}, ValueAnimator.ofFloat(rippleData.progress, 1f).apply {
|
||||
duration = RIPPLE_ANIM_DURATION
|
||||
interpolator = Interpolators.LINEAR_OUT_SLOW_IN
|
||||
addUpdateListener {
|
||||
@@ -187,4 +231,34 @@ class IlluminationDrawable : Drawable() {
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup touch events on a view such as tapping it would trigger effects on this drawable.
|
||||
* @param target View receiving touched.
|
||||
* @param container View that holds this drawable.
|
||||
*/
|
||||
fun setupTouch(target: View, container: View) {
|
||||
val containerRect = Rect()
|
||||
target.setOnTouchListener { view: View, event: MotionEvent ->
|
||||
container.getGlobalVisibleRect(containerRect)
|
||||
rippleData.x = event.rawX - containerRect.left
|
||||
rippleData.y = event.rawY - containerRect.top
|
||||
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
pressed = true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
invalidateSelf()
|
||||
}
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
pressed = false
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
illuminate()
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,21 +183,17 @@ public class QSMediaPlayer extends MediaControlPanel {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mMediaNotifView.getBackground() instanceof IlluminationDrawable) {
|
||||
((IlluminationDrawable) mMediaNotifView.getBackground())
|
||||
.setupTouch(thisBtn, mMediaNotifView);
|
||||
}
|
||||
|
||||
Drawable thatIcon = thatBtn.getDrawable();
|
||||
thisBtn.setImageDrawable(thatIcon.mutate());
|
||||
thisBtn.setVisibility(View.VISIBLE);
|
||||
thisBtn.setOnClickListener(v -> {
|
||||
Log.d(TAG, "clicking on other button");
|
||||
thatBtn.performClick();
|
||||
if (mMediaNotifView.getBackground() instanceof IlluminationDrawable) {
|
||||
Rect mediaRect = new Rect();
|
||||
Rect buttonRect = new Rect();
|
||||
mMediaNotifView.getGlobalVisibleRect(mediaRect);
|
||||
thisBtn.getGlobalVisibleRect(buttonRect);
|
||||
((IlluminationDrawable) mMediaNotifView.getBackground()).illuminate(
|
||||
buttonRect.centerX() - mediaRect.left,
|
||||
buttonRect.centerY() - mediaRect.top);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.media.IlluminationDrawable;
|
||||
import com.android.systemui.media.MediaControlPanel;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
|
||||
@@ -104,6 +105,11 @@ public class QuickQSMediaPlayer extends MediaControlPanel {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mMediaNotifView.getBackground() instanceof IlluminationDrawable) {
|
||||
((IlluminationDrawable) mMediaNotifView.getBackground())
|
||||
.setupTouch(thisBtn, mMediaNotifView);
|
||||
}
|
||||
|
||||
Drawable thatIcon = thatBtn.getDrawable();
|
||||
thisBtn.setImageDrawable(thatIcon.mutate());
|
||||
thisBtn.setVisibility(View.VISIBLE);
|
||||
|
||||
Reference in New Issue
Block a user