如何使用 Compose 和 Kotlin 为手机和平板电脑打造响应式 UI

问题描述 投票:0回答:3

我有一个案例,比如在两个方向(纵向和横向)的移动设备和平板电脑上使用单个 Compose UI,我有一个为移动设备开发的简单登录设计,但我也需要它在平板电脑上工作,但我由于我在专注于移动设备时在每个视图中添加了修改器,因此视图被隐藏了,现在我需要知道如何在具有相同设计的移动设备和平板电脑中使用Single Compose UI观看无任何影响

@Composable
fun TestLogin(
) {

val userNameFieldValue = remember { mutableStateOf("") }
val passwordFieldValue = remember { mutableStateOf("") }
val passwordVisibility = remember { mutableStateOf(false) }
val isLoginError = remember { mutableStateOf(false) }
val isInternetError = remember { mutableStateOf(false) }
val configuration = LocalConfiguration.current

Box(
    Modifier
        .fillMaxSize()
        .background(color = colorResource(id = R.color.white)),
    contentAlignment = Alignment.Center) {
    Card(
        shape = RoundedCornerShape(20.dp),
        modifier = Modifier
            .padding(start = 10.dp, end = 10.dp)
    ) {
        Column(
            modifier = Modifier
                .padding(start = 16.dp, end = 16.dp, bottom = 10.dp, top = 10.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center,
        ) {

            Icon(
                painter = painterResource(id = R.drawable.ic_launcher_background),
                tint = Color.Unspecified,
                contentDescription = "success",
                modifier = Modifier
                    .align(Alignment.CenterHorizontally)
            )
            Text(
                text = "Welcome to the App \n Hi There",
                fontWeight = FontWeight.ExtraBold,
                fontSize = 32.sp,
                color = colorResource(R.color.black),
                modifier = Modifier
                    .padding(bottom = 24.dp)
                    .fillMaxWidth(),
                textAlign = TextAlign.Center
            )
            Text(
                text = "Login",
                fontWeight = FontWeight.Bold,
                fontSize = 22.sp,
                color = colorResource(R.color.black),
                modifier = Modifier
                    .padding(top = 50.dp, bottom = 24.dp)
                    .fillMaxWidth(),
                textAlign = TextAlign.Center
            )
            OutlinedTextField(
                modifier = Modifier
                    .padding(bottom = 40.dp)
                    .fillMaxWidth(),
                value = userNameFieldValue.value,
                textStyle = TextStyle(
                    fontSize = 16.sp,
                    fontWeight = FontWeight.Normal
                ),
                singleLine = true,
                onValueChange = {
                    isLoginError.value = false
                    userNameFieldValue.value = it
                },
                keyboardOptions = KeyboardOptions(
                    imeAction = ImeAction.Next
                ),
                enabled = true,
                label = { Text(text = "username") },
                colors = TextFieldDefaults.outlinedTextFieldColors(
                    focusedBorderColor = colorResource(id = R.color.black),
                    unfocusedBorderColor = colorResource(id = R.color.black),
                    cursorColor = colorResource(id = R.color.black)
                )

            )
            OutlinedTextField(
                modifier = Modifier
                    .padding(bottom = 32.dp)
                    .fillMaxWidth(),
                value = passwordFieldValue.value,
                textStyle = TextStyle(
                    fontSize = 16.sp,
                    fontWeight = FontWeight.Normal
                ),
                enabled = true,
                singleLine = true,
                onValueChange = {
                    isLoginError.value = false
                    passwordFieldValue.value = it
                },
                label = { Text(text = "password") },
                visualTransformation = if (passwordVisibility.value) {
                    VisualTransformation.None
                } else {
                    PasswordVisualTransformation()
                },
                keyboardOptions = KeyboardOptions(
                    keyboardType = KeyboardType.Password
                ),
                colors = TextFieldDefaults.outlinedTextFieldColors(
                    focusedBorderColor = colorResource(id = R.color.black),
                    unfocusedBorderColor = colorResource(id = R.color.black),
                    cursorColor = colorResource(id = R.color.black)
                )
            )
            Row(
                Modifier
                    .background(
                        colorResource(
                            id = getLoginButtonColor(
                                userNameFieldValue,
                                passwordFieldValue,
                                isInternetError
                            )
                        ),
                        RoundedCornerShape(5.dp)
                    )
                    .align(Alignment.CenterHorizontally)
                    .fillMaxWidth()
                    .padding(15.dp)
                    .clickable(
                        enabled = userNameFieldValue.value.isNotEmpty() && passwordFieldValue.value.isNotEmpty() && !isInternetError.value,
                        onClick = {}
                    ),
                content = {
                        CircularProgressIndicator(
                            modifier = Modifier
                                .padding(end = 10.dp)
                                .size(20.dp)
                                .align(Alignment.CenterVertically),
                            color = colorResource(id = R.color.white),
                            strokeWidth = 3.dp
                        )
                    Text(
                        "Login",
                        fontWeight = FontWeight.Medium,
                        fontSize = 14.sp,
                        textAlign = TextAlign.Center,
                        color = colorResource(id = getLoginButtonTextColor(userNameFieldValue, passwordFieldValue, isInternetError)))
                },
                horizontalArrangement = Arrangement.Center
            )
            Text(
                text = "Forgot Password",
                fontWeight = FontWeight.ExtraBold,
                color = colorResource(id = R.color.black),
                modifier = Modifier
                    .padding(top = 28.dp),
                textAlign = TextAlign.Center
            )
            Text(
                text = "Not a User ",
                fontWeight = FontWeight.ExtraBold,
                color = colorResource(id = R.color.black),
                modifier = Modifier
                    .padding(top = 24.dp)
                    .clickable { },
                textAlign = TextAlign.Center
            )
        }
    }
}
}


fun getLoginButtonColor(
    userNameFieldValue: MutableState<String>,
    passwordFieldValue: MutableState<String>,
    isInternetError: MutableState<Boolean>
): Int {
    return if(!isInternetError.value && userNameFieldValue.value.isNotEmpty() && passwordFieldValue.value.isNotEmpty()) R.color.black else R.color.purple_200
}

fun getLoginButtonTextColor(
    userNameFieldValue: MutableState<String>,
    passwordFieldValue: MutableState<String>,
    isInternetError: MutableState<Boolean>
): Int {
    return if(!isInternetError.value && userNameFieldValue.value.isNotEmpty() && passwordFieldValue.value.isNotEmpty()) R.color.white else R.color.white
}

@Preview
@Composable
fun previewView() {
    TestLogin()
}

以上代码是针对移动设备的代码,从图中可以看出 当在平板电脑中看到时,视图隐藏

android kotlin responsive-design android-jetpack-compose android-orientation
3个回答
0
投票

只需在父视图上添加verticalScroll

示例:

只需修改你的父母

Box()
:

Box(
    Modifier
        .fillMaxSize()
        .background(color = colorResource(id = R.color.white))
        .verticalScroll(rememberScrollState()),
    contentAlignment = Alignment.Center) {
    // Content
}

0
投票

您问题的答案由两部分组成。

  • 支持不同手机屏幕:

为了支持不同的手机屏幕,请避免使用静态/硬编码的

DP
值作为可组合项的尺寸,并使用以下命令切换到相对尺寸 修饰符,例如
fillMaxSize()
fillMaxHeight()
fillMaxWidth()
weight()
widthIn()
。并至少在两部具有不同屏幕尺寸的不同手机上测试您拥有的每个屏幕。

  • 支持不同设备手机/平板电脑/可折叠设备/电脑:

对于这个主题,有一个完整的文档以获得最佳用户体验,因为对于您的示例,即使整个视图适合您的平板电脑,它对用户来说看起来也不太好(拉伸)。

提示:如果您不关心平板电脑的用户体验,那么只需使用第一种方法


0
投票

您的问题有两种解决方案。您要么使列可滚动(简单但丑陋),要么您可以检查窗口大小类别并相应地调整您的布局。检查窗口大小是否相当简单,并且根据大小,您可以调整填充,甚至使用完全不同的 UI/可组合项。

setContent {
     val windowSizeClass = calculateWindowSizeClass(this)
     MyApp(windowSizeClass)
}
when (windowSizeClass.heightSizeClass) {
        WindowWidthSizeClass.Compact -> ...
        WindowWidthSizeClass.Medium -> ...
        else -> ...
    }

[(无耻的自我推销:))顺便说一句,我最近做了一次关于如何支持所有外形规格的演讲。该视频于昨天发布,可以在这里找到。]

© www.soinside.com 2019 - 2024. All rights reserved.