ใช้แถบค้นหาเพื่อใช้ฟังก์ชันการค้นหา แถบค้นหาคือช่องค้นหาแบบถาวรที่ช่วยให้ผู้ใช้ป้อนคีย์เวิร์ดหรือวลีเพื่อแสดงผลลัพธ์ที่เกี่ยวข้องภายในแอปของคุณ และขอแนะนำให้ใช้เมื่อการค้นหาเป็นจุดสนใจหลักของแอป
แพลตฟอร์ม API
ใช้ SearchBar ที่ใช้ร่วมกันได้เพื่อใช้แถบค้นหา พารามิเตอร์หลักสำหรับ
ฟังก์ชันที่ประกอบกันได้นี้มีดังนี้
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ช่วยให้มั่นใจได้ว่าระบบจะคงสถานะของแถบค้นหาไม่ว่าจะขยายหรือ ยุบไว้เมื่อมีการเปลี่ยนแปลงการกำหนดค่า โดยจะเขียนค่าที่จดจำไว้ลงในsavedInstanceStateBundle ของ Activity ที่โฮสต์ก่อนที่ Activity จะถูกทำลายระหว่างการเปลี่ยนแปลงการกำหนดค่าsemanticsตัวแก้ไขจะควบคุมลำดับการข้ามของ TalkBackisTraversalGroupตั้งค่าเป็น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
- เมื่อคลิก
ผลลัพธ์
แถบค้นหาพร้อมรายการที่กรองแล้ว
ตัวอย่างนี้แสดง SearchBar ที่กรองรายการตามคำค้นหาของผู้ใช้
@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomizableSearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, searchResults: List<String>, onResultClick: (String) -> Unit, modifier: Modifier = Modifier, // 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, ) { // 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 = { … }จะเรียกใช้ LambdaonSearchและยุบแถบค้นหา เมื่อส่งการค้นหาLazyColumnจัดการผลการค้นหาจำนวนมากที่อาจเกิดขึ้น ได้อย่างมีประสิทธิภาพ โดยจะวนซ้ำในsearchResultslist และแสดงผลลัพธ์แต่ละรายการเป็นListItem- Composable แต่ละรายการ
ListItemจะแสดงข้อความของรายการ ข้อความที่แสดงข้อมูลเพิ่มเติม และไอคอนดาวเป็นleadingContentของรายการ ในตัวอย่างนี้ ตัวเลือกในการเพิ่มรายการเป็นรายการโปรดจะปรากฏขึ้น - ดูตรรกะการกรองได้ที่
CustomizableSearchBarExampleในซอร์สโค้ดแบบเต็ม บน GitHub
ผลลัพธ์
แหล่งข้อมูลเพิ่มเติม
- Material Design: แถบค้นหา