แถบค้นหา

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

แถบค้นหา 2 แถบจะแสดงขึ้น ส่วนแบบฟอร์มทางด้านซ้ายมีเฉพาะช่องข้อความ
  แถบค้นหาทางด้านซ้ายมีช่องข้อความและคำค้นหาที่แนะนำอยู่ด้านล่าง
รูปที่ 1 แถบค้นหาพื้นฐาน (1) และแถบค้นหาที่มีคำแนะนำ (2)

พื้นผิว API

ใช้ SearchBar ที่ใช้ร่วมกันได้เพื่อใช้แถบค้นหา พารามิเตอร์หลักสำหรับ Composable นี้มีดังนี้

  • inputField: กำหนดช่องป้อนข้อมูลของแถบค้นหา โดยทั่วไปจะใช้SearchBarDefaults.InputField ซึ่งช่วยให้ปรับแต่งสิ่งต่อไปนี้ได้
    • query: ข้อความค้นหาที่จะแสดงในช่องป้อนข้อมูล
    • onQueryChange: Lambda เพื่อจัดการการเปลี่ยนแปลงในสตริงการค้นหา
  • expanded: บูลีนที่ระบุว่าแถบค้นหาขยายเพื่อแสดงคำแนะนำหรือผลการค้นหาที่กรองแล้วหรือไม่
  • onExpandedChange: Lambda เพื่อจัดการการเปลี่ยนแปลงในสถานะที่ขยายของเมนูแบบเลื่อนลง

  • content: เนื้อหาของแถบค้นหานี้เพื่อแสดงผลการค้นหาใต้inputField

ข้อมูลโค้ดนี้แสดงการติดตั้งใช้งาน SearchBar ขั้นพื้นฐานพร้อมคำแนะนำ

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SimpleSearchBar(
    textFieldState: TextFieldState,
    onSearch: (String) -> Unit,
    searchResults: List<String>,
    modifier: Modifier = Modifier
) {
    // Controls expansion state of the search bar
    var expanded by rememberSaveable { mutableStateOf(false) }

    Box(
        modifier
            .fillMaxSize()
            .semantics { isTraversalGroup = true }
    ) {
        SearchBar(
            modifier = Modifier
                .align(Alignment.TopCenter)
                .semantics { traversalIndex = 0f },
            inputField = {
                SearchBarDefaults.InputField(
                    query = textFieldState.text.toString(),
                    onQueryChange = { textFieldState.edit { replace(0, length, it) } },
                    onSearch = {
                        onSearch(textFieldState.text.toString())
                        expanded = false
                    },
                    expanded = expanded,
                    onExpandedChange = { expanded = it },
                    placeholder = { Text("Search") }
                )
            },
            expanded = expanded,
            onExpandedChange = { expanded = it },
        ) {
            // Display search results in a scrollable column
            Column(Modifier.verticalScroll(rememberScrollState())) {
                searchResults.forEach { result ->
                    ListItem(
                        headlineContent = { Text(result) },
                        modifier = Modifier
                            .clickable {
                                textFieldState.edit { replace(0, length, result) }
                                expanded = false
                            }
                            .fillMaxWidth()
                    )
                }
            }
        }
    }
}

ประเด็นสำคัญเกี่ยวกับโค้ด

  • rememberSaveable ช่วยให้มั่นใจได้ว่าระบบจะคงสถานะของแถบค้นหาไว้ไม่ว่าจะขยายหรือ ยุบก็ตามเมื่อมีการเปลี่ยนแปลงการกำหนดค่า โดยจะเขียนค่าที่จดจำไว้ลงในsavedInstanceState Bundle ของ Activity ที่โฮสต์ก่อนที่ Activity จะถูกทำลายระหว่างการเปลี่ยนแปลงการกำหนดค่า
  • semantics ตัวปรับเปลี่ยนจะควบคุมลำดับการข้ามของ TalkBack
    • isTraversalGroup ตั้งค่าเป็น Box เพื่อจัดกลุ่ม Composable ย่อยทั้งหมด
    • traversalIndex ตั้งค่าเพื่อระบุลำดับที่ TalkBack อ่านข้อมูลการช่วยเหลือพิเศษจากเพียร์แต่ละกลุ่ม TalkBack จะอ่านข้อมูลการช่วยเหลือพิเศษ ในเพียร์ที่มีค่าเป็นลบ เช่น -1 ก่อนเพียร์ ที่มีค่าเป็นบวก เช่น 1 เนื่องจากค่าเป็นแบบลอย คุณจึง ระบุลำดับที่กำหนดเองของเพียร์จำนวนมากได้โดยการตั้งค่าระหว่าง -1.0 กับ 1.0 ในแต่ละเพียร์
  • SearchBar มี inputField สำหรับข้อมูลจากผู้ใช้และ Column เพื่อ แสดงคำแนะนำในการค้นหา
    • SearchBarDefaults.InputField สร้างช่องป้อนข้อมูลและจัดการการเปลี่ยนแปลง คำค้นหาของผู้ใช้
    • onQueryChange จะจัดการการป้อนข้อความและอัปเดตสถานะทุกครั้งที่ ข้อความในช่องป้อนข้อมูลมีการเปลี่ยนแปลง
    • สถานะ The expanded ควบคุมระดับการมองเห็นของรายการคำแนะนำ
  • searchResults.forEach { result -> … } จะวนซ้ำในsearchResults รายการและสร้าง ListItem สำหรับผลลัพธ์แต่ละรายการ
    • เมื่อคลิก ListItem ระบบจะอัปเดต textFieldState ยุบ แถบค้นหา และป้อนผลการค้นหาที่เลือกใน textField

