Merge "Support Lottie resouces in Illustration widget in SPA."

This commit is contained in:
Kelly Zhang
2022-09-08 05:30:37 +00:00
committed by Android (Google) Code Review
8 changed files with 4034 additions and 4 deletions

View File

@@ -53,6 +53,15 @@ object IllustrationPageProvider : SettingsPageProvider {
@Composable
private fun IllustrationPage() {
Column(Modifier.verticalScroll(rememberScrollState())) {
Preference(object : PreferenceModel {
override val title = "Lottie Illustration"
})
Illustration(object : IllustrationModel {
override val resId = R.raw.accessibility_shortcut_type_triple_tap
override val resourceType = ResourceType.LOTTIE
})
Preference(object : PreferenceModel {
override val title = "Image Illustration"
})

View File

@@ -30,6 +30,7 @@ android_library {
"androidx.compose.ui_ui-tooling-preview",
"androidx.navigation_navigation-compose",
"com.google.android.material_material",
"lottie_compose",
],
kotlincflags: [
"-Xjvm-default=all",

View File

@@ -29,7 +29,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.ui.ImageBox
import com.android.settingslib.spa.widget.ui.Lottie
enum class ResourceType { IMAGE, LOTTIE }
/**
@@ -72,7 +72,7 @@ fun Illustration(
Column(
modifier = modifier
.fillMaxWidth()
.padding(SettingsDimension.illustrationPadding),
.padding(horizontal = SettingsDimension.illustrationPadding),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val illustrationModifier = modifier
@@ -85,7 +85,10 @@ fun Illustration(
when (resourceType) {
ResourceType.LOTTIE -> {
// TODO: Add Lottie function after lottie is enabled.
Lottie(
resId = resId,
modifier = illustrationModifier,
)
}
ResourceType.IMAGE -> {
ImageBox(

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2022 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.
*/
package com.android.settingslib.spa.widget.ui
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.animateLottieCompositionAsState
import com.airbnb.lottie.compose.rememberLottieComposition
@Composable
fun Lottie(
resId: Int,
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier,
) {
BaseLottie(resId)
}
}
@Composable
private fun BaseLottie(resId: Int) {
val composition by rememberLottieComposition(
LottieCompositionSpec.RawRes(resId)
)
val progress by animateLottieCompositionAsState(
composition,
iterations = LottieConstants.IterateForever,
)
LottieAnimation(
composition = composition,
progress = { progress },
)
}

View File

@@ -17,12 +17,14 @@
package com.android.settingslib.spa.widget
import androidx.annotation.DrawableRes
import androidx.annotation.RawRes
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.SemanticsPropertyKey
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.test.SemanticsMatcher
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.filterToOne
import androidx.compose.ui.test.hasAnyAncestor
import androidx.compose.ui.test.junit4.createComposeRule
@@ -54,9 +56,52 @@ class IllustrationTest {
fun hasDrawable(@DrawableRes id: Int): SemanticsMatcher =
SemanticsMatcher.expectValue(DrawableId, id)
val isIllustrationNode = !hasAnyAncestor(hasDrawable(resId))
val isIllustrationNode = hasAnyAncestor(hasDrawable(resId))
composeTestRule.onAllNodes(hasDrawable(resId))
.filterToOne(isIllustrationNode)
.assertIsDisplayed()
}
private val RawId = SemanticsPropertyKey<Int>("RawResId")
private var SemanticsPropertyReceiver.rawId by RawId
@Test
fun lottie_displayed() {
val resId = R.raw.accessibility_shortcut_type_triple_tap
composeTestRule.setContent {
Illustration(
resId = resId,
resourceType = ResourceType.LOTTIE,
modifier = Modifier.semantics { rawId = resId }
)
}
fun hasRaw(@RawRes id: Int): SemanticsMatcher =
SemanticsMatcher.expectValue(RawId, id)
val isIllustrationNode = hasAnyAncestor(hasRaw(resId))
composeTestRule.onAllNodes(hasRaw(resId))
.filterToOne(isIllustrationNode)
.assertIsDisplayed()
}
@Test
fun empty_lottie_not_displayed() {
val resId = R.raw.empty
composeTestRule.setContent {
Illustration(
resId = resId,
resourceType = ResourceType.LOTTIE,
modifier = Modifier.semantics { rawId = resId }
)
}
fun hasRaw(@RawRes id: Int): SemanticsMatcher =
SemanticsMatcher.expectValue(RawId, id)
val isIllustrationNode = hasAnyAncestor(hasRaw(resId))
composeTestRule.onAllNodes(hasRaw(resId))
.filterToOne(isIllustrationNode)
.assertIsNotDisplayed()
}
}