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

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

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

ฟีเจอร์

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ไม่มี

SecureTextField เป็น Composable ที่สร้างขึ้นบนช่องข้อความแบบอิงตามสถานะสำหรับเขียนช่องรหัสผ่าน

  • ช่วยให้คุณเพิ่มประสิทธิภาพเพื่อความปลอดภัยภายใต้การทำงาน และมาพร้อมกับ 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 การเลือกเองจะแสดงด้วย a 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กรณีการใช้งานที่พบบ่อย หากต้องการจำกัด ความยาว ให้โทรหา 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()
        }
    }
}

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

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

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