ใช้แถบค้นหาเพื่อใช้ฟังก์ชันการค้นหา แถบค้นหาคือช่องค้นหาแบบถาวรที่ให้ผู้ใช้ป้อนคีย์เวิร์ดหรือวลีเพื่อแสดงผลลัพธ์ที่เกี่ยวข้องภายในแอป และขอแนะนำให้ใช้เมื่อการค้นหาเป็นจุดมุ่งหมายหลักของแอป
แพลตฟอร์ม API
ใช้ Composable 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ของกิจกรรมที่โฮสต์ก่อนที่กิจกรรมจะถูกทำลายระหว่างการเปลี่ยนแปลงการกำหนดค่า- ตัวแก้ไข
semanticsจะควบคุมลำดับการส่งผ่านของ TalkBackisTraversalGroupมีการตั้งค่าสำหรับBoxเพื่อจัดกลุ่ม Composable ย่อยทั้งหมดtraversalIndexมีไว้เพื่อระบุลำดับที่ TalkBack อ่านข้อมูลการช่วยเหลือพิเศษจากแอปเทียบเท่าแต่ละกลุ่ม TalkBack จะอ่านข้อมูลการช่วยเหลือพิเศษในระดับเดียวกันที่มีค่าเป็นลบ เช่น-1ก่อนระดับเดียวกันที่มีค่าเป็นบวก เช่น1เนื่องจากค่าเป็นแบบลอย คุณจึงระบุลำดับที่กำหนดเองของเพียร์หลายรายการได้โดยตั้งค่าระหว่าง-1.0ถึง1.0ในเพียร์แต่ละรายการ
SearchBarมีinputFieldสำหรับอินพุตของผู้ใช้และColumnเพื่อแสดงการแนะนำการค้นหาSearchBarDefaults.InputFieldจะสร้างช่องป้อนข้อมูลและจัดการการเปลี่ยนแปลงในคำค้นหาของผู้ใช้onQueryChangeจะจัดการการป้อนข้อความและอัปเดตสถานะทุกครั้งที่ข้อความในช่องป้อนข้อมูลมีการเปลี่ยนแปลง- สถานะ
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) ) } } } } }
ประเด็นสำคัญเกี่ยวกับโค้ด
- ระบบจะเรียกใช้ฟังก์ชัน Lambda
onQueryChangeทุกครั้งที่ผู้ใช้พิมพ์หรือลบข้อความในแถบค้นหา SearchBarDefaults.InputFieldมีleadingIconซึ่งจะเพิ่มไอคอนค้นหาที่จุดเริ่มต้นของช่องป้อนข้อมูล และtrailingIconซึ่งจะเพิ่มไอคอน "ตัวเลือกเพิ่มเติม" ที่ส่วนท้ายของช่องป้อนข้อมูล ในส่วนนี้ คุณสามารถระบุตัวเลือกการจัดเรียงและการกรองให้แก่ผู้ใช้ได้onSearch = { … }เรียกใช้แลมบ์ดาonSearchและยุบแถบค้นหาเมื่อส่งการค้นหาLazyColumnจัดการผลการค้นหาจำนวนมากได้อย่างมีประสิทธิภาพ โดยจะทำซ้ำผ่านรายการsearchResultsและแสดงผลลัพธ์แต่ละรายการเป็นListItem- องค์ประกอบ
ListItemแต่ละรายการจะแสดงข้อความของรายการ ข้อความที่แสดงข้อมูลเพิ่มเติม และไอคอนรูปดาวเป็นleadingContentของรายการ ในตัวอย่างนี้ ระบบจะแสดงตัวเลือกให้เพิ่มรายการเป็นรายการโปรด - ดูตรรกะการกรองได้ที่
CustomizableSearchBarExampleในซอร์สโค้ดแบบเต็มใน GitHub
ผลลัพธ์
แหล่งข้อมูลเพิ่มเติม
- Material Design: แถบค้นหา