Compose での自動入力

パスワード マネージャーなどのアプリを利用すると、別のアプリのコンポーネントにおいて、ユーザーが入力したデータを次回以降もそのまま入力できます。このように別のアプリに対して入力を行うアプリは、「自動入力サービス」と呼ばれます。自動入力フレームワークは、アプリと自動入力サービス間の通信を管理します。

認証情報やフォームの入力は時間がかかる作業であり、ミスが発生する可能性があります。自動入力を使用すると、項目に入力する時間を省き、ユーザー入力ミスを最小限に抑えることができます。

わずか数行のコードで、Compose に自動入力を実装できます。この機能には、ユーザーにとって次のようなメリットがあります。

認証情報を入力する

自動入力を使用すると、ユーザーは次の方法で認証情報を入力できます。

  • 自動入力セマンティクスが設定されているフィールドをユーザーがタップすると、自動入力の候補が表示されます。
  • システムは、ユーザーに自動入力候補を表示し、ユーザーが入力した内容に基づいて候補をフィルタします。

認証情報を保存する

ユーザーは、次の方法で自動入力を使用して認証情報を保存できます。

  • システムは保存ダイアログをトリガーします。このダイアログは、ユーザーが自動入力対応フィールドに新しい情報または更新された情報を入力したときに、情報を保存するようユーザーに促します。保存には次の 2 つの方法があります。
    • 明示的(ボタンのクリックなどによって情報を送信する)
    • 暗黙的: ユーザーがページから離れたとき
  • 認証情報プロバイダによっては、フィールドに ContentType.NewPassword が設定されている場合、システムがユーザーに安全なパスワードを提案することがあります。

アプリで自動入力を使用すると、ユーザーが保存したデータを効率的に取得できます。自動入力は、BasicTextField と、そのコンポーネントをベースに構築されたすべてのマテリアル テキスト フィールドを介して、テキスト コンポーネントをサポートします。

自動入力を設定

デバイスまたはエミュレータで Autofill API を使用する前に、[設定] で自動入力を有効にする必要があります。そこで、認証情報を保存する自動入力の認証情報プロバイダを指定できます。

認証情報プロバイダの指定方法を示す設定ページ。
図 1. 認証情報プロバイダを指定する方法を示す設定ページ。

コンテンツ タイプを使用してテキスト フィールドに自動入力を追加する

TextField で自動入力が有効になっていることを示すには、フィールドで受け入れ可能なタイプを使用して ContentType セマンティクスを設定します。これにより、この特定のフィールドに関連するユーザーデータの種類が自動入力サービスに示されます。ContentType.Username を使用して、ユーザーがユーザー名を入力できる TextField を設定します。

ContentType セマンティクスを設定すると、ユーザーはデバイスの認証情報プロバイダにすでに保存されている自動入力情報にアクセスできます。たとえば、ユーザーがノートパソコンの Chrome ブラウザからアプリにログインし、認証情報プロバイダを介してパスワードを保存している場合、認証情報は自動入力によって提供されます。

TextField(
    state = rememberTextFieldState(),
    modifier = Modifier.semantics { contentType = ContentType.Username }
)

複数のタイプの自動入力フィールドを追加する

場合によっては、TextField に複数の ContentType を引き継がせることがあります。たとえば、ログイン フィールドではメールアドレスまたはユーザー名のいずれかを入力できます。+ 演算子を使用して、TextField に複数のコンテンツ タイプを追加できます。

自動入力で保存できるすべてのデータタイプについては、ContentType リファレンスをご覧ください。

TextField(
    state = rememberTextFieldState(),
    modifier = Modifier.semantics {
        contentType = ContentType.Username + ContentType.EmailAddress
    }
)

自動入力でデータを入力する

TextField に ContentType を追加すると、ユーザーが認証情報を入力できるようにするために、他に行う必要はありません。

ユーザーが自動入力対応フィールドをクリックすると、関連するデータが保存されている場合、キーボードの上のツールバーに、認証情報の入力を求めるチップが表示されます。

保存された認証情報を示すテキスト ツールバーのチップ。
図 2 保存された認証情報を示すテキスト ツールバーのチップ。

ナビゲーション中に自動入力でデータを保存する

Compose は、ユーザーがページから移動して入力した認証情報を commit するタイミングを自動的に判断しようとします。フィールドで自動入力が有効になると、ユーザーがページから移動したときに、追加のコードを必要とせずに認証情報が自動的に保存されます。

