单击 OutlinedTextField 时如何在 Compose 中自动显示软键盘

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

我正在将基于 Kotlin 视图的应用程序转换为 JetPack Compose。 第一个要转换的是登录屏幕。 它有许多 OutlinedTextFields。 当用户单击其中一个字段时,我希望显示适当的软键盘。

我已将键盘类型编码为

keyboardType = KeyboardType.Text,  
keyboardType = KeyboardType.Email, 
keyboardType = KeyboardType.Phone,
keyboardType = KeyboardType.Password 

以上唯一自动显示软键盘的是Password。 所有其他的都在菜单中显示幻灯片,允许用户请求软键盘。 请参阅附图。

这里有一些屏幕截图可以提供帮助。

当我点击密码字段时,我想要的键盘显示如下:

Password Keyboard

这是我收到的菜单中的幻灯片。

Slide in menu enter image description here

这是当前的撰写屏幕代码。

enter code here
    
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun RegisterUserProfileScreen(registerUserProfileViewModel: RegisterUserProfileViewModel = viewModel(), navController: NavController) {
    val _uiState = MutableStateFlow(
        RegisterUserProfileUiState(
            registerUserProfileErrorMessage = "",
            primaryUserSelected = true,
            familyAdminSelected = false,
            registerUserProfileLastName = "",
            registerUserProfileFirstName = "",
            registerUserProfileMobilePhone = "",
            registerUserProfileEmailAddress = "",
            registerUserProfilePassword = "",
            registerUserProfileConfirmPassword = "",
            shouldShowAlertDialog = false,
            alertDialogTitle = " ",
            alertDialogMessage = " ",
            alertDialogType = " ",
            shouldShowIdentityVerificationDialog = false,
            identityVerificationTextCode = 0,
            identityVerificationEmailCode = 0,
            identityVerificationErrorMessage = " ",
            identityVerificationResponseReceived = false,
            mSendingActivity = " ",
            isConnected = false
        )
    )
    val registerUserProfileUiState by registerUserProfileViewModel.uiState.collectAsState()
    var showPassword by remember { mutableStateOf(value = false) }
    var shouldShowIdentityVerificationDialog = remember { mutableStateOf(false) }
    var primaryUserSelectedIn: Boolean = true
    var familyAdminSelectedIn: Boolean = false
    val myContext = LocalContext.current
    var registerUserProfilePassword2: String
    var verificationErrorMessage: String = " "
    val focusManager = LocalFocusManager.current
    val coroutineScope = CoroutineScope(Dispatchers.Main)

    LaunchedEffect(Unit) {
        registerUserProfileViewModel.initializeServices(myContext)
    }
    Log.i(" ", "RegisterUserProfileScreen: shouldShowIdentityVerificationDialog ${registerUserProfileViewModel.shouldShowIdentityVerificationDialog}")
  if (registerUserProfileViewModel.shouldShowIdentityVerificationDialog) {
        IdentityVerificationDialog(
            onDismiss = { /*TODO*/ },
            onExit = {
                _uiState.value.identityVerificationResponseReceived = true
                val mAnswer1 = _uiState.value.identityVerificationTextCode
                val mAnswer2 = _uiState.value.identityVerificationEmailCode
                val twoFactorTextResponse = mAnswer1
                val twoFactorEmailResponse = mAnswer2
                if (twoFactorTextResponse != registerUserProfileViewModel.randomNumberText) {
                    verificationErrorMessage =
                        "Incorrect answer to phone text security code"
                    registerUserProfileViewModel.responseCorrect = false
                } else if (twoFactorEmailResponse != registerUserProfileViewModel.randomNumberEmail) {
                    verificationErrorMessage =
                        "Incorrect answer to email security code"
                    registerUserProfileViewModel.responseCorrect = false
                } else {
                    registerUserProfileViewModel.responseCorrect = true
                }
                if (!registerUserProfileViewModel.responseCorrect) {
                    _uiState.update { currentState ->
                        currentState.copy(
                            alertDialogTitle = "Identity Verification",
                            alertDialogMessage = "A text has been sent to the mobile number you provided and an email " +
                                    "has been sent to the email you entered.  Please get the codes and enter below. ",
                            alertDialogType = " ",
                            identityVerificationErrorMessage = verificationErrorMessage,
                            shouldShowIdentityVerificationDialog = true,
                            identityVerificationResponseReceived = false,
                        )
                    }
                }
                    else {
                        registerUserProfileViewModel.responseCorrect = true
                        registerUserProfileViewModel.completeUserProfileRegistration()
                        _uiState.update { currentState ->
                            currentState.copy(
                                identityVerificationErrorMessage = " ",
                                shouldShowIdentityVerificationDialog = false,
                                identityVerificationResponseReceived = false,
                            )
                        }
                    }
              },
            registerUserProfileViewModel = registerUserProfileViewModel,
            shouldShowIdentityVerificationDialog = registerUserProfileViewModel.shouldShowIdentityVerificationDialog
        )
    }
        Column(
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier = Modifier
                .fillMaxSize()
                .padding(horizontal = 10.dp)
        ) {
            val (a, b, c, d, e, f) = FocusRequester.createRefs()
            Spacer(modifier = Modifier.height(120.dp))

            //Header text instructions
            Text(
                text = "Please enter your user profile information",
                fontSize = 18.sp,
                color = Color.Blue,

            )

            Spacer(modifier = Modifier.height(1.dp))

            var commentsAlpha: Float = 0f
            if ((registerUserProfileUiState.registerUserProfileErrorMessage != " ") &&
                (registerUserProfileUiState.registerUserProfileErrorMessage != ""))
                {
                    commentsAlpha = 1f
                }



            //Error message text
            var registerUserProfileErrorMessage by remember {
                mutableStateOf(
                    TextFieldValue(
                        ""
                    )
                )
            }
            TextField(
                value = registerUserProfileErrorMessage,
                onValueChange = { newErrorMessage  ->
                    registerUserProfileErrorMessage = newErrorMessage
                },
                modifier = Modifier
                    .height(20.dp)
                    .focusTarget()
                    .alpha(commentsAlpha),

            )

            Spacer(modifier = Modifier.height(1.dp))

            val radioOptions = listOf("Primary User", "Family Admin")
            var (selectedOption, onOptionSelected) = remember { mutableStateOf(radioOptions[0]) }

            Row(Modifier.selectableGroup()) {
                radioOptions.forEach { text ->
                    Column(
                        Modifier//.fillMaxWidth()
                            .height(76.dp)

                            .selectable(
                                selected = (text == selectedOption),
                                onClick = { onOptionSelected(text) },
                                role = Role.RadioButton
                            )
                            .padding(horizontal = 16.dp),
                        horizontalAlignment = Alignment.CenterHorizontally
                     ) {
                        RadioButton(
                            selected = (text == selectedOption),
                            onClick = { if (text == "Primary User") {
                                  selectedOption = "Primary User"
                                  onOptionSelected(selectedOption)
                                  primaryUserSelectedIn = true
                                  familyAdminSelectedIn = false
                                }
                                else {
                                  selectedOption = "Family Admin"
                                  onOptionSelected(selectedOption)
                                  primaryUserSelectedIn = false
                                  familyAdminSelectedIn = true
                                }
                            }
                        )
                        Text(
                            text = text,
                            style = MaterialTheme.typography.bodyLarge,
                            modifier = Modifier
                                .focusTarget()
                                .padding(start = 16.dp)
                        )
                    }
                }
            }

            Spacer(modifier = Modifier.height(10.dp))

            Column(

                modifier = Modifier
                    .fillMaxSize()
                    .padding(vertical = 10.dp),
                Arrangement.Center,
                Alignment.CenterHorizontally
            ) {

                //Last Name
                var registerUserProfileLastName by remember {mutableStateOf(TextFieldValue(""))
                }
                OutlinedTextField(
                    value = registerUserProfileLastName,
                    label = { Text("Last Name") },
                    enabled = true,
                    onValueChange = {
                        registerUserProfileLastName = it
                        registerUserProfileViewModel.registerUserProfileLastName =
                            registerUserProfileLastName.toString()
                        registerUserProfileViewModel.registerUserProfileLastNameIn =
                            registerUserProfileLastName.toString()
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .focusTarget()
                        .focusRequester(a)
                        .focusProperties {
                            next = b
                        }
                        .padding(10.dp),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = Blue,
                        unfocusedBorderColor = Blue),
                    keyboardOptions = KeyboardOptions.Default.copy(
                        keyboardType = KeyboardType.Text,
                        showKeyboardOnFocus = true,
                        imeAction = ImeAction.Next
                    ),
                    keyboardActions = KeyboardActions(
                        onNext = {
                            focusManager.moveFocus(FocusDirection.Down)
                        }
                    ),
                    singleLine = true,
                )

                //First Name
                var registerUserProfileFirstName by remember {mutableStateOf(TextFieldValue(""))
                }
                OutlinedTextField(
                    value = registerUserProfileFirstName,
                    label = { Text(text = "First Name") },
                    onValueChange = {
                        registerUserProfileFirstName = it
                        registerUserProfileViewModel.registerUserProfileFirstName =
                            registerUserProfileFirstName.toString()
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .focusable(true)
                        .focusRequester(b)
                        .focusProperties {
                            next = c
                            previous = a
                        }
                        .padding(10.dp),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = Blue,
                        unfocusedBorderColor = Blue),
                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Text,
                        showKeyboardOnFocus = true,
                        imeAction = ImeAction.Next
                    ),
                    keyboardActions = KeyboardActions(
                        onNext = {
                            focusManager.moveFocus(FocusDirection.Down)
                        }
                    ),
                    singleLine = true,
                )

                Spacer(modifier = Modifier.width(4.dp))

                //Mobile Phone
                var registerUserProfileMobilePhone by remember {mutableStateOf(TextFieldValue(""))
                }
                OutlinedTextField(
                    value = registerUserProfileMobilePhone,
                    label = { Text(text = "Mobile Phone Number") },
                    onValueChange = {
                        registerUserProfileMobilePhone = it
                        registerUserProfileViewModel.registerUserProfileMobilePhone =
                            registerUserProfileMobilePhone.toString()
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .focusTarget()
                        .focusRequester(c)
                        .focusProperties {
                            next = d
                            previous = b
                        }
                        .padding(10.dp),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = Blue,
                        unfocusedBorderColor = Blue),
                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Phone,
                        showKeyboardOnFocus = true,
                        imeAction = ImeAction.Next
                    ),
                    keyboardActions = KeyboardActions(
                        onNext = {
                            focusManager.moveFocus(FocusDirection.Down)
                        }
                    ),
                    singleLine = true,
                    visualTransformation = NanpVisualTransformation(),
                    )

                Spacer(modifier = Modifier.width(4.dp))

                //Email address
                var registerUserProfileEmailAddress by remember { mutableStateOf(TextFieldValue("")) }
                OutlinedTextField(
                    value = registerUserProfileEmailAddress,
                    label = { Text(text = "Email Address") },
                    onValueChange = {
                        registerUserProfileEmailAddress = it
                        registerUserProfileViewModel.registerUserProfileEmailAddress =
                            registerUserProfileEmailAddress.toString()
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .focusTarget()
                        .focusRequester(d)
                        .focusProperties {
                            next = e
                            previous = c
                        }
                        .padding(10.dp),
                    colors = OutlinedTextFieldDefaults.colors(

                            focusedBorderColor = Blue,
                            unfocusedBorderColor = Blue),
                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Email,
                        autoCorrect = false,
                        showKeyboardOnFocus = true,
                        imeAction = ImeAction.Next),
                    keyboardActions = KeyboardActions(
                            onNext = {
                            focusManager.moveFocus(FocusDirection.Down)
                        }
                ),
                )

                Spacer(modifier = Modifier.width(4.dp))

                //Password
                var registerUserProfilePassword by remember { mutableStateOf(TextFieldValue("")) }

                OutlinedTextField(
                    value = registerUserProfilePassword,
                    onValueChange = {
                        registerUserProfilePassword = it
                        registerUserProfileViewModel.registerUserProfilePassword =
                            registerUserProfilePassword.toString()
                    },
                    label = { Text(text = "Password") },
                    trailingIcon = {
                        if (showPassword) {
                            IconButton(onClick = { showPassword = false }) {
                                Icon(
                                    imageVector = Icons.Filled.Visibility,
                                    contentDescription = "hide_password"
                                )
                            }
                        } else {
                            IconButton(
                                onClick = { showPassword = true }) {
                                Icon(
                                    imageVector = Icons.Filled.VisibilityOff,
                                    contentDescription = "hide_password"
                                )
                            }
                        }
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .focusTarget()
                        .focusRequester(e)
                        .focusProperties {
                            next = f
                            previous = d
                        }
                        .padding(10.dp),
                    visualTransformation = if (showPassword) {
                        VisualTransformation.None
                    } else {
                        PasswordVisualTransformation()
                    },

                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Password,
                        showKeyboardOnFocus = true,
                        imeAction = ImeAction.Next),
                    keyboardActions = KeyboardActions(
                        onNext = {
                            focusManager.moveFocus(FocusDirection.Down)
                           // focusManager.moveFocus(FocusDirection.Next)
                        }
                    ),
                    singleLine = true,
                    shape = RoundedCornerShape(percent = 20),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = Blue,
                        unfocusedBorderColor = Blue)
                )

                Spacer(modifier = Modifier.width(4.dp))

                //Confirm Password
                var registerUserProfileConfirmPassword by remember { mutableStateOf(TextFieldValue(""))}

                OutlinedTextField(value = registerUserProfileConfirmPassword,
                    onValueChange = {
                        registerUserProfileConfirmPassword = it
                     registerUserProfileViewModel.registerUserProfileConfirmPassword =
                            registerUserProfileConfirmPassword.toString()
                    },
                    label = { Text(text = "Confirm Password") },
                    trailingIcon = {
                        if (showPassword) {
                            IconButton(onClick = { showPassword = false }) {
                                Icon(
                                    imageVector = Icons.Filled.Visibility,
                                    contentDescription = "hide_password"
                                )
                            }
                        } else {
                            IconButton(
                                onClick = { showPassword = true }) {
                                Icon(
                                    imageVector = Icons.Filled.VisibilityOff,
                                    contentDescription = "hide_password"
                                )
                            }
                        }
                    },
                    modifier = Modifier
                        .fillMaxWidth()
                        .focusTarget()
                        .focusRequester(f)
                        .focusProperties {
                            previous = e
                        }
                        .padding(10.dp),
                    visualTransformation = if (showPassword) {
                        VisualTransformation.None
                    } else {
                        PasswordVisualTransformation()
                    },

                    keyboardOptions = KeyboardOptions(
                        keyboardType = KeyboardType.Password,
                        showKeyboardOnFocus = true,
                        imeAction = ImeAction.Next),
                    keyboardActions = KeyboardActions(
                        onNext = {
                            focusManager.moveFocus(FocusDirection.Down)
                        }
                    ),
                    singleLine = true,
                    shape = RoundedCornerShape(percent = 20),
                    colors = OutlinedTextFieldDefaults.colors(
                        focusedBorderColor = Blue,
                        unfocusedBorderColor = Blue)

                )

                Spacer(modifier = Modifier.width(4.dp))

                //Button - Next
                Button(
                    onClick = {
                        _uiState.update { currentState ->
                            currentState.copy(
                                primaryUserSelected = primaryUserSelectedIn,
                                familyAdminSelected = familyAdminSelectedIn,
                                registerUserProfileLastName = registerUserProfileLastName.text,
                                registerUserProfileFirstName = registerUserProfileFirstName.text,
                                registerUserProfileMobilePhone = registerUserProfileMobilePhone.text,
                                registerUserProfileEmailAddress = registerUserProfileEmailAddress.text,
                                registerUserProfilePassword = registerUserProfilePassword.text,
                                registerUserProfileConfirmPassword = registerUserProfileConfirmPassword.text
                            )
                        }
                        Log.i(" ", "RegisterUserProfileScreen: lastname = ${_uiState.value.registerUserProfileLastName}")
                        coroutineScope.launch {
                        registerUserProfileViewModel.registerUserNextButtonOnClickListener(
                                uiState = _uiState)}
                              },

                    colors = ButtonDefaults.buttonColors(containerColor = Color.Blue),
                    shape = RoundedCornerShape(8.dp),
                    modifier = Modifier
                        .padding(8.dp)
                        .width(120.dp)
                        .height(40.dp)
                ) {
                    Text("Next")
                }

                Spacer(modifier = Modifier.width(4.dp))

                //Fragment - Adview
                AdmobBanner(modifier = Modifier.fillMaxWidth())
            }
        }

}

