จัดการข้อมูลจากผู้ใช้

TextField อนุญาตให้ผู้ใช้ป้อนและแก้ไขข้อความ หน้านี้อธิบายวิธีการ สามารถใช้อินพุต TextField, รูปแบบ TextField และกำหนดค่า ตัวเลือกอื่นๆ ของ TextField เช่น ตัวเลือกแป้นพิมพ์และการเปลี่ยนรูปแบบ ข้อมูลจากผู้ใช้

เลือกการใช้งาน TextField

การใช้งาน TextField มี 2 ระดับดังนี้

  1. TextField คือการใช้ดีไซน์ Material เราขอแนะนำให้เลือก การใช้งานนี้ที่เป็นไปตามดีไซน์ Material หลักเกณฑ์ต่อไปนี้
  2. BasicTextField ช่วยให้ผู้ใช้แก้ไขข้อความผ่านฮาร์ดแวร์หรือซอฟต์แวร์ได้ แป้นพิมพ์ แต่ไม่มีการตกแต่ง เช่น คำแนะนำหรือตัวยึดตำแหน่ง

@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

ช่องข้อความที่แก้ไขได้ที่มีคำว่า

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

ช่องข้อความที่แก้ไขได้ มีเส้นขอบสีม่วงและป้ายกำกับ

รูปแบบ TextField

TextField และ BasicTextField ใช้พารามิเตอร์ทั่วไปหลายรายการร่วมกันเพื่อปรับแต่ง ให้พวกเขา รายการทั้งหมดสำหรับ TextField มีอยู่ในแหล่งข้อมูล TextField นี่เป็นรายการบางส่วนของพารามิเตอร์ที่มีประโยชน์โดยสังเขป:

  • singleLine
  • maxLines
  • textStyle

@Composable
fun StyledTextField() {
    var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }

    TextField(
        value = value,
        onValueChange = { value = it },
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(20.dp)
    )
}

ฟิลด์ข้อความหลายบรรทัดซึ่งมีบรรทัดที่แก้ไขได้ 2 บรรทัดและป้ายกำกับ

เราขอแนะนำให้ TextField เกิน BasicTextField เมื่อการออกแบบของคุณต้องการ เนื้อหา TextField หรือ OutlineTextField แต่ควรใช้ BasicTextField เมื่อสร้างการออกแบบที่ไม่จำเป็นต้องมีการตกแต่งตามข้อมูลจำเพาะของ Material

ป้อนข้อมูลสไตล์ด้วย Brush API

คุณใช้ Brush API เพื่อจัดสไตล์ขั้นสูงขึ้นใน TextField ได้ ส่วนต่อไปนี้จะอธิบายวิธีใช้แปรงเพื่อเพิ่มการไล่ระดับสี ไปยังอินพุต TextField

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้ Brush API เพื่อจัดรูปแบบข้อความ โปรดดู เปิดใช้การจัดรูปแบบขั้นสูงด้วย Brush API

ใช้การไล่ระดับสีโดยใช้ TextStyle

หากต้องการใช้การไล่ระดับสีขณะที่คุณพิมพ์ภายใน TextField ให้ตั้งค่าแปรง ที่เลือกเป็น TextStyle สำหรับ TextField ของคุณ ในตัวอย่างนี้ เราใช้ แปรงในตัวพร้อม linearGradient เพื่อดูเอฟเฟกต์การไล่ระดับสีรุ้ง พิมพ์ข้อความลงใน TextField

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

วันที่ ใช้ createAnnotatedString และ SpanStyle ร่วมกับ LinearGradient เพื่อปรับแต่งข้อความเท่านั้น
รูปที่ 3 ใช้ buildAnnotatedString และ SpanStyle ร่วมกับ linearGradient เพื่อปรับแต่งข้อความเพียงบางส่วน

ตั้งค่าตัวเลือกแป้นพิมพ์

TextField ให้คุณตั้งค่าตัวเลือกการกำหนดค่าแป้นพิมพ์ เช่น แป้นพิมพ์ หรือเปิดการแก้ไขอัตโนมัติ หากแป้นพิมพ์รองรับ ใช้บ้าง อาจไม่รับประกันตัวเลือก หากซอฟต์แวร์แป้นพิมพ์ไม่เป็นไปตาม ที่ระบุไว้ที่นี่ รายการแป้นพิมพ์ที่รองรับมีดังนี้ ดังต่อไปนี้

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

