กำหนดค่าช่องข้อความ

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

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

ฟีเจอร์

ฟิลด์ข้อความตามค่า

ช่องข้อความตามรัฐ

สิทธิประโยชน์ตามรัฐ

การจัดการสถานะ

อัปเดตสถานะช่องข้อความด้วยแฮนเดิล onValueChange คุณมีหน้าที่รับผิดชอบในการอัปเดต value ในรัฐของคุณเองตามการเปลี่ยนแปลงที่ onValueChange รายงาน

ใช้TextFieldStateออบเจ็กต์อย่างชัดแจ้งเพื่อจัดการสถานะการป้อนข้อความ (ค่า การเลือก การเขียน) ระบบจะจดจำและแชร์สถานะนี้ได้

  • เราได้นำonValueChange Callback ออกแล้ว ซึ่งจะช่วยป้องกันไม่ให้คุณนำลักษณะการทำงานแบบไม่พร้อมกันมาใช้
  • สถานะจะยังคงอยู่หลังจากการประกอบใหม่ การกำหนดค่า และการสิ้นสุดกระบวนการ

การเปลี่ยนรูปแบบภาพ

ใช้ VisualTransformation เพื่อแก้ไขลักษณะที่ข้อความที่แสดงปรากฏ ซึ่งโดยทั่วไปจะจัดการทั้งการจัดรูปแบบอินพุตและเอาต์พุตในขั้นตอนเดียว

ใช้ InputTransformation เพื่อแก้ไขอินพุตของผู้ใช้ก่อนที่จะคอมมิตไปยังสถานะ และ OutputTransformation เพื่อจัดรูปแบบเนื้อหาของช่องข้อความโดยไม่เปลี่ยนข้อมูลสถานะพื้นฐาน

  • คุณไม่จำเป็นต้องระบุการแมปออฟเซ็ตระหว่างข้อความดิบต้นฉบับกับข้อความที่แปลงแล้วด้วย OutputTransformation อีกต่อไป

ขีดจำกัดของบรรทัด

ยอมรับ singleLine: Boolean, maxLines: Int และ minLines: Int เพื่อควบคุมจำนวนบรรทัด

ใช้ lineLimits: TextFieldLineLimits เพื่อกำหนดค่าจำนวนบรรทัดขั้นต่ำและสูงสุดที่ฟิลด์ข้อความใช้ได้

  • ขจัดความคลุมเครือเมื่อกำหนดค่าขีดจำกัดบรรทัดโดยระบุlineLimitsพารามิเตอร์ประเภท TextFieldLineLimits

ช่องข้อความที่ปลอดภัย

ไม่มี

SecureTextField เป็นคอมโพสเซเบิลที่สร้างขึ้นบนฟิลด์ข้อความตามสถานะสำหรับเขียนฟิลด์รหัสผ่าน

  • ช่วยให้คุณเพิ่มประสิทธิภาพเพื่อความปลอดภัยภายใต้การทำงาน และมาพร้อมกับ UI ที่กำหนดไว้ล่วงหน้าด้วย textObfuscationMode

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

เลือกการติดตั้งใช้งาน TextField

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

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

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

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

OutlinedTextField(
    state = rememberTextFieldState(),
    label = { Text("Label") }
)

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

รูปแบบ TextField

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

  • textStyle
  • lineLimits

TextField(
    state = rememberTextFieldState("Hello\nWorld\nInvisible"),
    lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
    placeholder = { Text("") },
    textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
    label = { Text("Enter text") },
    modifier = Modifier.padding(20.dp)
)

TextField หลายบรรทัดที่มี 2 บรรทัดที่แก้ไขได้และป้ายกำกับ

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

จัดรูปแบบอินพุตด้วย Brush API

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

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

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

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

val brush = remember {
    Brush.linearGradient(
        colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
    )
}
TextField(
    state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
)

ใช้ buildAnnotatedString และ SpanStyle ร่วมกับ linearGradient เพื่อปรับแต่งเฉพาะบางส่วนของข้อความ
รูปที่ 1 เอฟเฟกต์ไล่ระดับสีรุ้งสำหรับเนื้อหา TextField

จัดการสถานะช่องข้อความ

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

  • initialText: เนื้อหาของ TextField
  • initialSelection: ระบุตำแหน่งปัจจุบันของเคอร์เซอร์หรือส่วนที่เลือก

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

คุณใช้ TextFieldState() เพื่อยกระดับสถานะใน TextField ได้ เราขอแนะนำให้ใช้ฟังก์ชัน rememberTextFieldState() สำหรับการดำเนินการนี้ rememberTextFieldState() จะสร้างอินสแตนซ์ TextFieldState ใน Composable, ตรวจสอบว่าระบบจดจำออบเจ็กต์สถานะ และมีฟังก์ชันการบันทึก และกู้คืนในตัว

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

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

