Merge "Add ProgressBar and LoadingBar widgets to SPA and create gallery samples for them."
This commit is contained in:
@@ -25,6 +25,7 @@ import com.android.settingslib.spa.gallery.home.HomePageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.FooterPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.IllustrationPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ProgressBarPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SliderPageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.MainSwitchPreferencePageProvider
|
||||
@@ -66,6 +67,7 @@ object GallerySpaEnvironment : SpaEnvironment() {
|
||||
IllustrationPageProvider,
|
||||
CategoryPageProvider,
|
||||
ActionButtonPageProvider,
|
||||
ProgressBarPageProvider,
|
||||
),
|
||||
rootPages = listOf(
|
||||
HomePageProvider.createSettingsPage(),
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.settingslib.spa.gallery.page.ArgumentPageModel
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.FooterPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.IllustrationPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ProgressBarPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.SliderPageProvider
|
||||
import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider
|
||||
@@ -54,6 +55,7 @@ object HomePageProvider : SettingsPageProvider {
|
||||
IllustrationPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
CategoryPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ActionButtonPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ProgressBarPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.gallery.page
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Delete
|
||||
import androidx.compose.material.icons.outlined.SystemUpdate
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPage
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.theme.SettingsTheme
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.ProgressBarPreference
|
||||
import com.android.settingslib.spa.widget.preference.ProgressBarPreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.ProgressBarWithDataPreference
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.CircularLoadingBar
|
||||
import com.android.settingslib.spa.widget.ui.CircularProgressBar
|
||||
import com.android.settingslib.spa.widget.ui.LinearLoadingBar
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private const val TITLE = "Sample ProgressBar"
|
||||
|
||||
object ProgressBarPageProvider : SettingsPageProvider {
|
||||
override val name = "ProgressBar"
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = SettingsPage.create(name))
|
||||
.setIsAllowSearch(true)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
// Mocks a loading time of 2 seconds.
|
||||
var loading by remember { mutableStateOf(true) }
|
||||
LaunchedEffect(Unit) {
|
||||
delay(2000)
|
||||
loading = false
|
||||
}
|
||||
|
||||
RegularScaffold(title = TITLE) {
|
||||
// Auto update the progress and finally jump tp 0.4f.
|
||||
var progress by remember { mutableStateOf(0f) }
|
||||
LaunchedEffect(Unit) {
|
||||
delay(2000)
|
||||
while (progress < 1f) {
|
||||
delay(100)
|
||||
progress += 0.01f
|
||||
}
|
||||
delay(500)
|
||||
progress = 0.4f
|
||||
}
|
||||
|
||||
// Show as a placeholder for progress bar
|
||||
LargeProgressBar(progress)
|
||||
// The remaining information only shows after loading complete.
|
||||
if (!loading) {
|
||||
SimpleProgressBar()
|
||||
ProgressBarWithData()
|
||||
CircularProgressBar(progress = progress, radius = 160f)
|
||||
}
|
||||
}
|
||||
|
||||
// Add loading bar examples, running for 2 seconds.
|
||||
LinearLoadingBar(isLoading = loading, yOffset = 64.dp)
|
||||
CircularLoadingBar(isLoading = loading)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LargeProgressBar(progress: Float) {
|
||||
ProgressBarPreference(object : ProgressBarPreferenceModel {
|
||||
override val title = "Large Progress Bar"
|
||||
override val progress = progress
|
||||
override val height = 20f
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SimpleProgressBar() {
|
||||
ProgressBarPreference(object : ProgressBarPreferenceModel {
|
||||
override val title = "Simple Progress Bar"
|
||||
override val progress = 0.2f
|
||||
override val icon = Icons.Outlined.SystemUpdate
|
||||
})
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ProgressBarWithData() {
|
||||
ProgressBarWithDataPreference(model = object : ProgressBarPreferenceModel {
|
||||
override val title = "Progress Bar with Data"
|
||||
override val progress = 0.2f
|
||||
override val icon = Icons.Outlined.Delete
|
||||
}, data = "25G")
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun ProgressBarPagePreview() {
|
||||
SettingsTheme {
|
||||
ProgressBarPageProvider.Page(null)
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ internal fun BaseLayout(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BaseIcon(
|
||||
internal fun BaseIcon(
|
||||
icon: @Composable (() -> Unit)?,
|
||||
modifier: Modifier,
|
||||
paddingStart: Dp,
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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.preference
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.widget.ui.LinearProgressBar
|
||||
import com.android.settingslib.spa.widget.ui.SettingsTitle
|
||||
|
||||
/**
|
||||
* The widget model for [ProgressBarPreference] widget.
|
||||
*/
|
||||
interface ProgressBarPreferenceModel {
|
||||
/**
|
||||
* The title of this [ProgressBarPreference].
|
||||
*/
|
||||
val title: String
|
||||
|
||||
/**
|
||||
* The progress fraction of the ProgressBar. Should be float in range [0f, 1f]
|
||||
*/
|
||||
val progress: Float
|
||||
|
||||
/**
|
||||
* The icon image for [ProgressBarPreference]. If not specified, hides the icon by default.
|
||||
*/
|
||||
val icon: ImageVector?
|
||||
get() = null
|
||||
|
||||
/**
|
||||
* The height of the ProgressBar.
|
||||
*/
|
||||
val height: Float
|
||||
get() = 4f
|
||||
|
||||
/**
|
||||
* Indicates whether to use rounded corner for the progress bars.
|
||||
*/
|
||||
val roundedCorner: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Progress bar preference widget.
|
||||
*
|
||||
* Data is provided through [ProgressBarPreferenceModel].
|
||||
*/
|
||||
@Composable
|
||||
fun ProgressBarPreference(model: ProgressBarPreferenceModel) {
|
||||
ProgressBarPreference(
|
||||
title = model.title,
|
||||
progress = model.progress,
|
||||
icon = model.icon,
|
||||
height = model.height,
|
||||
roundedCorner = model.roundedCorner,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Progress bar with data preference widget.
|
||||
*/
|
||||
@Composable
|
||||
fun ProgressBarWithDataPreference(model: ProgressBarPreferenceModel, data: String) {
|
||||
val icon = model.icon
|
||||
ProgressBarWithDataPreference(
|
||||
title = model.title,
|
||||
data = data,
|
||||
progress = model.progress,
|
||||
icon = if (icon != null) ({
|
||||
Icon(imageVector = icon, contentDescription = null)
|
||||
}) else null,
|
||||
height = model.height,
|
||||
roundedCorner = model.roundedCorner,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun ProgressBarPreference(
|
||||
title: String,
|
||||
progress: Float,
|
||||
icon: ImageVector? = null,
|
||||
height: Float = 4f,
|
||||
roundedCorner: Boolean = true,
|
||||
) {
|
||||
BaseLayout(
|
||||
title = title,
|
||||
subTitle = {
|
||||
LinearProgressBar(progress, height, roundedCorner)
|
||||
},
|
||||
icon = if (icon != null) ({
|
||||
Icon(imageVector = icon, contentDescription = null)
|
||||
}) else null,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
internal fun ProgressBarWithDataPreference(
|
||||
title: String,
|
||||
data: String,
|
||||
progress: Float,
|
||||
icon: (@Composable () -> Unit)? = null,
|
||||
height: Float = 4f,
|
||||
roundedCorner: Boolean = true,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(end = SettingsDimension.itemPaddingEnd),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
BaseIcon(icon, Modifier, SettingsDimension.itemPaddingStart)
|
||||
TitleWithData(
|
||||
title = title,
|
||||
data = data,
|
||||
subTitle = {
|
||||
LinearProgressBar(progress, height, roundedCorner)
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(vertical = SettingsDimension.itemPaddingVertical),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TitleWithData(
|
||||
title: String,
|
||||
data: String,
|
||||
subTitle: @Composable () -> Unit,
|
||||
modifier: Modifier
|
||||
) {
|
||||
Column(modifier) {
|
||||
Row {
|
||||
Box(modifier = Modifier.weight(1f)) {
|
||||
SettingsTitle(title)
|
||||
}
|
||||
Text(
|
||||
text = data,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
}
|
||||
subTitle()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.foundation.layout.absoluteOffset
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Indeterminate linear progress bar. Expresses an unspecified wait time.
|
||||
*/
|
||||
@Composable
|
||||
fun LinearLoadingBar(
|
||||
isLoading: Boolean,
|
||||
xOffset: Dp = 0.dp,
|
||||
yOffset: Dp = 0.dp
|
||||
) {
|
||||
if (isLoading) {
|
||||
LinearProgressIndicator(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.absoluteOffset(xOffset, yOffset)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indeterminate circular progress bar. Expresses an unspecified wait time.
|
||||
*/
|
||||
@Composable
|
||||
fun CircularLoadingBar(isLoading: Boolean) {
|
||||
if (isLoading) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.Canvas
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.progressSemantics
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.CornerRadius
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.DrawScope
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
/**
|
||||
* Determinate linear progress bar. Displays the current progress of the whole process.
|
||||
*
|
||||
* Rounded corner is supported and enabled by default.
|
||||
*/
|
||||
@Composable
|
||||
fun LinearProgressBar(
|
||||
progress: Float,
|
||||
height: Float = 4f,
|
||||
roundedCorner: Boolean = true
|
||||
) {
|
||||
Box(modifier = Modifier.padding(top = 8.dp, bottom = 8.dp)) {
|
||||
val color = MaterialTheme.colorScheme.onSurface
|
||||
val trackColor = MaterialTheme.colorScheme.surfaceVariant
|
||||
Canvas(
|
||||
Modifier
|
||||
.progressSemantics(progress)
|
||||
.fillMaxWidth()
|
||||
.height(height.dp)
|
||||
) {
|
||||
drawLinearBarTrack(trackColor, roundedCorner)
|
||||
drawLinearBar(progress, color, roundedCorner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun DrawScope.drawLinearBar(
|
||||
endFraction: Float,
|
||||
color: Color,
|
||||
roundedCorner: Boolean
|
||||
) {
|
||||
val width = endFraction * size.width
|
||||
drawRoundRect(
|
||||
color = color,
|
||||
size = Size(width, size.height),
|
||||
cornerRadius = if (roundedCorner) CornerRadius(
|
||||
size.height / 2,
|
||||
size.height / 2
|
||||
) else CornerRadius.Zero,
|
||||
)
|
||||
}
|
||||
|
||||
private fun DrawScope.drawLinearBarTrack(
|
||||
color: Color,
|
||||
roundedCorner: Boolean
|
||||
) = drawLinearBar(1f, color, roundedCorner)
|
||||
|
||||
/**
|
||||
* Determinate circular progress bar. Displays the current progress of the whole process.
|
||||
*
|
||||
* Displayed in default material3 style, and rounded corner is not supported.
|
||||
*/
|
||||
@Composable
|
||||
fun CircularProgressBar(progress: Float, radius: Float = 40f) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(
|
||||
progress = progress,
|
||||
modifier = Modifier.size(radius.dp, radius.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.preference
|
||||
|
||||
import androidx.compose.ui.semantics.ProgressBarRangeInfo
|
||||
import androidx.compose.ui.semantics.SemanticsProperties.ProgressBarRangeInfo
|
||||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ProgressBarPreferenceTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun title_displayed() {
|
||||
composeTestRule.setContent {
|
||||
ProgressBarPreference(object : ProgressBarPreferenceModel {
|
||||
override val title = "Title"
|
||||
override val progress = 0.2f
|
||||
})
|
||||
}
|
||||
composeTestRule.onNodeWithText("Title").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun data_displayed() {
|
||||
composeTestRule.setContent {
|
||||
ProgressBarWithDataPreference(model = object : ProgressBarPreferenceModel {
|
||||
override val title = "Title"
|
||||
override val progress = 0.2f
|
||||
}, data = "Data")
|
||||
}
|
||||
composeTestRule.onNodeWithText("Title").assertIsDisplayed()
|
||||
composeTestRule.onNodeWithText("Data").assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun progressBar_displayed() {
|
||||
composeTestRule.setContent {
|
||||
ProgressBarPreference(object : ProgressBarPreferenceModel {
|
||||
override val title = "Title"
|
||||
override val progress = 0.2f
|
||||
})
|
||||
}
|
||||
|
||||
fun progressEqualsTo(progress: Float): SemanticsMatcher =
|
||||
SemanticsMatcher.expectValue(
|
||||
ProgressBarRangeInfo,
|
||||
ProgressBarRangeInfo(progress, 0f..1f, 0)
|
||||
)
|
||||
composeTestRule.onNode(progressEqualsTo(0.2f)).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user