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

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 Design ดังนี้
    • การจัดรูปแบบเริ่มต้นคือเติม
    • 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)
)

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

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

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

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

สิ่งที่ทำให้ TextFieldState แตกต่างจากแนวทางอื่นๆ เช่น การเรียกกลับ onValueChange คือ 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("1234567890")

TextField(
    state = phoneNumberState,
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Phone
    ),
    inputTransformation = InputTransformation.maxLength(10).then {
        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 และอื่นๆ ได้

    // Initial textFieldState text passed in is "I love Android"
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    textFieldState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    textFieldState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    textFieldState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

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

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

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

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

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

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

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

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

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

มีตัวกรองในตัวสำหรับInputTransformation Use Case ที่พบบ่อย หากต้องการจำกัด ความยาว ให้โทรหา 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 (!asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    }
}

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

หากต้องการเพิ่มตัวกรองหลายรายการในข้อความที่ป้อน ให้เชื่อมต่อ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

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