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örüntülemek için bir anahtar kelime veya ifade girmesine olanak tanıyan kalıcı bir arama alanıdır. 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.
1. şekil. 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 composable'ın 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 Lambda.
  • expanded: Arama çubuğunun, önerileri veya filtrelenmiş sonuçları gösterecek şekilde 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'in altında göstermek için bu arama çubuğunun içeriği.

Bu snippet'te, önerilerle birlikte SearchBar'nın 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, yapılandırma değişiklikleri sırasında arama çubuğunun genişletilmiş veya daraltılmış olmasının korunmasını sağlar. Bu yöntem, yapılandırma değişikliği sırasında Etkinlik yok edilmeden önce hatırlanan değeri, barındıran Etkinliğin savedInstanceState paketine yazar.
  • semantics değiştiricisi, TalkBack'in geçiş sırasını kontrol eder.
    • isTraversalGroup, tüm alt composable'ları 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, -1 gibi negatif değere sahip bir öğedeki erişilebilirlik bilgilerini, 1 gibi pozitif değere sahip bir öğeden önce 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 -> … }, searchResultslisteyiListItem yineler ve her sonuç için bir ListItem oluşturur.
    • Bir 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österilir.
Ş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 bir SearchBar gösterilmektedir:

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

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 listesini yineler ve her sonucu ListItem olarak gösterir.
  • Her ListItem composable'ı, öğe metnini, ek bilgileri gösteren metni ve öğenin leadingContent olarak bir yıldız simgesini gösterir. 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 bir yıldız simgesiyle birlikte arama önerileri listesi gösterilir.
3.şekil Alakalı önerilerin gösterildiği bir arama çubuğu.

Ek kaynaklar