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

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

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

การติดตั้งใช้งาน TextField มี 2 ระดับ ได้แก่

  1. TextField คือการใช้งาน Material Design เราขอแนะนําให้คุณเลือกใช้การติดตั้งใช้งานนี้เนื่องจากเป็นไปตามหลักเกณฑ์ของ Material Design
  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)
    )
}

TextField แบบหลายบรรทัดที่มี 2 บรรทัดซึ่งแก้ไขได้พร้อมป้ายกำกับ

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

อินพุตสไตล์ด้วย 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)
)

การใช้ buildAnnotatedString และ 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 นําหน้า ให้นํา 0 นําหน้าออกทั้งหมดเมื่อค่ามีการเปลี่ยนแปลง

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

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

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

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

  • ใช้ 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 นั้นถูกต้อง หากไม่มี คุณสามารถใช้คอมโพสิเบิลหรือคลาสตัวเก็บสถานะเป็นแหล่งข้อมูล ดูข้อมูลเพิ่มเติมเกี่ยวกับตําแหน่งที่จะยกสถานะได้ในส่วนเอกสารประกอบการยกสถานะ