🐻‍❄️

Jetpack Compose で Clipboard を利用したコピー&ペーストを実装する

2021/11/13に公開約4,000字

はじめに

Jetpack Compose で Clipboard を利用する方法について調べてコピー&ペーストの機能を実装してみる。

セットアップ

本記事では以下の環境で動作確認をしています。

  • Kotlin v1.5.10
  • Jetpack Compose v1.0.1
  • Android Studio Bumblebee | 2021.1.1 Canary 10

ClipboardManager を取得する

Jetpack Compose の CompositionLocalLocalClipboardManager にて ClipboardManager を取得できるようになっている。

val clipboardManager: ClipboardManager = LocalClipboardManager.current

この ClipboardManager は androidx.compose.ui.platform されており Jetpack Compose ではこのインタフェースで定義されるメソッドを利用してクリップボードの操作をする。

interface ClipboardManager {
    /**
     * This method put the text into the Clipboard.
     *
     * @param annotatedString The [AnnotatedString] to be put into Clipboard.
     */
    fun setText(annotatedString: AnnotatedString)

    /**
     * This method get the text from the Clipboard.
     *
     * @return The text in the Clipboard.
     * It could be null due to 2 reasons: 1. Clipboard is empty; 2. Cannot convert the
     * [CharSequence] text in Clipboard to [AnnotatedString].
     */
    fun getText(): AnnotatedString?
}

ClipboardManager でコピー&ペーストを実現する

ClipboardManager を取得して以下の仕様でコピー&ペーストをする UI を実装してみる。

  • TextField にある文字列を Button をタップでクリップボードにコピーする
  • Button をタップでクリップボードの文字列を TextField にペーストする
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val clipboardManager: ClipboardManager = LocalClipboardManager.current
            var editText: String by remember { mutableStateOf("") }

            Column(modifier = Modifier.fillMaxWidth().wrapContentHeight()) {
                TextField(
                    value = editText,
                    modifier = Modifier.fillMaxWidth().padding(8.dp),
                    onValueChange = { editText = it }
                )

                Button(
                    modifier = Modifier.fillMaxWidth().padding(8.dp),
                    onClick = { clipboardManager.setText(AnnotatedString(editText)) }
                ) {
                    Text(text = "Copy Text")
                }

                Button(
                    modifier = Modifier.fillMaxWidth().padding(8.dp),
                    onClick = { editText = clipboardManager.getText()?.text ?: "" }
                ) {
                    Text(text = "Paste Text")
                }
            }
        }
    }
}

実装した UI を利用してコピーしてみる。

demo1.gif

実装した UI を利用してペーストしてみる。

demo2.gif

コピーもペーストの処理も問題なく動いています。

というように ClipboardManager を利用すればクリップボードの操作が簡単にできるようになっている。

おわりに

LocalContext を利用して SystemService から旧来の ClipboardManager を取得する方法もあるみたいですが JetpackCompose では LocalClipboardManager を利用して取得するのが正しい方法です。なのでクリップボードを操作するときには LocalClipboardManager から取得した ClipboardManager を利用して操作しましょう。

Discussion

ログインするとコメントできます