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

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

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

ฟีเจอร์

ช่องข้อความตามมูลค่า

ช่องข้อความตามสถานะ

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

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

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

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

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

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

ใช้ 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
  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 เมื่อการออกแบบต้องใช้วัสดุ 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 ในคอมโพสิเบิล ตรวจสอบว่าระบบจดจำออบเจ็กต์สถานะ และให้บริการบันทึกและกู้คืนในตัว

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

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