类似textView中的hint属性功能(我这边所使用的是material3的依赖库)
库:androidx.compose.material3
1.在material中在Modifier中实现placeholder函数并实现Text(value=str)来实现。
Modifier
.placeholder {
Text(
text = "in hint"
)
}
2.在material3中已经封装到OutlinedTextField里面作为@Compose参数了,以下是使用方法
@Composable
fun TextField(str:String) {
OutlinedTextField(
value = str,
onValueChange = { },
placeholder = {
Text(
text =stringResource(R.string.login_input_hint_user_pwd),
color = Color.Gray,
fontSize = labelTextSize
)
},
)
}
3.左边增加图标,这里两个函数都可以实现,leadingIcon和prefix,这两个函数所增加的icon都是在内容的前面。但两个函数有所区别,我所理解的区别在于图标所处的位置。
leadingIcon,与内容有一定的pading效果
leadingIcon = {
Image(imageVector = Icons.Default.Phone,
contentDescription = "IS PHOME")
}
prefix,与内容中间没有pading效果。
需要使用到OutlinedTextField中的prefix函数。
prefix = {
Image(imageVector = Icons.Default.Phone,
contentDescription = "IS PHOME")
},
4.右边增加图标,需要使用到trailingIcon此函数实现
trailingIcon = {
Image(imageVector = Icons.Default.Phone,
contentDescription = "IS PHOME")
}
注意:placeholder函数有个问题,当实现hint时,当获取输入焦点时才会显示,否则是不显示。
这里需要注意下。因为我在实现过程中未获取焦点时就不显示,才会自定义实现hint效果。
以下是效果:
当然还有自定义实现hint效果,请看代码:
新增了4个参数:isHint,hint,hintPadding,contentAlignment等属性。
isHint是否需要显示,默认为false。以内容是否为空作为条件,当为空时才会显示hint内容;
hint是@Compose组合函数,按照自己需要添加;
hintPadding,hint与文本之间的间距调整;
contentAlignment,上下左右的居中属性;可根据需要自行调整
/**
* 自定义输入框,增加hint 属性。hint为 @Compose()组合函数
* @param value String 内容
* @param onValueChange Function1<String, Unit>
* @param modifier Modifier
* @param isHint Boolean 需要根据输入框内容判断是否显示hint [value.isNullOrBlank()] true则显示,false则不显示
* @param hint [@androidx.compose.runtime.Composable] Function0<Unit>
* @param hintPadding PaddingValues 内容区域与icon或者左边[hint]的padding间距
* @param contentAlignment Alignment 内容区域的居中
* @param enabled Boolean
* @param readOnly Boolean
* @param textStyle TextStyle
* @param label [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param placeholder [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param leadingIcon [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param trailingIcon [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param prefix [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param suffix [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param supportingText [@androidx.compose.runtime.Composable] Function0<Unit>?
* @param isError Boolean
* @param visualTransformation VisualTransformation
* @param keyboardOptions KeyboardOptions
* @param keyboardActions KeyboardActions
* @param singleLine Boolean
* @param maxLines Int
* @param minLines Int
* @param interactionSource MutableInteractionSource
* @param shape Shape
* @param colors TextFieldColors
*/
@Composable
fun CustomOutlinedTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
isHint:Boolean = false,
hint: @Composable () -> Unit = {},
hintPadding: PaddingValues = PaddingValues(20.dp, 0.dp,0.dp, 0.dp),
contentAlignment: Alignment = Alignment.CenterStart,
enabled: Boolean = true,
readOnly: Boolean = false,
textStyle: TextStyle = LocalTextStyle.current,
label: @Composable (() -> Unit)? = null,
placeholder: @Composable (() -> Unit)? = null,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
prefix: @Composable (() -> Unit)? = null,
suffix: @Composable (() -> Unit)? = null,
supportingText: @Composable (() -> Unit)? = null,
isError: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
minLines: Int = 1,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = OutlinedTextFieldDefaults.shape,
colors: TextFieldColors = OutlinedTextFieldDefaults.colors()
) {
BasicTextField(
modifier = modifier,
value = value,
onValueChange = onValueChange,
decorationBox = {
Box(modifier = modifier,contentAlignment = contentAlignment) {
// 添加自定义的提示
if (isHint) {
Box(modifier = modifier.padding(hintPadding)
,contentAlignment = contentAlignment){
hint()
}
}
// 原生的输入框
OutlinedTextField(
value,
onValueChange = onValueChange,
modifier,
enabled,
readOnly,
textStyle,
label,
placeholder,
leadingIcon,
trailingIcon,
prefix,
suffix,
supportingText,
isError,
visualTransformation,
keyboardOptions,
keyboardActions,
singleLine,
maxLines,
minLines,
interactionSource,
shape,
colors
)
}
}
)
}
使用方法:
CustomOutlinedTextField(
value = password,
onValueChange = { password = it },
hintPadding = PaddingValues(40.dp, 0.dp, 0.dp, 0.dp),
isHint = password.isNullOrBlank(),
hint = {
Text(
text =stringResource(R.string.login_input_hint_user_pwd),
color = Color.Gray,
fontSize = labelTextSize
)
},
placeholder = {
Text(
text =stringResource(R.string.login_input_hint_user_pwd),
color = Color.Gray,
fontSize = labelTextSize
)
},
prefix = {
Image(imageVector = Icons.Default.Lock,
contentDescription = "IS LOCK")
},
textStyle = outlinedTextFieldTextSize,
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier
.fillMaxWidth(),
colors = getTextFieldColors(),
singleLine = true,
)
接下来请看完整代码:
private val spacedColumnVerticalArrangement = Arrangement.spacedBy(16.dp)
private val boxPadding = 16.dp
private val imageSize = 100.dp
private val textFontSize = 24.sp
private val outlinedTextFieldTextSize = TextStyle(fontStyle = FontStyle(18))
private val labelTextSize = TextUnit(18f, TextUnitType.Sp)
private val shapeRoundedButton = RoundedCornerShape(8.dp)
private const val initialTime = 10
//这个是边框的颜色
@Composable
fun getTextFieldColors():TextFieldColors {
return TextFieldDefaults.colors(
focusedTextColor = Color.Black,
unfocusedTextColor = Color.Black,
focusedIndicatorColor = Color.Red,
unfocusedIndicatorColor = Color.Red,
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent
)
}
@Composable
fun LoginPage(modifier: Modifier, activity: ComponentActivity) {
//输入法管理类
val keyboardController = LocalSoftwareKeyboardController.current
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var isToLogin by remember { mutableStateOf(false) }
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
Column(
modifier = modifier
.align(Alignment.Center)
.padding(boxPadding),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = spacedColumnVerticalArrangement
) {
Image(
painter = painterResource(id = androidx.core.R.drawable.ic_call_answer),
contentDescription = "App Logo",
modifier = Modifier.size(imageSize)
)
Text(
text = "Welcome Back!",
fontSize = textFontSize,
fontWeight = FontWeight.Bold,
color = Color.Black
)
OutlinedTextField(
value = username,
modifier = Modifier.fillMaxWidth(),
onValueChange = { username = it },
placeholder = {
Text(
text = stringResource(R.string.login_input_hint_user_name),
color = Color.Gray,
fontSize = labelTextSize
)
},
//左边图标,与文本之间有padding
// leadingIcon = {
// Image(imageVector = Icons.Default.Phone,
// contentDescription = "IS PHOME")
// },
//左边图标,与文本之间无padding效果
suffix = {
Image(imageVector = Icons.Default.Phone,
contentDescription = "IS PHOME")
},
//右边图标
// trailingIcon = {
// Image(imageVector = Icons.Default.Phone,
// contentDescription = "IS PHOME")
// },
textStyle = outlinedTextFieldTextSize,
singleLine = true,
colors = getTextFieldColors(),
)
CustomOutlinedTextField(
value = password,
onValueChange = { password = it },
hintPadding = PaddingValues(40.dp, 0.dp, 0.dp, 0.dp),
isHint = password.isNullOrBlank(),
hint = {
Text(
text =stringResource(R.string.login_input_hint_user_pwd),
color = Color.Gray,
fontSize = labelTextSize
)
},
placeholder = {
Text(
text =stringResource(R.string.login_input_hint_user_pwd),
color = Color.Gray,
fontSize = labelTextSize
)
},
prefix = {
Image(imageVector = Icons.Default.Lock,
contentDescription = "IS LOCK")
},
textStyle = outlinedTextFieldTextSize,
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier
.fillMaxWidth(),
colors = getTextFieldColors(),
singleLine = true,
)
Spacer(modifier = Modifier.height(60.dp))
Button(
onClick = {
isToLogin = true
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
shape = shapeRoundedButton
) {
Text(text = "Login", fontSize = labelTextSize, color = Color.White)
}
}
if (isToLogin) {
keyboardController?.hide()
Box(
modifier = Modifier
.fillMaxSize()
.background(transparentBackgroundModifier)
) {
username = ""
password = ""
}
}
}
}