Loading packages/SystemUI/src/com/android/keyguard/TextAnimator.kt +19 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import android.animation.AnimatorListenerAdapter import android.animation.TimeInterpolator import android.animation.ValueAnimator import android.graphics.Canvas import android.graphics.Typeface import android.text.Layout import android.util.SparseArray private const val TAG_WGHT = "wght" private const val DEFAULT_ANIMATION_DURATION: Long = 300 Loading Loading @@ -72,6 +74,8 @@ class TextAnimator( }) } private val typefaceCache = SparseArray<Typeface?>() fun updateLayout(layout: Layout) { textInterpolator.layout = layout } Loading Loading @@ -120,7 +124,12 @@ class TextAnimator( textInterpolator.targetPaint.textSize = textSize } if (weight >= 0) { // Paint#setFontVariationSettings creates Typeface instance from scratch. To reduce the // memory impact, cache the typeface result. textInterpolator.targetPaint.typeface = typefaceCache.getOrElse(weight) { textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight" textInterpolator.targetPaint.typeface } } if (color != null) { textInterpolator.targetPaint.color = color Loading Loading @@ -155,3 +164,12 @@ class TextAnimator( } } } private fun <V> SparseArray<V>.getOrElse(key: Int, defaultValue: () -> V): V { var v = get(key) if (v == null) { v = defaultValue() put(key, v) } return v } No newline at end of file packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt +39 −0 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ package com.android.keyguard import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.graphics.Typeface import android.testing.AndroidTestingRunner import android.text.Layout import android.text.StaticLayout import android.text.TextPaint import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor Loading Loading @@ -140,4 +142,41 @@ class TextAnimatorTest : SysuiTestCase() { verify(animationEndCallback).run() verify(valueAnimator).removeListener(eq(captor.value)) } @Test fun testCacheTypeface() { val layout = makeLayout("Hello, World", PAINT) val valueAnimator = mock(ValueAnimator::class.java) val textInterpolator = mock(TextInterpolator::class.java) val paint = TextPaint().apply { typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf") } `when`(textInterpolator.targetPaint).thenReturn(paint) val textAnimator = TextAnimator(layout, {}).apply { this.textInterpolator = textInterpolator this.animator = valueAnimator } textAnimator.setTextStyle( weight = 400, animate = true ) val prevTypeface = paint.typeface textAnimator.setTextStyle( weight = 700, animate = true ) assertThat(paint.typeface).isNotSameInstanceAs(prevTypeface) textAnimator.setTextStyle( weight = 400, animate = true ) assertThat(paint.typeface).isSameInstanceAs(prevTypeface) } } Loading
packages/SystemUI/src/com/android/keyguard/TextAnimator.kt +19 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,9 @@ import android.animation.AnimatorListenerAdapter import android.animation.TimeInterpolator import android.animation.ValueAnimator import android.graphics.Canvas import android.graphics.Typeface import android.text.Layout import android.util.SparseArray private const val TAG_WGHT = "wght" private const val DEFAULT_ANIMATION_DURATION: Long = 300 Loading Loading @@ -72,6 +74,8 @@ class TextAnimator( }) } private val typefaceCache = SparseArray<Typeface?>() fun updateLayout(layout: Layout) { textInterpolator.layout = layout } Loading Loading @@ -120,7 +124,12 @@ class TextAnimator( textInterpolator.targetPaint.textSize = textSize } if (weight >= 0) { // Paint#setFontVariationSettings creates Typeface instance from scratch. To reduce the // memory impact, cache the typeface result. textInterpolator.targetPaint.typeface = typefaceCache.getOrElse(weight) { textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight" textInterpolator.targetPaint.typeface } } if (color != null) { textInterpolator.targetPaint.color = color Loading Loading @@ -155,3 +164,12 @@ class TextAnimator( } } } private fun <V> SparseArray<V>.getOrElse(key: Int, defaultValue: () -> V): V { var v = get(key) if (v == null) { v = defaultValue() put(key, v) } return v } No newline at end of file
packages/SystemUI/tests/src/com/android/keyguard/TextAnimatorTest.kt +39 −0 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ package com.android.keyguard import android.animation.AnimatorListenerAdapter import android.animation.ValueAnimator import android.graphics.Typeface import android.testing.AndroidTestingRunner import android.text.Layout import android.text.StaticLayout import android.text.TextPaint import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.google.common.truth.Truth.assertThat import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor Loading Loading @@ -140,4 +142,41 @@ class TextAnimatorTest : SysuiTestCase() { verify(animationEndCallback).run() verify(valueAnimator).removeListener(eq(captor.value)) } @Test fun testCacheTypeface() { val layout = makeLayout("Hello, World", PAINT) val valueAnimator = mock(ValueAnimator::class.java) val textInterpolator = mock(TextInterpolator::class.java) val paint = TextPaint().apply { typeface = Typeface.createFromFile("/system/fonts/Roboto-Regular.ttf") } `when`(textInterpolator.targetPaint).thenReturn(paint) val textAnimator = TextAnimator(layout, {}).apply { this.textInterpolator = textInterpolator this.animator = valueAnimator } textAnimator.setTextStyle( weight = 400, animate = true ) val prevTypeface = paint.typeface textAnimator.setTextStyle( weight = 700, animate = true ) assertThat(paint.typeface).isNotSameInstanceAs(prevTypeface) textAnimator.setTextStyle( weight = 400, animate = true ) assertThat(paint.typeface).isSameInstanceAs(prevTypeface) } }