Arama çubuğu

Arama işlevini uygulamak için arama çubuğu kullanın. Arama çubuğu, kullanıcıların uygulamanızda alakalı sonuçları göstermek için bir anahtar kelime veya ifade girmesine olanak tanıyan kalıcı bir arama alanıdır ve arama, uygulamanızın temel odak noktası olduğunda kullanılması önerilir.

İki arama çubuğu gösterilir. Soldaki formda yalnızca bir metin alanı var.
  Soldaki arama çubuğunda bir metin alanı ve altında bir arama önerisi bulunur.
Şekil 1. Temel bir arama çubuğu (1) ve öneri içeren bir arama çubuğu (2).

API yüzeyi

Arama çubuklarını uygulamak için SearchBar composable'ını kullanın. Bu birleştirilebilir öğenin temel parametreleri şunlardır:

  • inputField: Arama çubuğunun giriş alanını tanımlar. Genellikle SearchBarDefaults.InputField kullanılır. Bu, aşağıdakilerin özelleştirilmesine olanak tanır:
    • query: Giriş alanında gösterilecek sorgu metni.
    • onQueryChange: Sorgu dizesindeki değişiklikleri işlemek için kullanılan Lambda.
  • expanded: Arama çubuğunun, önerileri veya filtrelenmiş sonuçları göstermek için genişletilip genişletilmediğini belirten bir boole değeri.
  • onExpandedChange: Açılır listenin genişletilmiş durumundaki değişiklikleri işlemek için Lambda.

  • content: Arama sonuçlarını inputField'nin altında göstermek için bu arama çubuğunun içeriği.

Bu snippet'te, önerilerle birlikte SearchBar öğesinin temel bir uygulaması gösterilmektedir:

@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()
                    )
                }
            }
        }
    }
}

Kodla ilgili önemli noktalar

  • rememberSaveable, arama çubuğunun genişletilmiş veya daraltılmış olmasının yapılandırma değişikliklerinde korunmasını sağlar. Bu yöntem, hatırlanan değeri, yapılandırma değişikliği sırasında Etkinlik yok edilmeden önce barındıran Etkinliğin savedInstanceState paketine yazar.
  • semantics değiştiricisi, TalkBack geçiş sırasını kontrol eder.
    • isTraversalGroup, tüm alt composable'larını gruplandırmak için Box olarak ayarlanır.
    • traversalIndex, TalkBack'in her grup eşinden erişilebilirlik bilgilerini okuma sırasını belirlemek için ayarlanır. TalkBack, pozitif değere sahip bir öğeden (ör. 1) önce negatif değere sahip bir öğedeki (ör. -1) erişilebilirlik bilgilerini okur. Değer bir kayan nokta olduğundan, her bir eşte -1.0 ile 1.0 arasında değerler ayarlayarak birçok eşin özel sırasını belirtebilirsiniz.
  • SearchBar, kullanıcı girişi için bir inputField ve arama önerilerini göstermek için bir Column içerir.
    • SearchBarDefaults.InputField giriş alanını oluşturur ve kullanıcı sorgusundaki değişiklikleri işler.
    • onQueryChange, metin girişini işler ve giriş alanındaki metin her değiştiğinde durumu günceller.
    • The expanded durumu, öneri listesinin görünürlüğünü kontrol eder.
  • searchResults.forEach { result -> … }, searchResultslistede yineleme yapar ve her sonuç için bir ListItem oluşturur.
    • ListItem tıklandığında textFieldState güncellenir, arama çubuğu daraltılır ve textField seçilen arama sonucuyla doldurulur.

Sonuç

İçine &quot;a&quot; harfinin yazıldığı bir arama çubuğu gösteriliyor. Arama çubuğunun altında altı arama önerisi içeren bir liste gösteriliyor.
Şekil 2. Önerilerin gösterildiği bir arama çubuğu.

Filtrelenmiş listeyle arama çubuğu

Bu örnekte, kullanıcıların arama sorgusuna göre bir listeyi filtreleyen SearchBar gösterilmektedir:

@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)
                    )
                }
            }
        }
    }
}

Kodla ilgili önemli noktalar

  • Kullanıcı, arama çubuğuna metin yazdığında veya metin sildiğinde onQueryChange lambda işlevi çağrılır.
  • SearchBarDefaults.InputField, giriş alanının başına bir arama simgesi ekleyen leadingIcon ve giriş alanının sonuna bir "diğer seçenekler" simgesi ekleyen trailingIcon içerir. Burada, kullanıcıya sıralama ve filtreleme seçenekleri sunabilirsiniz.
  • onSearch = { … }, onSearch lambda'sını çağırır ve arama gönderildiğinde arama çubuğunu daraltır.
  • Bir LazyColumn, olası çok sayıda arama sonucunu verimli bir şekilde işler. searchResults listesinde iterasyon yapar ve her sonucu ListItem olarak gösterir.
  • Her ListItem composable'da öğe metni, ek bilgileri gösteren metin ve öğenin leadingContent olarak bir yıldız simgesi gösterilir. Bu örnekte, öğeyi favorilere ekleme seçeneği sunuluyor.
  • Filtreleme mantığı için GitHub'daki tam kaynak kodunda CustomizableSearchBarExample bölümüne bakın.

Sonuç

İçinde &quot;ipuçlu metin arama&quot; kelimelerinin yer aldığı bir arama çubuğu gösterilir. Arama çubuğunun altında, her önerinin yanında yıldız simgesi bulunan bir arama önerileri listesi gösterilir.
Şekil 3. Alakalı önerilerin gösterildiği bir arama çubuğu.

Ek kaynaklar