可点击修饰符在Jetpack Compose中不起作用。

huangapple go评论114阅读模式
英文:

Clickable modifier not working in Jetpack Compose

问题

我正在尝试在Modifier上实现一个扩展函数,该函数可以轻松地将点击操作设置为可组合项,以将特定文本复制到剪贴板:

以下是代码:

/**
 * @param textCopied 要复制到剪贴板的文本。
 * @param clipLabel 用于标识textCopied的标签。可以为null。
 *
 * Android 13在本地复制文本到剪贴板时会显示一条消息,因此我们不需要用户知道已经发生了复制以避免重复消息。
 * 此方法将给定的textCopied复制到剪贴板,并在用户的Android版本低于13时显示一个toast。
 * 更多信息请参见:https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications
 */
fun Context.copyTextToClipboardAndNotify(textCopied: String, clipLabel: String? = null) {
    val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
    // 设置剪贴板文本。
    clipboardManager.setPrimaryClip(ClipData.newPlainText(clipLabel, textCopied))
    // 仅在Android 12及更低版本上显示toast。
    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2)
        Toast.makeText(this, getString(R.string.text_copied_to_clipboard_S, textCopied), Toast.LENGTH_SHORT).show()
}

/**
 * @param textToCopy 点击可组合项时要复制的文本。
 *
 * 为可组合项设置点击操作,将提供的textToCopy复制到剪贴板。
 */
fun Modifier.copyOnClick(textToCopy: String?) = composed {
    val context = LocalContext.current
    textToCopy?.let {
        clickable {
            context.copyTextToClipboardAndNotify(it)
        }
    }
    this
}

这是我在视图中使用它的方式:

Column(
    modifier = Modifier.copyOnClick(username),
    horizontalAlignment = Alignment.CenterHorizontally
) { 
    // 列内容在这里
}

然而,这根本不起作用。在调试时,我可以看到调试器在clickable{}断点处停止,但当我点击视图时,它实际上并没有进入函数。

所以,为了尝试它,我将我的视图更改为:

val context = LocalContext.current
Column(
    modifier = Modifier.clickable { context.copyTextToClipboardAndNotify(username) },
    horizontalAlignment = Alignment.CenterHorizontally
) {
   // 列内容在这里
}

这样就可以了!但显然比我想要实现的方式要不那么简洁。

为什么我的函数不能正常工作?我怀疑这与他们建议在Modifier工厂中使用的composed函数有关。我不确定它具体做了什么,但似乎搞乱了事情。但我需要它来访问上下文。

英文:

I am trying to implement an extension function on Modifier that would easily allow me to set a click action to a composable that would copy a specific text to the clipboard:

Here it is:

/**
 * @param textCopied Text to be copied to the clipboard.
 * @param clipLabel Label to identify the textCopied. Can be null.
 *
 * Android 13 shows a message when text has been copied to the clipboard natively, so we don&#39;t need to user that it has happened to avoid duplicate messages.
 * This method copies the given textCopied to the clipboard and shows a toast if the user is on an Android version lower than 13.
 * More info on: https://developer.android.com/develop/ui/views/touch-and-input/copy-paste#duplicate-notifications
 * */
fun Context.copyTextToClipboardAndNotify(textCopied: String, clipLabel: String? = null) {
    val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
    // When setting the clipboard text.
    clipboardManager.setPrimaryClip(ClipData.newPlainText(clipLabel, textCopied))
    // Only show a toast for Android 12 and lower.
    if (Build.VERSION.SDK_INT &lt;= Build.VERSION_CODES.S_V2)
        Toast.makeText(this, getString(R.string.text_copied_to_clipboard_S, textCopied), Toast.LENGTH_SHORT).show()
}

/**
 * @param textToCopy Text to be copied when composable is clicked.
 *
 * Sets a click action to the composable to copy the provided textToCopy to the clipboard.
 */
fun Modifier.copyOnClick(textToCopy: String?) = composed {
    val context = LocalContext.current
    textToCopy?.let {
        clickable {
            context.copyTextToClipboardAndNotify(it)
        }
    }
    this
}

And this is how I use it in the view:

    Column(
        modifier = Modifier.copyOnClick(username),
        horizontalAlignment = Alignment.CenterHorizontally
    ) { 
        // Column content here
      }

This is not working at all though. When debugging, I can see that the debugger stops at the clickable{} breakpoint but never really enters the function when I click the view.

So, to try it out, I changed my view to

        val context = LocalContext.current
        Column(
            modifier = Modifier.clickable { context.copyTextToClipboardAndNotify(username) },
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
           // Column content here
          }

And this worked! But it's obviously way less clean than what I want to achieve.

Why is my function not working properly? I suspect it's something with this composed function that they recommend using with Modifiers factories. I don't know exactly what it's doing, but seems to be messing things up. But I need it to access the context.

答案1

得分: 1

fun Modifier.copyOnClick(textToCopy: String?) = composed {
val context = LocalContext.current
textToCopy?.let {
clickable {
context.copyTextToClipboardAndNotify(it)
}
} ?: this

}

问题是你总是返回 Modifier,而不是 clickable。根据空值检查返回应该解决这个问题。

英文:
fun Modifier.copyOnClick(textToCopy: String?) = composed {
    val context = LocalContext.current
    textToCopy?.let {
        clickable {
            context.copyTextToClipboardAndNotify(it)
        }
    }
    this
}

problem is you always return Modifier, never the clickable. Returning based on null check should solve the issue.

fun Modifier.copyOnClick(textToCopy: String?) = composed {
    val context = LocalContext.current
    textToCopy?.let {
        clickable {
            context.copyTextToClipboardAndNotify(it)
        }
    }?:this
   
}

huangapple
  • 本文由 发表于 2023年8月9日 17:44:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76866493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定