Basic API Introduction

@composable fun TextField(value: TextFieldValue,// To display TextField onValueChange: (TextFieldValue) -> Unit,// Monitor text changes modifier: Enabled: Boolean = true,// whether to use readOnly: Boolean = false,// whether to readOnly textStyle: TextStyle = LocalTextStyle. Current, / / text format label: @ Composable (() - > Unit)? Placeholder: @composable (() -> Unit)? = null,// placeholder, display leadingIcon when input is null: @composable (() -> Unit)? = null,// the left-most icon trailingIcon: @composable (() -> Unit)? = null,// isError: Boolean = false,// Whether the current input is incorrect VisualTransformation = VisualTransformation. None, / / specified input type, similar inputType keyboardOptions: KeyboardOptions = KeyboardOptions. Default, / / custom keyboard key keyboardActions: SingleLine: Boolean = false,// display singleLine maxLines: Int = Int.MAX_VALUE,// Maximum number of lines MutableInteractionSource = remember {MutableInteractionSource()}, Shape = MaterialTheme. Shapes. Small. Copy (bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), / / define text box background colors: TextFieldColors = TextFieldDefaults. TextFieldColors () / / text and cursor color)Copy the code

Basic usage

In daily development, text input box is often used; A search icon is displayed on the left and a clear text icon is displayed on the right. If the text field is not entered, the hint keyword is displayed.

Compose compose compose compose compose compose compose compose compose

@Composable fun ShowTextField(context: Var text by remember {mutableStateOf("")} TextField(value = text, OnValueChange = {text = it}, // monitor text changes, Text label = {text (text = "Input")}, // Set label leadingIcon = @composable {// Set left icon Image(imageVector = Icons.Filled.Search, contentDescription = "search", Clickable {// Use the modifier to set the click event toaster. MakeText (context, "search $text", Toast.length_short).show()})}, trailingIcon = @composable {// Set the right icon Image(imageVector = Icons. ContentDescription = "clear", modifier = modifier. Clickable {text = ""}) Placeholder = @composable {Text(Text = "This is placeholder")},//hint hint visualTransformation = PasswordVisualTransformation (), / / show the ciphertext keyboardOptions = keyboardOptions (imeAction = imeAction. Search), / / custom enter Search operation OnSearch = {toasts. MakeText (context, "search $text", Toast.LENGTH_SHORT ).show() }), Shape = RoundedCornerShape 16. (dp), / / set the text box with rounded corners colors. = TextFieldDefaults textFieldColors (focusedIndicatorColor = Transparent,// unfocusedIndicatorColor = color. Green,// No focus, errorIndicatorColor = color. Red,// Error, DisabledIndicatorColor = color. Gray,// unavailable, Gray))}Copy the code

The normal textbox for accessing Compose looks something like this:

For Compose, a new UI toolkit, the dynamic effects of Compose are no different from the textboxes implemented by the View-based system. The point is that the amount of code is less. Is there a lot? ! These are the advantages of Compose, which helps developers spend less time on UI and app implementation, putting more of the time saved into their business logic.

Now let’s add a few lines of code to see if we can achieve something even cooler:

isError = true, / / display error message visualTransformation = PasswordVisualTransformation (), / / show the ciphertext keyboardOptions = keyboardOptions (imeAction = Imeaction.search),// Custom enter for Search operations keyboardActions = keyboardActions (// custom Search events onSearch = {toasts. MakeText (context, "search $text", Toast.LENGTH_SHORT ).show()Copy the code

After adding these lines of code, it looks like this:

Compared to the previous effect, the text and the underline of the input box are marked with error red. Can I customize the red color here? Will be answer later, text display into encrypted cryptograph format at the same time, also modified soft keyboard enter into the search button, not only can modify into search, also can complete such as buttons, custom to send, see ImeAction file, there are the following custom button type, you can go to your custom try:

val None: ImeAction = ImeAction(0)
val Default: ImeAction = ImeAction(1)
val Go: ImeAction = ImeAction(2)
val Search: ImeAction = ImeAction(3)
val Send: ImeAction = ImeAction(4)
val Previous: ImeAction = ImeAction(5)
val Next: ImeAction = ImeAction(6)
val Done: ImeAction = ImeAction(7)
Copy the code

What about if you have a need to set an input box with rounded corners, and it’s really easy, you don’t have to set a selector, you just need one line of code to do it:

Shape = RoundedCornerShape(16.dp),// Sets the text box's rounded cornersCopy the code

What if I only need to achieve a half-rounded corner effect, which is also one line of code:

Shape = RoundedCornerShape(16.dp,16.dp,0.dp,0.dp),// Sets the text box's rounded cornersCopy the code

You can see why it sets rounded corners by looking at the RoundedCornerShape source code

fun RoundedCornerShape( topStart: Dp = 0.dp, topEnd: Dp = 0.dp, bottomEnd: Dp = 0.dp, bottomStart: Dp = 0.dp ) ... fun RoundedCornerShape(corner: CornerSize) = RoundedCornerShape(corner, corner, corner, corner) ... Override fun createOutline(size: size, topStart: Float, topEnd: Float, bottomEnd: Float, bottomStart: Float, layoutDirection: LayoutDirection) = if (topStart + topEnd + bottomEnd + bottomStart == 0.0f) { Rectangle(size.torect ())} else {Outline.Rounded(// RoundRect(rect = size.torect (), topLeft = CornerRadius(if (layoutDirection == Ltr) topStart else topEnd), topRight = CornerRadius(if (layoutDirection == Ltr) topEnd else topStart), bottomRight = CornerRadius(if (layoutDirection == Ltr) bottomEnd else bottomStart), bottomLeft = CornerRadius(if (layoutDirection == Ltr) bottomStart else bottomEnd) ) ) }Copy the code

TextField has an argument called colors for developers to customize the colors of each state of the TextField:

Colors = TextFieldDefaults. TextFieldColors (focusedIndicatorColor = Color Transparent, / / a focus Instructions at the bottom of the bar is transparent UnfocusedIndicatorColor = color. Green,// No focus, Green errorIndicatorColor = color. Red,// Error, DisabledIndicatorColor = color. Gray,// unavailable, Gray)Copy the code

We also need to change the isError state so that the text box is not always in an error state:

IsError = false, // Display error messageCopy the code

If the Error state is not changed, the text box will be in the Error state and the underline will always be red; With that done, let’s look at the style of the textbox:

As you can see, underlining is what we specify when we lose focusunfocusedIndicatorColorgreen; Underline is specified when focus is obtained and text is enteredfocusedIndicatorColortransparentColor; As for the color in unavailable state and error state, you can simulate the scene to test;

extension

Outline text field

OutlinedTextField has almost the same API as a regular TextField, but it can also stroke a text box. As the name suggests, an outline text box comes with an outline stroke, making it easy to achieve the look of the product and the UI

Here’s a simple demo:

@Composable fun OutlinedTextFieldDemo() { var text by remember { mutableStateOf("") } OutlinedTextField(value = text, OnValueChange = {Text = it})} onValueChange = {Text = it}Copy the code

The usage is the same as TextField, but the style is different:

BasicTextField

It can be seen that both TextField and OutlinedTextField have helped developers realize most of the dynamic effects and functions of common text fields. However, there are many special scenarios in actual development, and a basic TextField is needed for developers to highly customize the style required for business implementation. You can use BasicTextField to edit text with hardware or soft keyboard. You can customize cursor, border, etc. Since borders are customized, the label property can also be removed from BasicTextField. TextField has some differences between its API and TextField.

@composable Fun BasicTextField(value: String,// Display text onValueChange: (String) -> Unit,// Monitor text changes modifier: Modifier = Modifier,// Modifier, often used to set background, etc. Enabled: Boolean = true,// Whether it is available readOnly: Boolean = false,// Whether it is read-only textStyle: TextStyle = textstyle. Default,// Text format keyboardOptions: KeyboardOptions = KeyboardOptions. Default, / / custom keyboard key keyboardActions: KeyboardActions = KeyboardActions. Default, / / a custom button event singleLine: Boolean = false, / / a single display maxLines: Int = Int.MAX_VALUE,// Maximum row number visualTransformation: VisualTransformation = VisualTransformation. None, / / specified input type, similar inputType onTextLayout: (TextLayoutResult) -> Unit = {},// Listen for layout changes interactionSource: MutableInteractionSource = remember {MutableInteractionSource()}, Brush = SolidColor(color.black); @Composable (innerTextField: @Composable () -> Unit) -> Unit = @Composable { innerTextField -> innerTextField() } )Copy the code

Once we get the API, let’s write a simple demo:

@Composable fun ShowBasicTextField(context: MainActivity) { var input by remember { mutableStateOf("hello") } BasicTextField( value = input, // display text onValueChange = {input = it}, // when the text changes, assign the value to text)}Copy the code

The display effect is as follows:

If I set the initial value to null, I will not even know where the text box is 🤦🏻♀️; It’s really primitive, it’s really Basic, but that’s why it’s possible to highly customize the textfield style. Let’s see how BasicTextField works correctly:

First, give it a background, otherwise you won’t even know where it is:

Modifier = modifier. Background (color.green, RoundedCornerShape(8.dp)),// Set Green background, 8dp rounded corner background, also can use the above method to set half rounded cornerCopy the code

The effect is as follows:

Instead of just adding a background color, let’s draw a text box and add the following code:

DecorationBox = @composable {innerTextField -> Canvas(modifier = modifier. Size (width = 100.dp, // drawCircle(color = color.red, style = Stroke(width = 1F))}Copy the code

Draw the text inside the text box by calling the innerTextField. The result is as follows:

You can draw not only borders and circles, but also ICONS, placeholders, etc. The innerTextField method for drawing text can only be called once:

* @param decorationBox 
* Composable lambda that allows to add decorations around text field, such
* as icon, placeholder, helper messages or similar, and automatically increase the hit target area
* of the text field. To allow you to control the placement of the inner text field relative to your
* decorations, the text field implementation will pass in a framework-controlled composable
* parameter "innerTextField" to the decorationBox lambda you provide. You must call
* innerTextField exactly once.
Copy the code

conclusion

If normal text fields don’t meet your business needs, try BasicTextField, which allows you to customize text field styles.

If a plain TextField is exactly what we want, we can use TextField;

If you want to use a hollow outline text field, use an OutlinedTextField.

TextField and OutlinedTextField one is solid and one is hollow, and the rest of the API is exactly the same; BasicTextField has some differences in API and can be highly customized;