TextField(
    state = rememberTextFieldState(initialText = "Username"),
    lineLimits = TextFieldLineLimits.SingleLine,
)

TextField ที่มีข้อความ "ชื่อผู้ใช้" ปรากฏในช่องข้อความ
รูปที่ 2 TextField โดยมี "ชื่อผู้ใช้" เป็นข้อความเริ่มต้น

แก้ไขข้อความด้วย TextFieldBuffer

TextFieldBuffer ทำหน้าที่เป็นคอนเทนเนอร์ข้อความที่แก้ไขได้ ซึ่งมีฟังก์ชันคล้ายกับ StringBuilder โดยจะเก็บทั้งเนื้อหาข้อความและข้อมูลเกี่ยวกับการเลือกปัจจุบัน

คุณมักจะเห็น TextFieldBuffer เป็นขอบเขตตัวรับในฟังก์ชันต่างๆ เช่น TextFieldState.edit, InputTransformation.transformInput หรือ OutputTransformation.transformOutput ในฟังก์ชันเหล่านี้ คุณสามารถอ่านหรือ อัปเดต TextFieldBuffer ได้ตามต้องการ หลังจากนั้น การเปลี่ยนแปลงเหล่านี้จะได้รับการ คอมมิตไปยัง TextFieldState หรือส่งต่อไปยังไปป์ไลน์การแสดงผลในกรณีของ OutputTransformation

คุณสามารถใช้ฟังก์ชันการแก้ไขมาตรฐาน เช่น append, insert, replace หรือ delete เพื่อแก้ไขเนื้อหาของบัฟเฟอร์ หากต้องการเปลี่ยนสถานะการเลือก ให้ตั้งค่าตัวแปร selection: TextRange โดยตรง หรือใช้ฟังก์ชันยูทิลิตี เช่น placeCursorAtEnd หรือ selectAll การเลือกเองจะแสดงด้วย TextRange โดยดัชนีเริ่มต้นจะรวมอยู่ด้วยและดัชนีสิ้นสุดจะไม่รวมอยู่ด้วย TextRange ที่มีค่าเริ่มต้นและค่าสิ้นสุดเหมือนกัน เช่น (3, 3) หมายถึง ตำแหน่งเคอร์เซอร์ที่ไม่มีการเลือกอักขระในขณะนี้

val phoneNumberState = rememberTextFieldState()

LaunchedEffect(phoneNumberState) {
    phoneNumberState.edit { // TextFieldBuffer scope
        append("123456789")
    }
}

TextField(
    state = phoneNumberState,
    inputTransformation = InputTransformation { // TextFieldBuffer scope
        if (asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    },
    outputTransformation = OutputTransformation {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
)

แก้ไขข้อความใน TextFieldState

คุณแก้ไขสถานะได้โดยตรงผ่านตัวแปรสถานะด้วยวิธีต่างๆ ดังนี้

  • edit: ให้คุณแก้ไขเนื้อหาสถานะและให้ฟังก์ชัน TextFieldBuffer เพื่อให้คุณใช้วิธีการต่างๆ เช่น insert, replace, append และอื่นๆ ได้

    val usernameState = rememberTextFieldState("I love Android")
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    usernameState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    usernameState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: ล้างข้อความปัจจุบัน แทนที่ด้วยข้อความที่ ระบุ และตั้งค่าเคอร์เซอร์ไว้ที่ท้ายข้อความ

    usernameState.setTextAndPlaceCursorAtEnd("I really love Android")
    // textFieldState.text : I really love Android
    // textFieldState.selection : TextRange(21, 21)

  • clearText: ล้างข้อความทั้งหมด

    usernameState.clearText()
    // textFieldState.text :
    // textFieldState.selection : TextRange(0, 0)

สำหรับฟังก์ชันอื่นๆ ของ TextFieldState โปรดดูTextFieldState ข้อมูลอ้างอิง

แก้ไขข้อมูลจากผู้ใช้

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

กรองอินพุตของผู้ใช้ด้วยการเปลี่ยนรูปแบบอินพุต

การแปลงอินพุตช่วยให้คุณกรองอินพุตจากผู้ใช้ได้ เช่น หากTextFieldรับหมายเลขโทรศัพท์ของอเมริกา คุณต้องการยอมรับเฉพาะหมายเลข 10 หลัก ระบบจะบันทึกผลลัพธ์ของ InputTransformation ไว้ใน TextFieldState

มีตัวกรองในตัวสำหรับInputTransformationกรณีการใช้งานทั่วไป หากต้องการจำกัด ความยาว ให้โทร InputTransformation.maxLength()

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine,
    inputTransformation = InputTransformation.maxLength(10)
)

การเปลี่ยนรูปแบบอินพุตที่กำหนดเอง

InputTransformation เป็นอินเทอร์เฟซฟังก์ชันเดียว เมื่อติดตั้งใช้งาน InputTransformationที่กำหนดเอง คุณต้องลบล้าง TextFieldBuffer.transformInput

class CustomInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
    }
}