@Preview (
    showSystemUi = true,
)
@PreviewScreenSizes
@Composable
fun RegisterUserProfilePreview() {
    PeepsConnectionTheme {
    }
}
android android-jetpack-compose kotlin-multiplatform
1个回答
0
投票

有趣的问题。

抱歉,如果我偏离主题,但在这种情况下,您不应该在单个可组合项中编写整个屏幕代码 RegisterUserProfileScreen。如果发生重组,将会非常昂贵且令人疲惫不堪。

您可以将其分解为单一的模块化可组合方法。我已经实现了相同的功能,可以给你基本的片段。

以下只是一个基本要点,您可以根据自己的需要进行修改。

例如:-

EmailInput (emailState = email, enabled = !loading, onAction = KeyboardActions {
            passwordFocusRequest.requestFocus()
        }

你可以将此函数放在组件文件中,它会像:-

@Composable fun EmailInput(
modifier: Modifier = Modifier,
emailState: MutableState<String>,
labelId: String = "Email",
enabled: Boolean = true,
imeAction: ImeAction = ImeAction.Next,
onAction: KeyboardActions = KeyboardActions.Default) {
InputField(
    modifier = modifier,
    valueState = emailState,
    labelId = labelId,
    enabled = enabled,
    keyboardType = KeyboardType.Email,
    imeAction = imeAction,
    onAction = onAction
)}

输入字段就像:-

@Composable fun InputField(
modifier: Modifier = Modifier,
valueState: MutableState<String>,
labelId: String,
enabled: Boolean,
isSingleLine: Boolean = true,
keyboardType: KeyboardType = KeyboardType.Text,
imeAction: ImeAction = ImeAction.Next,
onAction: KeyboardActions = KeyboardActions.Default) { OutlinedTextField(
    value = valueState.value,
    onValueChange = { valueState.value = it },
    label = { Text(text = labelId) },
    singleLine = isSingleLine,
    textStyle = TextStyle(
        fontSize = 18.sp, color = MaterialTheme.colorScheme.onBackground
    ),
    modifier = modifier
        .padding(bottom = 10.dp, start = 10.dp, end = 10.dp)
        .fillMaxWidth(),
    enabled = enabled,
    keyboardOptions = KeyboardOptions(
        keyboardType = keyboardType, imeAction = imeAction,
    ),
    keyboardActions = onAction
)}
© www.soinside.com 2019 - 2024. All rights reserved.