小编Moh*_*mad的帖子

jetpack 中的自动镜像 compose 图标

我现在使用 jetpack compose,我的应用程序有两种语言环境,其中一种是 RTL,另一种是 LTR。
当用户更改区域设置时,一切正常,整个布局将重新排列。

我遇到的唯一问题是 Jetpack Compose 图标的镜像。我有一个像这样的图标按钮:

IconButton(onClick = { backView(true) }) {
    Icon(Icons.Filled.ArrowBack, contentDescription = "back")
}
Run Code Online (Sandbox Code Playgroud)

用于向后导航。
我的问题是,当用户切换到 RTL 语言环境时,该图标不会被镜像。

在 Compose 之前,我导入了arrow_back向量,它有一个用于 RTL 支持的复选框auto mirroring

如何在 Compose 中实现 RTL 支持?

android android-jetpack-compose

12
推荐指数
2
解决办法
4156
查看次数

如何在 Jetpack Compose Canvas 中绘制圆角多边形?

我正在尝试在 Jetpack Compose 中使用创建圆角三角形Canvas

我尝试用这段代码来绘制三角形:

@Composable
fun RoundedTriangle() {
    Canvas(modifier = Modifier.size(500.dp)) {
        val trianglePath = Path().apply {
            val height = size.height
            val width = size.width
            moveTo(width / 2.0f, 0f)
            lineTo(width, height)
            lineTo(0f, height)
        }
            drawPath(trianglePath, color = Color.Blue)
    }
}
Run Code Online (Sandbox Code Playgroud)

但我不知道如何圆化三角形的角。我也尝试过使用arcTo,但无法得到合适的结果。

我怎样才能画出像下图这样的东西?

在此输入图像描述

android canvas rounded-corners kotlin android-jetpack-compose

10
推荐指数
1
解决办法
7192
查看次数

如何绑定ViewModel生命周期来撰写

我现在正在使用 Jetpack Compose。我意识到我可以在可组合项中使用 ViewModel 并在可组合项中初始化视图模型,如下所示:

val myViewModel:MyViewModel = viewModel()
Run Code Online (Sandbox Code Playgroud)

但存在一个问题,即使未显示可组合项,这些视图模型也永远不会被销毁。

例如,我有一个主可组合屏幕,它根据用户交互加载一些其他屏幕,如下所示:

