شريط البحث

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

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

النتيجة

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

مراجع إضافية