משתמשים בשורת חיפוש כדי להטמיע פונקציונליות של חיפוש. סרגל חיפוש הוא שדה חיפוש קבוע שמאפשר למשתמשים להזין מילת מפתח או ביטוי כדי להציג תוצאות רלוונטיות באפליקציה. מומלץ להשתמש בו כשהחיפוש הוא המוקד העיקרי של האפליקציה.
פלטפורמת ה-API
משתמשים ברכיב ה-Composable 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מבטיח שהמצב של שורת החיפוש (מורחב או מכווץ) יישמר גם אם משנים את ההגדרות. הוא כותב את הערך שנשמר בחבילתsavedInstanceStateשל ה-Activity המארח לפני שה-Activity נהרס במהלך שינוי ההגדרות. - המשתנה
semanticsשולט בסדר המעבר של TalkBack.- המאפיין
isTraversalGroupמוגדר ל-Boxכדי לקבץ את כל הרכיבים הניתנים לשילוב ברמת הצאצא. - המאפיין
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) ) } } } } }
מידע חשוב על הקוד
- פונקציית הלמבדה
onQueryChangeנקראת בכל פעם שהמשתמש מקליד או מוחק טקסט בשורת החיפוש. -
SearchBarDefaults.InputFieldמכילleadingIcon, שמוסיף סמל חיפוש לתחילת השדה להזנת קלט, ו-trailingIcon, שמוסיף סמל של "אפשרויות נוספות" לסוף השדה להזנת קלט. כאן אפשר לספק למשתמש אפשרויות מיון וסינון. -
onSearch = { … }קורא ל-lambda שלonSearchומכווץ את שורת החיפוש כששולחים את החיפוש. LazyColumnמטפל ביעילות במספר גדול של תוצאות חיפוש. הוא עובר על הרשימהsearchResultsומציג כל תוצאה בתורListItem.- כל רכיב קומפוזבילי מסוג
ListItemמציג את טקסט הפריט, טקסט עם מידע נוסף וסמל כוכב בתור ה-leadingContentשל הפריט. בדוגמה הזו, מוצגת אפשרות להוסיף את הפריט למועדפים. - לוגיקת הסינון מופיעה ב-
CustomizableSearchBarExampleבקוד המקור המלא ב-GitHub.
תוצאה
מקורות מידע נוספים
- Material Design: שורת חיפוש