@Composable
fun MainAuthentication(viewModel: MainViewModel) {
    val state = viewModel.state.value
    val scope = rememberCoroutineScope()
    val scaffoldState = rememberScaffoldState()
    Scaffold(scaffoldState = scaffoldState)
    {

        //--------------------(login and sign up button)--------------------//
        Row(
            modifier = Modifier
                .padding(top = 50.dp)
                .fillMaxSize(),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            if (!state.signUpFormIsVisible && !state.loginFormIsVisible) {
                Button(
                    onClick = {
                        viewModel.onEvent(event = MainEvent.LoginButtonClick)
                    },
                    modifier = Modifier
                        .padding(10.dp)
                        .weight(0.5f)
                ) {
                    Text(text = stringResource(id = R.string.login))
                }

                Button(
                    onClick = { …
Run Code Online (Sandbox Code Playgroud)

viewmodel android-lifecycle kotlin android-jetpack-compose

8
推荐指数
1
解决办法
6019
查看次数

使用jetpack compose时在android测试中测试小吃栏

我正在使用 jetpack compose 并使用此代码来显示我的 Snackbar:

 LaunchedEffect(true) {
        viewModel.snackBar.collectLatest { message ->
            scaffoldState.snackbarHostState.currentSnackbarData?.dismiss()
            scaffoldState.snackbarHostState.showSnackbar(message = message)
        }
    }
Run Code Online (Sandbox Code Playgroud)

通常,当我想访问 compose 元素时,我使用testTagin modifier。但 Snackbar 没有。那么我如何测试我的 Snackbar 是否显示特定文本?

我尝试使用:

 composeRule.onNodeWithText(SNACKBAR_MESSAGE).assertIsDisplayed()
Run Code Online (Sandbox Code Playgroud)

但它找不到任何节点。

testing android android-testing android-snackbar android-jetpack-compose

7
推荐指数
1
解决办法
1151
查看次数

如何使用 jetpack 撰写导航注销后将用户重定向到登录页面

我在我的项目中使用 jetpack compose。我的应用程序包含多个屏幕和嵌套导航。所以我的 MainActivity 中有这个:

   val startDestination = if (setting.isUserLoggedIn)
            HomeNavGraph.HomeRoute.route
        else
            AuthenticationNavGraph.AuthenticationRoute.route

        setContent {
            val navController = rememberNavController()
            DoneTheme {
                NavHost(
                    navController = navController,
                    startDestination = startDestination
                ) {
                    authentication(navController = navController)
                    home()
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

此代码根据用户是否已登录来决定将用户导航到身份验证屏幕或主屏幕。首页导航是这样的:

fun NavGraphBuilder.home() {
    navigation(
        startDestination = HomeNavGraph.HomeScreen.route,
        route = HomeNavGraph.HomeRoute.route
    ) {
        composable(route = HomeNavGraph.HomeScreen.route)
        {
            HomeRouteScreen()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

HomeRouteScreen()本身具有底部导航及其 navHost。现在,我想将用户从个人资料屏幕导航到身份HomeRouteScreen()验证屏幕,其可组合项在 MainActivity 导航图中定义。

我的问题是:

如果我调用navcontroller.navigate(AuthenticationNavGraph.AuthenticationScreen.route),我会收到错误消息,表明目的地未明确显示在当前导航图中。另一方面,如果我使用navController主活动中存在的 ,HomeRouteScreen我会收到错误 ViewModelStore should be set before …

android android-navigation android-jetpack-compose

6
推荐指数
1
解决办法
3287
查看次数

将地图存储在房间数据库中

我正在尝试存储Map<String,String>在我的房间数据库中。所以我创建了一个转换器类,如下所示:

class HashMapConverter {

    @TypeConverter
    fun toHashMap(value: JsonElement): Map<String, String> =
        Gson().fromJson(value, object : TypeToken<Map<String, String>>() {}.type)

    @TypeConverter
    fun fromHashMap(value: Map<String, String>): String =
        Gson().toJson(value)


}
Run Code Online (Sandbox Code Playgroud)

并像这样创建了我的数据库类:

@Database(
    entities = [TasksModel::class],
    version = 1, exportSchema = false
)
@TypeConverters( HashMapConverter::class,EnumConverters::class)
abstract class TasksDatabase : RoomDatabase() {
    abstract val tasksDAO: TasksDAO
}
Run Code Online (Sandbox Code Playgroud)

这是我的任务模型:

@Entity(tableName = "Tasks")
data class TasksModel(
    @PrimaryKey
    @ColumnInfo
    val id: Int,

    @ColumnInfo
    val taskName: String,

    @ColumnInfo
    val date: Map<String, String>,

    @ColumnInfo
    val time: String?,

    @ColumnInfo
    val …
Run Code Online (Sandbox Code Playgroud)

android typeconverter kotlin android-room

5
推荐指数
1
解决办法
1315
查看次数

如何使用 jetpack 撰写导航将位图从一个屏幕传递到另一个屏幕

我正在使用jetpack compose。我有两个屏幕,我想将位图从第一个屏幕发送到第二个屏幕。因此,我将位图转换为字符串并将其作为参数传递:


                            composable(
                                route = "${NavGraph.FilterScreen.route}/{screenShot}",
                                arguments = listOf(navArgument("screenShot") {
                                    this.type = NavType.StringType
                                })
                            ) {
                                FilterScreen(
                                    innerPadding = padding,
                                    navController = navController,
                                    screenShot = it.arguments?.getString("screenShot")
                                )
                            }
Run Code Online (Sandbox Code Playgroud)

我从第一个屏幕导航到第二个屏幕,如下所示:

 navController.navigate(NavGraph.FilterScreen.route + "/${bitmapToString(it)}")
Run Code Online (Sandbox Code Playgroud)

问题是:

看来是因为 Bitmap 的字符串版本太长,导航无法处理它并给出以下错误:

cannot be found in the navigation graph NavGraph(0x0) startDestination={Destination(0x78d845ec) route=home}
Run Code Online (Sandbox Code Playgroud)

我这么说是因为当我用包含位图值的字符串替换一个小的随机字符串时,一切都有效。

我也尝试过使用parcellable。但我收到错误,parcellable 不能有默认值,所以我们必须作为字符串传递。我该如何解决这个问题?

android android-jetpack-navigation android-jetpack-compose

5
推荐指数
1
解决办法
1095
查看次数

如何断言 android jetpack 撰写测试中的文本不包含特定字符?

我正在尝试为我的撰写功能编写一些测试用例。我有一个轮廓文本字段,最大值为 16 个字符。所以我想测试一下这个功能。这是测试:

    @Test
    fun checkMaxTaxCodeLength_16Character() {
        val taxCode = composeRule.onNodeWithTag(testTag = AUTHENTICATION_SCREEN_TAX_CODE_EDIT_TEXT)
        for (i in 'A'..'Z')
            taxCode.performTextInput(i.toString())
        taxCode.assertTextEquals("ABCDEFGHIJKLMNOP")
    }
Run Code Online (Sandbox Code Playgroud)

但是,虽然我可以看到输入是正确的,但测试失败,并且似乎assertTextEquals无法正常工作。所以:

  • 首先,我做错了什么?
  • 其次,有没有办法不检查相等性,而检查文本不包含特定字符?

这是文本字段的代码:

                OutlinedTextField(
                    value = state.taxCode,
                    maxLines = 1,
                    onValueChange = { string ->
                        viewModel.onEvent(
                            AuthenticationEvent.TaxCodeChanged(string)
                        )
                    },
                    label = {
                        Text(text = stringResource(id = R.string.tax_code))
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .testTag(TestingConstant.AUTHENTICATION_SCREEN_TAX_CODE_EDIT_TEXT)
                )
Run Code Online (Sandbox Code Playgroud)

最大长度在视图模型中处理。如果用户添加的字符超过 16 个,视图模型将不会更新状态并保留旧值。

testing android android-jetpack-compose android-jetpack-compose-testing

4
推荐指数
1
解决办法
3015
查看次数

在 kotlin 中是字符串不可变的

我正在尝试通过阅读其文档来学习 Kotlin。在文档中有一个关于字符串的部分。在该部分它说:

字符串是不可变的。一旦初始化字符串,就无法更改其值或为其分配新值。所有转换字符串的操作都在一个新的 String 对象中返回其结果,而原始字符串保持不变。

并试图通过一个例子来证明这一点:

fun main() {
    val str = "abcd"
    println(str.uppercase()) // Create and print a new String object
    println(str) // the original string remains the same
}

Run Code Online (Sandbox Code Playgroud)

我对说的部分有问题:

字符串的值在初始化后不能改变。

但是当我更改为时valvar我可以轻松更改字符串的值。

那么文档说字符串的值不能改变是什么意思?我们知道这val使得变量不可变,而不仅仅是字符串。

string kotlin

1
推荐指数
1
解决办法
48
查看次数