משתמשים בסרגל חיפוש כדי להטמיע פונקציונליות חיפוש. שורת חיפוש היא שדה חיפוש קבוע שמאפשר למשתמשים להזין מילת מפתח או ביטוי כדי להציג תוצאות רלוונטיות באפליקציה. מומלץ להשתמש בשורת חיפוש כשהחיפוש הוא המוקד העיקרי של האפליקציה.

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

מקורות מידע נוספים
- Material Design: סרגל חיפוש