自動入力でデータを明示的に保存する

自動入力を使用してテキスト フィールドから新しい認証情報を明示的に保存するには、自動入力マネージャーによって自動入力コンテキストを commit(またはキャンセル)する必要があります。ローカルの自動入力マネージャーは、必要に応じて自動入力フレームワークと通信します。ユーザーが入力した認証情報を削除する場合は、AutofillManager.cancel を呼び出して、保留中のデータを保存せずに削除します。

次のスニペットは、ボタンを使用して自動入力でデータを明示的に保存する方法を示しています。

  1. 自動入力マネージャーを保持するローカル変数を作成します。この変数は、次のように取得できます。

    val autofillManager = LocalAutofillManager.current

  2. TextField(s) で、Modifier.semantics を使用して選択したコンテンツ タイプを追加します。

    val autofillManager = LocalAutofillManager.current
    
    Column {
        TextField(
            state = rememberTextFieldState(),
            modifier = Modifier.semantics { contentType = ContentType.NewUsername }
        )
    
        Spacer(modifier = Modifier.height(16.dp))
    
        TextField(
            state = rememberTextFieldState(),
            modifier = Modifier.semantics { contentType = ContentType.NewPassword }
        )
    }

  3. 必要に応じて、ボタンクリックで自動入力コンテキストを commit します。

    val autofillManager = LocalAutofillManager.current
    
    Column {
        TextField(
            state = rememberTextFieldState(),
            modifier = Modifier.semantics { contentType = ContentType.NewUsername },
        )
    
        Spacer(modifier = Modifier.height(16.dp))
    
        TextField(
            state = rememberTextFieldState(),
            modifier = Modifier.semantics { contentType = ContentType.NewPassword },
        )
    
        // Submit button
        Button(onClick = { autofillManager?.commit() }) { Text("Reset credentials") }
    }

Commit は、ユーザーが画面から離れるたびに呼び出されます。[送信] ボタンがナビゲーションにリンクされている場合、Commit を呼び出す必要はありません。[送信] をクリックして保存ダイアログをトリガーする場合は、ここに [Commit] を追加します。

ユーザーがボタンをクリックすると、選択した認証情報プロバイダに認証情報を保存するよう求めるボトムシートが表示されます。

パスワードの保存をユーザーに求めるボトムシート。
図 3. パスワードの保存をユーザーに促すボトムシート。

安全なパスワードの候補を使用して自動入力でデータを保存する

認証情報プロバイダによっては、NewUsername と NewPassword のコンテンツ タイプを使用しているときに、キーボードに [安全なパスワードを提案] ボタンが表示されることがあります。これをクリックすると、認証情報を保存できるボトムシートが表示されます。ユーザーがこのエクスペリエンスを利用できるようにするために、他に実装する必要はありません。

キーボード ツールバーの [安全なパスワードを自動生成] チップ。
図 4. キーボード ツールバーの安全なパスワードを自動生成するチップ。
安全なパスワードを使用するようユーザーに促すボトムシート。
図 5. 安全なパスワードを使用するようユーザーに促すボトムシート。

トラブルシューティング

「保存」のユーザー ジャーニーを呼び出すときに、[後で] を複数回クリックすると、認証情報プロバイダにボトムシートが表示されなくなることがあります。再度有効にして表示するには、[このパスワードを保存しますか?] をブロックしている特定のアプリを削除する必要があります。

パスワードの保存をユーザーに求めるボトムシート。
図 6. パスワードの保存をユーザーに促すボトムシート。

自動入力をさらにカスタマイズする

一般的な自動入力のユーザー ジャーニーでは、自動入力対応コンポーネントに認証情報が入力されると、コンポーネントの色が変わり、ハイライト表示されて、自動入力が正常に完了したことがユーザーに通知されます。

このハイライト色をカスタマイズするには、CompositionLocal を使用して、任意の色を指定します。デフォルトの自動入力ハイライト色は Color(0x4dffeb3b) として定義されています。

val customHighlightColor = Color.Red

CompositionLocalProvider(LocalAutofillHighlightColor provides customHighlightColor) {
    TextField(
        state = rememberTextFieldState(),
        modifier = Modifier.semantics { contentType = ContentType.Username }
    )
}