نوار جستجو

از نوار جستجو برای اجرای عملکرد جستجو استفاده کنید. نوار جستجو یک فیلد جستجوی دائمی است که به کاربران امکان می‌دهد یک کلمه کلیدی یا عبارت را وارد کنند تا نتایج مرتبط را در برنامه شما نمایش دهد و زمانی توصیه می‌شود که جستجو تمرکز اصلی برنامه شما باشد.

دو نوار جستجو نشان داده شده است. مورد سمت چپ فقط یک فیلد متنی دارد.   نوار جستجو در سمت چپ دارای یک فیلد متنی و یک پیشنهاد جستجو در زیر آن است.
شکل 1. یک نوار جستجوی اولیه (1) و یک نوار جستجو با یک پیشنهاد (2).

سطح API

از SearchBar composable برای پیاده سازی نوارهای جستجو استفاده کنید. پارامترهای کلیدی برای این ترکیب شامل موارد زیر است:

  • inputField : فیلد ورودی نوار جستجو را تعریف می کند. معمولاً از SearchBarDefaults.InputField استفاده می کند که امکان سفارشی سازی موارد زیر را فراهم می کند:
    • query : متن درخواستی که باید در قسمت ورودی نشان داده شود..
    • onQueryChange : Lambda برای رسیدگی به تغییرات در رشته query.
  • expanded : یک بولی که نشان می دهد نوار جستجو برای نمایش پیشنهادات یا نتایج فیلتر شده گسترش یافته است یا خیر.
  • onExpandedChange : لامبدا برای کنترل تغییرات در حالت بازشده کشویی.

  • 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 تضمین می‌کند که نوار جستجو بزرگ یا جمع‌شده در تغییرات پیکربندی حفظ می‌شود. قبل از اینکه Activity در طول تغییر پیکربندی از بین برود، مقدار به خاطر سپرده شده را در بسته savedInstanceState 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 با نتیجه جستجوی انتخاب شده پر می کند.

نتیجه

یک نوار جستجو با تایپ حرف "a" در داخل نوار نشان داده می شود. فهرستی شامل شش پیشنهاد جستجو در زیر نوار جستجو نمایش داده می شود.
شکل 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 زمانی فراخوانی می شود که کاربر متنی را در نوار جستجو تایپ یا حذف کند.
  • SearchBarDefaults.InputField شامل یک leadingIcon است که یک نماد جستجو را به ابتدای فیلد ورودی اضافه می کند و یک trailingIcon که یک نماد "گزینه های بیشتر" را به انتهای فیلد ورودی اضافه می کند. در اینجا می توانید گزینه های مرتب سازی و فیلترینگ را در اختیار کاربر قرار دهید.
  • onSearch = { … } onSearch لامبدا را فراخوانی می کند و نوار جستجو را هنگام ارسال جستجو جمع می کند.
  • LazyColumn تعداد بالقوه زیادی از نتایج جستجو را به طور موثر مدیریت می کند. از طریق لیست searchResults تکرار می شود و هر نتیجه را به عنوان ListItem نمایش می دهد.
  • هر ListItem قابل ترکیب، متن مورد، متنی که اطلاعات اضافی را نشان می دهد و یک نماد ستاره را به عنوان leadingContent مورد نشان می دهد. در این مثال، گزینه ای برای دلخواه مورد نظر ارائه شده است.
  • برای منطق فیلتر کردن، CustomizableSearchBarExample در کد منبع کامل در GitHub ببینید.

نتیجه

یک نوار جستجو حاوی کلمات جستجوی متن اشاره شده در داخل نشان داده شده است. در زیر نوار جستجو، لیستی از پیشنهادات جستجو نمایش داده می شود که در کنار هر پیشنهاد یک نماد ستاره وجود دارد.
شکل 3. یک نوار جستجو با پیشنهادات مرتبط نمایش داده شده است.

منابع اضافی