動的トップ アプリバーを作成する

このガイドでは、リストからアイテムを選択するとオプションが変更される、Compose で動的なトップアプリバーを作成する方法について説明します。選択状態に基づいて、上部のアプリバーのタイトルとアクションを変更できます。

上部のアプリバーの動的な動作を実装する

このコードは、アイテムの選択に応じて変化する、上部アプリバーのコンポーズ可能な関数を定義します。

@Composable
fun AppBarSelectionActions(
    selectedItems: Set<Int>,
    modifier: Modifier = Modifier,
) {
    val hasSelection = selectedItems.isNotEmpty()
    val topBarText = if (hasSelection) {
        "Selected ${selectedItems.size} items"
    } else {
        "List of items"
    }

    TopAppBar(
        title = {
            Text(topBarText)
        },
        colors = TopAppBarDefaults.topAppBarColors(
            containerColor = MaterialTheme.colorScheme.primaryContainer,
            titleContentColor = MaterialTheme.colorScheme.primary,
        ),
        actions = {
            if (hasSelection) {
                IconButton(onClick = {
                    /* click action */
                }) {
                    Icon(
                        imageVector = Icons.Filled.Share,
                        contentDescription = "Share items"
                    )
                }
            }
        },
    )
}

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

  • AppBarSelectionActions は、選択したアイテム インデックスの Set を受け入れます。
  • topBarText は、項目が選択されているかどうかに応じて変化します。
    • アイテムを選択すると、選択したアイテム数を示すテキストが TopAppBar に表示されます。
    • 項目が選択されていない場合、topBarText は「List of items」です。
  • actions ブロックは、上部のアプリバーに表示されるアクションを定義します。hasSelection が true の場合、テキストの後に共有アイコンが表示されます。
  • IconButtononClick ラムダは、アイコンがクリックされたときの共有アクションを処理します。

結果

動的なトップ アプリバーに、[3 つのアイテムを選択しました] というテキストと共有アイコンが表示されています。このテキストとアイコンは、アイテムが選択されている場合にのみ表示されます
図 1. アイテムが選択された場合にのみ表示されるテキストと共有アイコンを含む、動的トップ アプリバー。

選択リストを動的トップアプリバーに統合する

この例は、選択リストを動的トップ アプリバーに追加する方法を示しています。

@Composable
private fun AppBarMultiSelectionExample(
    modifier: Modifier = Modifier,
) {
    val listItems by remember { mutableStateOf(listOf(1, 2, 3, 4, 5, 6)) }
    var selectedItems by rememberSaveable { mutableStateOf(setOf<Int>()) }

    Scaffold(
        topBar = { AppBarSelectionActions(selectedItems) }
    ) { innerPadding ->
        LazyColumn(contentPadding = innerPadding) {
            itemsIndexed(listItems) { _, index ->
                val isItemSelected = selectedItems.contains(index)
                ListItemSelectable(
                    selected = isItemSelected,
                    Modifier
                        .combinedClickable(
                            interactionSource = remember { MutableInteractionSource() },
                            indication = null,
                            onClick = {
                                /* click action */
                            },
                            onLongClick = {
                                if (isItemSelected) selectedItems -= index else selectedItems += index
                            }
                        )
                )
            }
        }
    }
}

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

  • 上部のバーは、選択されているリストアイテムの数に基づいて更新されます。
  • selectedItems には、選択したアイテムのインデックスのセットが保持されます。
  • AppBarMultiSelectionExampleScaffold を使用して画面を構造化します。
    • topBar = { AppBarSelectionActions(selectedItems) } は、AppBarSelectionActions コンポーザブルをトップ アプリバーとして設定します。AppBarSelectionActionsselectedItems 状態を受け取ります。
  • LazyColumn は、アイテムを縦方向のリストに表示し、画面に表示されているアイテムのみをレンダリングします。
  • ListItemSelectable は、選択可能なリストアイテムを表します。
    • combinedClickable を使用すると、アイテム選択のクリックと長押しの両方の処理が可能になります。クリックするとアクションが実行され、アイテムを長押しすると選択状態が切り替わります。

結果

動的なトップ アプリバーに「3 つのアイテムを選択しました」というテキストと、その後に共有アイコンが表示されます。下には、複数の項目が表示され、選択されている 3 つの項目の横にチェックマークが付いています。
図 2. 特定のアイテムが選択された、動的トップアプリバーに統合されたリスト。

参考情報