🤏

Jetpack ComposeでModal風に見せる

2023/03/31に公開

今回する話

スペースマーケットでAndroid開発を担当していますseoです。

前回投稿したJetpack ComposeのModalって直感的じゃないですよね、という話の延長ですが、ModalBottomSheetLayoutにLazyColumnを置くと、下スワイプ中にモーダルが閉じてしまうバグがあるみたいです😢

そのため、Modal内でリスト表示したい場合などでは、ModalBottomSheetLayoutを使うべきなのですが、これはこれでModalを非表示にさせる処理などがぎこちなく、あまり使い勝手がよいと感じませんでした。

↓そこで考えた方法が、NavigationにAnimationをつけて、Modal風に見せる方法です。

Image from Gyazo
*検索結果一覧画面から検索条件絞り込みへの遷移する様子です。

厳密に言うと、全然Modalではないのですが、下から出てくることでModal風に見せることに成功しました笑

実装方法

  1. NavHostにAnimationをつけたいため、accompanist-navigation-animationをgradleに追加します。
implementation "com.google.accompanist:accompanist-navigation-animation:$accompanistVer"
  1. enterTransition, popEnterTransition, popExitTransitionにそれぞれAnimationを設定します。
import com.google.accompanist.navigation.animation.AnimatedNavHost

AnimatedNavHost(
    navController = navHostController,
    startDestination = SearchScreen.MainScreen.route,
) {
    // 検索一覧画面
    composable(
	SearchScreen.MainScreen.route
    ) {
        // 検索一覧画面Compose
    }
    // 検索条件モーダル
    composable(
	SearchScreen.SearchListScreen.route,
	enterTransition = {
	    slideIn { fullSize -> IntOffset(0, fullSize.height) }
	},
	popEnterTransition = {
	    slideIn { fullSize -> IntOffset(-fullSize.width, 0) }
	},
	popExitTransition = {
	    slideOut { fullSize -> IntOffset(0, fullSize.height) }
	}
    ) {
       // 検索条件モーダルCompose
    }

iOSのPush遷移風に見せたい場合

上記の方法を応用して、iOSのPush遷移風に見せることもできます。

composable(
    SearchScreen.AreaSearchScreen.route,
    enterTransition = {
        slideIn { fullSize -> IntOffset(fullSize.width, 0) }
    },
    popEnterTransition = {
	slideIn { fullSize -> IntOffset(-fullSize.width, 0) }
    },
    exitTransition = {
        slideOut { fullSize -> IntOffset(-fullSize.width, 0) }
    },
    popExitTransition = {
        slideOut { fullSize -> IntOffset(fullSize.width, 0) }
    },
) {
    // 遷移先画面Compose
}

Image from Gyazo

最後に

スペースマーケットではAndroid/Flutterエンジニアを絶賛募集中です!
ご応募お待ちしています!

https://herp.careers/v1/spmhr/m2LlDFRg7Ck0

スペースマーケット Engineer Blog

Discussion