Support Lottie resouces in Illustration widget in SPA.
Bug: 242951784 Test: unit test and manually test on device Change-Id: Ic083dc5725f8e731106ccdf5f118c373b43e7e73
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
})
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 },
|
||||
)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
0
packages/SettingsLib/Spa/tests/res/raw/empty.json
Normal file
0
packages/SettingsLib/Spa/tests/res/raw/empty.json
Normal 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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user