สำหรับหมายเลขโทรศัพท์ ให้เพิ่มการเปลี่ยนรูปแบบอินพุตที่กำหนดเองซึ่งอนุญาตให้ป้อนได้เฉพาะตัวเลข ใน TextField ดังนี้

class DigitOnlyInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
        if (!TextUtils.isDigitsOnly(asCharSequence())) {
            revertAllChanges()
        }
    }
}

การเปลี่ยนรูปแบบอินพุตของเชน

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

TextField(
    state = rememberTextFieldState(),
    inputTransformation = InputTransformation.maxLength(6)
        .then(CustomInputTransformation()),
)

หลังจากเพิ่มการเปลี่ยนรูปแบบอินพุตแล้ว อินพุต TextField จะยอมรับตัวเลขได้สูงสุด 10 หลัก

จัดรูปแบบอินพุตก่อนแสดง

OutputTransformation ช่วยให้คุณจัดรูปแบบข้อมูลที่ผู้ใช้ป้อนก่อนที่จะแสดงบน หน้าจอ การจัดรูปแบบที่ทำผ่าน OutputTransformation จะไม่ได้รับการบันทึกใน TextFieldState ซึ่งต่างจาก InputTransformation จากตัวอย่างหมายเลขโทรศัพท์ก่อนหน้า คุณต้องเพิ่มวงเล็บและขีดคั่นในตำแหน่งที่เหมาะสม ดังนี้

หมายเลขโทรศัพท์ของอเมริกาที่มีรูปแบบถูกต้องโดยใช้วงเล็บ ขีดกลาง และดัชนีที่เกี่ยวข้อง
รูปที่ 3 หมายเลขโทรศัพท์ของอเมริกาที่มีการจัดรูปแบบที่เหมาะสมและดัชนีที่เกี่ยวข้อง

นี่คือวิธีที่อัปเดตแล้วในการจัดการ VisualTransformation ใน TextField ที่อิงตามมูลค่า โดยความแตกต่างที่สำคัญคือคุณไม่จำเป็นต้องคำนวณการแมปออฟเซ็ต

OutputTransformation เป็นอินเทอร์เฟซเมธอดแบบนามธรรมเดียว หากต้องการใช้ OutputTransformation ที่กำหนดเอง คุณต้องลบล้างเมธอด transformOutput ดังนี้

class CustomOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
    }
}

หากต้องการจัดรูปแบบหมายเลขโทรศัพท์ ให้เพิ่มวงเล็บเปิดที่ดัชนี 0 วงเล็บปิดที่ดัชนี 4 และขีดกลางที่ดัชนี 8 ใน OutputTransformation ดังนี้

class PhoneNumberOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
}

จากนั้นเพิ่ม OutputTransformation ลงใน TextField โดยทำดังนี้

TextField(
    state = rememberTextFieldState(),
    outputTransformation = PhoneNumberOutputTransformation()
)

วิธีการทำงานร่วมกันของการเปลี่ยนรูปแบบ

แผนภาพต่อไปนี้แสดงขั้นตอนตั้งแต่การป้อนข้อความไปจนถึงการเปลี่ยนรูปแบบและเอาต์พุต

ภาพการป้อนข้อความที่ผ่านการแปลงก่อนที่จะกลายเป็นเอาต์พุตข้อความ
รูปที่ 4 แผนภาพแสดงวิธีที่อินพุตข้อความผ่านการแปลงก่อนที่จะกลายเป็นเอาต์พุตข้อความ
  1. ได้รับอินพุตจากแหล่งที่มาของอินพุต
  2. ระบบจะกรองข้อมูลที่ป้อนผ่าน InputTransformation ซึ่งจะบันทึกไว้ใน TextFieldState
  3. ระบบจะส่งอินพุตผ่าน OutputTransformation เพื่อจัดรูปแบบ
  4. โดยอินพุตจะแสดงใน TextField

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

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

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

แหล่งข้อมูลเพิ่มเติม