📝

Accompanistの使い所 (Jetpack Compose)

2022/07/11に公開

はじめに

Jetpack Composeを使用する際にAccompanistというのを聞くが、一体何者でどのような時に使えばよいか不明だったため、調べたことを書きました。 参考程度に(v0.24.13-rc時点)

どのような時に使えるか

まずはさくっと。実現したいことで以下に当てはまる場合はAccompanistの導入を検討してください。

  • SystemUIバーの色を更新したい
  • 既存のアプリ、フラグメントをJetpackComposeに移行する際、既存のActivityのXMLテーマの色やタイポグラフィを、MaterialThemeに反映したい
  • ページングUI(ViewPager)を実現したい
  • カメラや位置情報などの権限周りを取得する
  • コンテンツの読み込み中の表示をいい感じにしたい
  • Viewを横(縦)並びにした際に、よしなに改行してほしい
  • 遷移時のアニメーションをカスタマイズしたい
  • ボトムシートを表示したい
  • リスト表示時等のPullToRefreshを実現したい
  • 既存のdrawableをJetpack Composeで使用したい
  • Webページを表示したい

もう少し詳しく知りたい方は以下をどうぞ

Accompanistとは

Jetpack Composは従来の手法と比べると、必要とする機能が足りてないので、それを補うことを目的としたライブラリーグループ。ComposeAPIのラボのようなもの。
公式のツールキットに導入されることが目的。導入後は非推奨になり、Accompanistから削除される。

使用時の注意事項

Composeのバージョンと一致するAccompanistバージョンを使用すること

各ライブラリ

System UI Controller

用途: SystemUIバーの色を更新したい
使い方: https://google.github.io/accompanist/systemuicontroller/

  • SystemUiControllerを使用
val systemUiController = rememberSystemUiController()
val useDarkIcons = MaterialTheme.colors.isLight

SideEffect {
    systemUiController.setSystemBarsColor(
        color = Color.Transparent,
        darkIcons = useDarkIcons
    )
}

AppCompat Theme

用途: 既存のアプリ、フラグメントをJetpackComposeに移行する際、既存のActivityのXMLテーマの色やタイポグラフィを、MaterialThemeに反映したい
使い方: https://google.github.io/accompanist/appcompat-theme/

  • MaterialThemeの代わりにAppCompatThemeを使用
  • カスタマイズしたい場合はcreateAppCompatTheme を用いてcolorsとtypographyの設定を取得
val context = LocalContext.current
var (colors, type) = context.createAppCompatTheme()
MaterialTheme(
    colors = colors,
    typography = type
) {
    
}

Pager layouts

用途: ページングUI(ViewPager)を実現したい
使い方: https://google.github.io/accompanist/pager/

  • 水平方向はHorizontalPager, 垂直方向はVerticalPagerを使用。特定のページに飛びたい場合はpagerStateを使用
val pagerState = rememberPagerState()
HorizontalPager(count = 10, state = pagerState) { page ->
  // content
}
// 6ページ目に遷移したい場合
scope.launch {
    pagerState.scrollToPage(6)
}
  • コンテンツへのパディングもつけれる
//  左右をちょい見せしたい場合
HorizontalPager(
    count = 4,
    contentPadding = PaddingValues(horizontal = 32.dp),
) { page ->
    // content
}
  • calculateCurrentOffsetForPage()でスクロール時のページの現在の位置を取得可能
  • ページ変更時の処理
val pagerState = rememberPagerState()
LaunchedEffect(pagerState) {
    snapshotFlow { pagerState.currentPage }.collect { page ->
        // ページが切り替わった際の処理を書く
    }
}
VerticalPager(
    count = 10,
    state = pagerState,
) { page ->
    Text(text = "Page: $page")
}
  • ページインジケーターもある(何ページあり何ページ目を表示しているいかのUI)

    • VerticalPagerIndicator, HorizontalPagerIndicator
  • タブとの統合も可能

val pagerState = rememberPagerState()
TabRow(
    selectedTabIndex = pagerState.currentPage,
    indicator = { tabPositions ->
        TabRowDefaults.Indicator(
            Modifier.pagerTabIndicatorOffset(pagerState, tabPositions)
        )
    }
) {
    pages.forEachIndexed { index, title ->
        Tab(
            text = { Text(title) },
            selected = pagerState.currentPage == index,
            onClick = { /* TODO */ },
        )
    }
}

HorizontalPager(
    count = pages.size,
    state = pagerState,
) { page ->
    // TODO: page content
}

Swipe Refresh

用途: リスト表示時等のPullToRefreshを実現したい
使い方: https://google.github.io/accompanist/swiperefresh/

val viewModel: MyViewModel = viewModel()
val isRefreshing by viewModel.isRefreshing.collectAsState()
SwipeRefresh(
    state = rememberSwipeRefreshState(isRefreshing),
    onRefresh = { viewModel.refresh() },
) {
    LazyColumn {
        items(30) { index ->
          
        }
    }
}

Placeholder

用途: コンテンツの読み込み中の表示をいい感じにしたい
使い方: https://google.github.io/accompanist/placeholder/

  • 種類が2つある
    • Placeholder Foundation
      -> アプリが表示する色を指定する必要がある
    • Placeholder Material
      -> マテリアルカラーパレットを使用して適切な色を表示する
  • 表示 エフェクトは以下
    • Basic
    • Fade
    • Shimmer

Drawable Painter

用途: 既存のdrawableをJetpack Composeで使用したい
使い方: https://google.github.io/accompanist/drawablepainter/
ほとんどのDrawableとAnimatedVectorDrawableなどのアニメーションするDrawableをサポート

Flow layouts

用途: Viewを横(縦)並びにした際に、よしなに改行してほしい
使い方: https://google.github.io/accompanist/flowlayout/

Permissions

用途: カメラや位置情報などの権限周りを取得する
使い方: https://google.github.io/accompanist/permissions/

  • 単一の権限の取得はrememberPermissionStateを使用
  • 複数の権限の取得はrememberMultiplePermissionsStateを使用 (公式サンプル)

用途: 遷移時のアニメーションをカスタマイズしたい
使い方: https://google.github.io/accompanist/navigation-animation/
公式サンプルはこちら

用途: ボトムシートを表示したい
使い方: https://google.github.io/accompanist/navigation-material/
公式サンプルはこちら

WebView

用途: Webページを表示したい
使い方: https://google.github.io/accompanist/webview/

val state = rememberWebViewState("https://example.com")
WebView(state)
// WebViewの設定をする場合
WebView(
    state = webViewState,
    onCreated = { it.settings.javaScriptEnabled = true }
)
// バックプレス/スワイプで戻るのを無効にする
WebView(
    state = webViewState,
    captureBackPresses = false
)

Discussion