入力中にリストをフィルタする

このガイドでは、Jetpack Compose でテキスト入力に基づいて文字列のリストをフィルタする方法について説明します。この方法は、ユーザーの検索語句に基づいてリストを動的に更新する場合に使用します。

バージョンの互換性

この実装は、Compose バージョン 1.2.0 以降で動作します。

依存関係

build.gradle に次の依存関係を含めます。

テキスト入力に基づいてリストをフィルタする

次のスニペットを組み合わせると、ユーザーが入力するたびにリアルタイムで更新されるリストが生成されます。この例では、ViewModel を使用してリストデータとフィルタリング ロジックを保持し、FilterTextView() 関数を使用して、フィルタテキストが変更されるたびに自動的に更新される UI を作成します。

class FilterTextViewModel : ViewModel() {
    private val items = listOf(
        "Cupcake",
        "Donut",
        "Eclair",
        "Froyo",
        "Gingerbread",
        "Honeycomb",
        "Ice Cream Sandwich"
    )

    private val _filteredItems = MutableStateFlow(items)
    var filteredItems: StateFlow<List<String>> = _filteredItems

    fun filterText(input: String) {
        // This filter returns the full items list when input is an empty string.
        _filteredItems.value = items.filter { it.contains(input, ignoreCase = true) }
    }
}

コードに関する主なポイント

  • ViewModel コードは、フィルタリング作業をコンポーザブルから抽象化します。
  • ViewModel には、元のリストとフィルタされたリストの両方が保持されます。アイテムのリストと、フィルタされたアイテムを保持する MutableStateFlow を定義します。
  • filterText 関数は、指定された入力文字列に基づいてリストをフィルタし、filteredItems 状態を更新します。この状態は UI に渡されます。

@Composable
fun FilterTextView(modifier: Modifier = Modifier, viewModel: FilterTextViewModel = viewModel()) {
    val filteredItems by viewModel.filteredItems.collectAsStateWithLifecycle()
    var text by rememberSaveable { mutableStateOf("") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(all = 10.dp)
    ) {
        OutlinedTextField(
            value = text,
            onValueChange = {
                text = it
                viewModel.filterText(text)
            },
            label = { Text("Filter Text") },
            modifier = Modifier.fillMaxWidth()
        )

        LazyColumn {
            items(
                count = filteredItems.size,
                key = { index -> filteredItems[index] }
            ) {
                ListItem(
                    headlineContent = { Text(filteredItems[it]) },
                    modifier = Modifier
                        .fillParentMaxWidth()
                        .padding(10.dp)
                )
            }
        }
    }
}

コードに関する主なポイント

  • ユーザー入力用の OutlinedTextField と、フィルタされたリストアイテムを表示する LazyColumn を表示します。
  • ViewModel から filteredItems 状態フローを収集し、ライフサイクル対応の State オブジェクトに変換します。
    • collectAsStateWithLifecycleStateFlow から最新の値を収集し、値が変更されると UI を再コンポーズします。
  • text by rememberSaveable { mutableStateOf("") } は、フィルタ テキスト フィールドに入力された現在のテキストを保持する状態変数 text を作成します。
    • rememberSaveable は、構成の変更をまたいでテキストの値を保持します。
    • by キーワードは、テキストの値を MutableState オブジェクトの value プロパティに委任します。
  • テキストの変更が onValueChange コールバックをトリガーすると、OutlinedTextField はビューモデルから filterText 関数を呼び出します。

結果

図 1. 新しいテキストが入力されると更新されるフィルタされたリスト。

このガイドを含むコレクション

このガイドは、Android 開発の幅広い目標を網羅する、厳選されたクイックガイド コレクションの一部です。

ユーザーがテキストの入力やその他の入力手段を使用してアプリを操作できるようにする方法について学びます。

ご質問やフィードバックがある場合

よくある質問のページでクイックガイドをご覧になるか、お問い合わせフォームからご意見をお寄せください。