Merge "Cache Typeface for later animation" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
40ee59c0fc
@@ -21,7 +21,9 @@ import android.animation.AnimatorListenerAdapter
|
|||||||
import android.animation.TimeInterpolator
|
import android.animation.TimeInterpolator
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.text.Layout
|
import android.text.Layout
|
||||||
|
import android.util.SparseArray
|
||||||
|
|
||||||
private const val TAG_WGHT = "wght"
|
private const val TAG_WGHT = "wght"
|
||||||
private const val DEFAULT_ANIMATION_DURATION: Long = 300
|
private const val DEFAULT_ANIMATION_DURATION: Long = 300
|
||||||
@@ -72,6 +74,8 @@ class TextAnimator(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val typefaceCache = SparseArray<Typeface?>()
|
||||||
|
|
||||||
fun updateLayout(layout: Layout) {
|
fun updateLayout(layout: Layout) {
|
||||||
textInterpolator.layout = layout
|
textInterpolator.layout = layout
|
||||||
}
|
}
|
||||||
@@ -120,7 +124,12 @@ class TextAnimator(
|
|||||||
textInterpolator.targetPaint.textSize = textSize
|
textInterpolator.targetPaint.textSize = textSize
|
||||||
}
|
}
|
||||||
if (weight >= 0) {
|
if (weight >= 0) {
|
||||||
textInterpolator.targetPaint.fontVariationSettings = "'$TAG_WGHT' $weight"
|
// 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) {
|
if (color != null) {
|
||||||
textInterpolator.targetPaint.color = color
|
textInterpolator.targetPaint.color = color
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -18,12 +18,14 @@ package com.android.keyguard
|
|||||||
|
|
||||||
import android.animation.AnimatorListenerAdapter
|
import android.animation.AnimatorListenerAdapter
|
||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.text.Layout
|
import android.text.Layout
|
||||||
import android.text.StaticLayout
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentCaptor
|
import org.mockito.ArgumentCaptor
|
||||||
@@ -140,4 +142,41 @@ class TextAnimatorTest : SysuiTestCase() {
|
|||||||
verify(animationEndCallback).run()
|
verify(animationEndCallback).run()
|
||||||
verify(valueAnimator).removeListener(eq(captor.value))
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user