💳

Jectpack Compose の AndroidView と Stripe Android Sdk でクレジットカード登録画面を作った話

2023/04/05に公開

こんにちは、Luup Androidチームの土谷です。

皆さん、Jetpack Compose書いていますか?
弊社のAndroidチームでも導入が進んでから徐々にJetpack Composeに移行しつつあります。
今回は表題通りではありますが、Jectpack Compose の AndroidView と Stripe Android Sdk でクレジットカード登録画面を作った話をしようと思います。

AndroidView とは

Compose UI に AndroidView 階層を含めることができます。
つまり、Composeでまだ利用できないUI要素(AdViewなど)を使用したいときに便利です。
また、このアプローチでは、設計したカスタムビューを再利用できます。

@Composable
@UiComposable
fun <T : View> AndroidView(
    factory: (Context) -> T,
    modifier: Modifier = Modifier,
    update: (T) -> Unit = NoOpUpdate
): Unit

Stripe Android Sdk とは

言わずもがな、決済周りを肩代わりしてくれるSdkです。
今回はSdkで提供されている「CardNumberEditText, ExpiryDateEditText, CvcEditText」を使いました。
https://github.com/stripe/stripe-android

なぜ AndroidView と Stripe Android Sdk で クレジットカード登録画面を作ったのか?

結論から言うと、Stripe Android Sdk で Compose専用のUI要素を提供していないからです。(2023/03/14執筆時点)
弊社Androidチームでは「新規画面の作成 or 既存画面を大きく編集するとき」には特別な理由がない限りComposeで実装するルールがあります。
一部だけ従来のlayout.xmlで実装する手も使えなくないのですが、せっかくなのでフルComposeで実装しました。

せっかくなのでちょっとだけ実装してみる

プロジェクト作成

Android Studio → New Project → Empty Compose Acitivty → Next。
スクリーンショット1

Android 5.0 (API Level 21) 以上に設定されていることを確認してから Finish。
サンプルでは LUUP Androidアプリの最低バージョンと同じである、Android 8.0 (API Level 26) を選択しました。
スクリーンショット2

インストール

下記の依存を追加します。
※バージョンは執筆時点の最新です。

dependencies {
    implementation "com.stripe:stripe-android:20.20.0"
}

こちらも追加しないとエラーとなってしまうので注意です。(執筆者も沼に嵌りました)

dependencies {
    implementation "com.google.android.material:material:1.8.0"
}

Stripe の View を AndroidView で追加する

AndroidView(
    factory = { context ->
        CardNumberEditText(context = context).apply {
            hint = "0000 0000 0000 0000"
        }
    }
)
AndroidView(
    factory = { context ->
        ExpiryDateEditText(context = context).apply {
            hint = "MM/YY"
        }
    }
)
AndroidView(
    factory = { context ->
        CvcEditText(context = context)
    }
)

コード全体

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                Column {
                    AndroidView(
                        factory = { context ->
                            CardNumberEditText(context = context).apply {
                                hint = "0000 0000 0000 0000"
                            }
                        }
                    )
                    AndroidView(
                        factory = { context ->
                            ExpiryDateEditText(context = context).apply {
                                hint = "MM/YY"
                            }
                        }
                    )
                    AndroidView(
                        factory = { context ->
                            CvcEditText(context = context)
                        }
                    )
                }
            }
        }
    }
}

themes.xml をイジる

<style name="Theme.MyApplication" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="android:statusBarColor">@color/purple_700</item>
</style>

ビルド結果

ちゃんとキーボード操作でフォーカス移動もされます!素晴らしい!
build

振り返り

元々、AbstractComposeView は使っていましたが今回初めて AndroidView を使いました。
ここまで相互運用が可能だともうlayout.xmlを書く機会はないと思いました。
機会があるとすれば元々layout.xmlで書かれていてそれをちょっと直すときくらいですかね。(最近それすらも億劫に感じるようになってきたけど)

相互運用APIの資料はこちらを参考にしてください。
https://developer.android.com/jetpack/compose/interop/interop-apis?hl=ja

Luup Developers Blog

Discussion