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

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

ข้อความที่พิมพ์ในช่องข้อความซึ่งแสดงเอฟเฟกต์การไล่ระดับสีรุ้ง
รูปที่ 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("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

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