استخدِم شريط البحث لتنفيذ وظيفة البحث. شريط البحث هو حقل بحث دائم يتيح للمستخدمين إدخال كلمة رئيسية أو عبارة لعرض النتائج ذات الصلة داخل تطبيقك، ويُنصح به عندما يكون البحث هو التركيز الأساسي لتطبيقك.
مساحة عرض واجهة برمجة التطبيقات
استخدِم الدالة المركّبة 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لتجميع جميع الدوال المركّبة الفرعية. - يتم ضبط السمة
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 = { … }دالة lambdaonSearchويصغّر شريط البحث عند إرسال طلب البحث. - يتعامل
LazyColumnمع عدد كبير من نتائج البحث بكفاءة. تتكرّر هذه الدالة في قائمةsearchResultsوتعرض كل نتيجة على شكلListItem. - تعرض كل دالة مركّبة
ListItemنص العنصر ونصًا يعرض معلومات إضافية ورمز نجمة كـleadingContentللعنصر. في هذا المثال، يتم تقديم خيار لتفضيل العنصر. - للاطّلاع على منطق الفلترة، يمكنك مراجعة
CustomizableSearchBarExampleفي الرمز المصدر الكامل على GitHub.
النتيجة
مراجع إضافية
- التصميم المتعدد الأبعاد: شريط البحث