ผลลัพธ์

แถบค้นหาจะแสดงขึ้นพร้อมกับตัวอักษร &quot;ก&quot; ที่พิมพ์อยู่ภายในแถบ รายการที่มีคำแนะนำในการค้นหา 6 รายการจะแสดงใต้แถบค้นหา
รูปที่ 2 แถบค้นหาพร้อมคำแนะนำที่แสดง

แถบค้นหาพร้อมรายการที่กรองแล้ว

ตัวอย่างนี้แสดง SearchBar ที่กรองรายการตามคำค้นหาของผู้ใช้

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CustomizableSearchBar(
    query: String,
    onQueryChange: (String) -> Unit,
    onSearch: (String) -> Unit,
    searchResults: List<String>,
    onResultClick: (String) -> Unit,
    // Customization options
    placeholder: @Composable () -> Unit = { Text("Search") },
    leadingIcon: @Composable (() -> Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") },
    trailingIcon: @Composable (() -> Unit)? = null,
    supportingContent: (@Composable (String) -> Unit)? = null,
    leadingContent: (@Composable () -> Unit)? = null,
    modifier: Modifier = Modifier
) {
    // Track expanded state of search bar
    var expanded by rememberSaveable { mutableStateOf(false) }

    Box(
        modifier
            .fillMaxSize()
            .semantics { isTraversalGroup = true }
    ) {
        SearchBar(
            modifier = Modifier
                .align(Alignment.TopCenter)
                .semantics { traversalIndex = 0f },
            inputField = {
                // Customizable input field implementation
                SearchBarDefaults.InputField(
                    query = query,
                    onQueryChange = onQueryChange,
                    onSearch = {
                        onSearch(query)
                        expanded = false
                    },
                    expanded = expanded,
                    onExpandedChange = { expanded = it },
                    placeholder = placeholder,
                    leadingIcon = leadingIcon,
                    trailingIcon = trailingIcon
                )
            },
            expanded = expanded,
            onExpandedChange = { expanded = it },
        ) {
            // Show search results in a lazy column for better performance
            LazyColumn {
                items(count = searchResults.size) { index ->
                    val resultText = searchResults[index]
                    ListItem(
                        headlineContent = { Text(resultText) },
                        supportingContent = supportingContent?.let { { it(resultText) } },
                        leadingContent = leadingContent,
                        colors = ListItemDefaults.colors(containerColor = Color.Transparent),
                        modifier = Modifier
                            .clickable {
                                onResultClick(resultText)
                                expanded = false
                            }
                            .fillMaxWidth()
                            .padding(horizontal = 16.dp, vertical = 4.dp)
                    )
                }
            }
        }
    }
}

ประเด็นสำคัญเกี่ยวกับโค้ด

  • ระบบจะเรียกใช้onQueryChangeฟังก์ชัน Lambda ทุกครั้งที่ผู้ใช้พิมพ์หรือ ลบข้อความในแถบค้นหา
  • SearchBarDefaults.InputField มี leadingIcon ซึ่งจะเพิ่มไอคอนค้นหา ที่จุดเริ่มต้นของช่องป้อนข้อมูล และ trailingIcon ซึ่งจะเพิ่มไอคอน "ตัวเลือกเพิ่มเติม" ที่ส่วนท้ายของช่องป้อนข้อมูล ในส่วนนี้ คุณสามารถระบุ ตัวเลือกการจัดเรียงและการกรองให้ผู้ใช้ได้
  • onSearch = { … } จะเรียกใช้ Lambda onSearch และยุบแถบค้นหา เมื่อส่งการค้นหา
  • LazyColumnจัดการผลการค้นหาจำนวนมากที่อาจเกิดขึ้น ได้อย่างมีประสิทธิภาพ โดยจะวนซ้ำในsearchResults list และแสดงผลลัพธ์แต่ละรายการเป็น ListItem
  • Composable แต่ละรายการ ListItem จะแสดงข้อความของรายการ ข้อความที่แสดงข้อมูลเพิ่มเติม และไอคอนดาวเป็น leadingContent ของรายการ ในตัวอย่างนี้ ตัวเลือกในการเพิ่มรายการเป็นรายการโปรดจะปรากฏขึ้น
  • ดูตรรกะการกรองได้ที่ CustomizableSearchBarExample ในซอร์สโค้ดแบบเต็ม บน GitHub

ผลลัพธ์

แถบค้นหาที่มีคำว่า &quot;ค้นหาข้อความที่แนะนำ&quot; จะปรากฏขึ้น ระบบจะแสดงรายการคำแนะนำในการค้นหาใต้แถบค้นหา โดยมีไอคอนรูปดาวข้างคำแนะนำแต่ละรายการ
รูปที่ 3 แถบค้นหาที่มีคำแนะนำที่เกี่ยวข้องแสดงอยู่

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