شريط البحث

استخدِم شريط بحث لتنفيذ وظيفة البحث. شريط البحث هو حقل بحث دائم يتيح للمستخدمين إدخال كلمة رئيسية أو عبارة لعرض نتائج ذات صلة داخل تطبيقك، ويُنصح باستخدامه عندما يكون البحث هو التركيز الأساسي لتطبيقك.

يظهر شريطا بحث. يحتوي النموذج على اليمين على حقل نصي فقط.
  يحتوي شريط البحث على يمين الصفحة على حقل نصي واقتراح بحث أسفله.
الشكل 1. شريط بحث أساسي (1) وشريط بحث يتضمّن اقتراحًا (2)

مساحة واجهة برمجة التطبيقات

استخدِم 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 مع إدخال النص ويعدّل الحالة كلما تغيّر النص في حقل الإدخال.
    • تتحكّم حالة The expanded في مستوى ظهور قائمة الاقتراحات.
  • تتكرّر searchResults.forEach { result -> … } خلال قائمة searchResults وتنشئ ListItem لكل نتيجة.
    • عند النقر على ListItem، يتم تعديل textFieldState وتصغير شريط البحث وملء textField بنتيجة البحث المحدّدة.

النتيجة

يظهر شريط بحث مكتوب داخله الحرف &quot;أ&quot;. يتم عرض قائمة تحتوي على ستة اقتراحات بحث أسفل شريط البحث.
الشكل 2. شريط بحث مع اقتراحات معروضة

شريط البحث مع قائمة تمت فلترتها

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

النتيجة

يظهر شريط بحث يحتوي على عبارة &quot;البحث النصي الملمّح&quot;. أسفل شريط البحث، تظهر قائمة باقتراحات البحث مع رمز نجمة بجانب كل اقتراح.
الشكل 3. شريط بحث مع اقتراحات ذات صلة معروضة

مراجع إضافية