จัดรูปแบบอินพุต

TextField อนุญาตให้คุณตั้งค่า VisualTransformation กับค่าที่ป้อน เช่น การแทนที่อักขระด้วย * สำหรับรหัสผ่าน หรือ ใส่เครื่องหมายขีดกลางทุกๆ 4 หลักสำหรับหมายเลขบัตรเครดิต:

@Composable
fun PasswordTextField() {
    var password by rememberSaveable { mutableStateOf("") }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}

ช่องป้อนข้อความสำหรับรหัสผ่านที่มีข้อความมาสก์อยู่

ดูตัวอย่างเพิ่มเติมได้ในซอร์สโค้ด VisualTransformationSamples

ล้างอินพุต

งานทั่วไปเมื่อแก้ไขข้อความคือ นำอักขระนำหน้าออก เปลี่ยนสตริงอินพุตทุกครั้งที่มีการเปลี่ยนแปลง

ตัวอย่างเช่น คุณควรคิดว่าแป้นพิมพ์อาจมีขนาดที่กำหนดเอง แก้ไข onValueChange แต่ละรายการ เหตุการณ์นี้อาจเกิดขึ้นได้ เช่น หากผู้ใช้เลือกใช้ การแก้ไขอัตโนมัติ แทนที่คำด้วยอีโมจิ หรือฟีเจอร์การแก้ไขอัจฉริยะอื่นๆ ถึง จัดการเรื่องนี้ได้อย่างถูกต้อง เขียนตรรกะการเปลี่ยนแปลง โดยมีสมมติฐานที่ว่า ข้อความปัจจุบันที่ส่งไปยัง onValueChange ไม่เกี่ยวข้องกับข้อความก่อนหน้าหรือข้อความถัดไป ค่าที่จะส่งไปยัง onValueChange

หากต้องการใช้ช่องข้อความซึ่งไม่อนุญาตให้ใช้ 0 นำหน้า คุณสามารถทำได้โดย ตัดเลขศูนย์นำหน้าทั้งหมดในทุกการเปลี่ยนแปลงค่า

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

หากต้องการควบคุมตำแหน่งเคอร์เซอร์ขณะทำความสะอาดข้อความ ให้ใช้ TextFieldValue TextField มากเกินไป ในฐานะส่วนหนึ่งของรัฐ

แนวทางปฏิบัติแนะนำเกี่ยวกับรัฐ

ต่อไปนี้เป็นชุดแนวทางปฏิบัติแนะนำในการกำหนดและอัปเดต TextField เพื่อป้องกันปัญหาอินพุตในแอปของคุณ

  • ใช้ MutableState เพื่อแสดงสถานะ TextField: หลีกเลี่ยง โดยใช้สตรีมเชิงรับ เช่น StateFlow เพื่อนำเสนอ TextField เนื่องจากโครงสร้างเหล่านี้อาจทำให้เกิดความล่าช้าไม่พร้อมกัน

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • หลีกเลี่ยงความล่าช้าในการอัปเดตสถานะ: โปรดอัปเดตเมื่อโทรหา onValueChange TextField แบบพร้อมกันและทันที:

// SignUpViewModel.kt

class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {

    var username by mutableStateOf("")
        private set

    fun updateUsername(input: String) {
        username = input
    }
}

// SignUpScreen.kt

@Composable
fun SignUpScreen(/*...*/) {

    OutlinedTextField(
        value = viewModel.username,
        onValueChange = { username -> viewModel.updateUsername(username) }
        /*...*/
    )
}

  • ความหมายของรัฐ: หากรัฐTextFieldกำหนดให้มีธุรกิจ ตรวจสอบเชิงตรรกะได้ขณะพิมพ์ การคงสถานะเป็น ViewModel หากไม่ คุณสามารถใช้ Composables หรือคลาสตัวยึดตำแหน่งเป็น มีแหล่งข้อมูลที่ถูกต้อง หากต้องการเรียนรู้เพิ่มเติมว่าจะสร้างรัฐขึ้นมาจากที่ไหน โปรดดู การรอของรัฐ