Android开发 compose组件 实现长按Text弹出系统的文本操作菜单 帮我写kotlin代码
时间: 2023-06-16 19:06:41 浏览: 222
好的,这里是 Kotlin 代码示例:
```kotlin
import androidx.compose.foundation.Text
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.detectTapOrLongPress
import androidx.compose.foundation.gestures.waitForUpOrCancellation
import androidx.compose.foundation.layout.Row
import androidx.compose.material.AlertDialog
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getSystemService
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.text.style.ClickableSpan
import android.view.ContextMenu
import android.view.MenuItem
import android.view.View
import android.widget.TextView
@Composable
fun LongPressText(
text: String,
modifier: Modifier = Modifier
) {
val context = LocalContext.current
val showDialog = remember { mutableStateOf(false) }
val dialogText = remember { mutableStateOf("") }
fun onContextMenuClick(item: MenuItem): Boolean {
when (item.itemId) {
1 -> {
val clipboard = getSystemService(context, ClipboardManager::class.java)
val clip = android.content.ClipData.newPlainText("text", dialogText.value)
clipboard?.setPrimaryClip(clip)
}
2 -> {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, dialogText.value)
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
context.startActivity(shareIntent)
}
}
return true
}
fun showContextMenu(view: View, text: String) {
val menu = ContextMenu(context)
menu.apply {
add(0, 1, 0, "复制")
add(0, 2, 0, "分享")
setOnMenuItemClickListener { item -> onContextMenuClick(item) }
}
dialogText.value = text
menu.show(view, view.x.toInt(), view.y.toInt())
}
val annotatedString = buildAnnotatedString {
append(text)
addStyle(SpanStyle(color = Color.Blue), 0, text.length)
addStringAnnotations(text = text, onClick = {
showDialog.value = true
dialogText.value = it
}, onLongClick = {
val textView = TextView(context)
textView.text = it
textView.setTextColor(ContextCompat.getColor(context, android.R.color.black))
textView.textSize = 18f
showContextMenu(textView, it)
})
}
Text(text = annotatedString, modifier = modifier)
if (showDialog.value) {
AlertDialog(
onDismissRequest = { showDialog.value = false },
title = { Text(text = "闲聊") },
text = { Text(text = dialogText.value) },
confirmButton = {
Button(onClick = {
showDialog.value = false
}) {
Text("关闭")
}
}
)
}
}
fun AnnotatedString.Builder.addStringAnnotations(text: String, onClick: (String) -> Unit, onLongClick: (String) -> Unit) {
var startIndex = 0
var spaceIndex = text.indexOf(' ', startIndex)
var newestSpace = text.length
while (startIndex < text.length) {
if (spaceIndex == -1) spaceIndex = text.length
val word = text.substring(startIndex, spaceIndex)
val clickableSpan = object : ClickableSpan() {
override fun onClick(widget: View) {
onClick(word)
}
}
val range = startIndex until spaceIndex
val color = Color.Blue
val style = SpanStyle(color = color, textDecoration = null, background = null, fontWeight = null)
addStyle(style, range.start, range.end)
addStringAnnotation("Clickable", word, clickableSpan)
if (word != text.substring(range.last)) {
addStringAnnotation("LongClickable", word, LongClickableSpan(onLongClick))
}
newestSpace = spaceIndex
startIndex = spaceIndex + 1
spaceIndex = text.indexOf(' ', startIndex)
}
}
class LongClickableSpan(private val onClick: (String) -> Unit) : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
ds.color = ds.linkColor // changes the actual color of the clickable text, default is link blue
ds.isUnderlineText = false // removes the underline from the clickable text, default is true
}
override fun onClick(view: View) {
val textView = TextView(view.context)
textView.text = (view as TextView).text
textView.setTextColor(view.textColors)
textView.textSize = view.textSize
onClick(view.text.toString())
}
}
```
这个示例代码演示了如何使用 Jetpack Compose 开发 Android 应用程序,并在 Text 组件中实现长按文本菜单。这里使用了 AnnotatedString 组件来渲染富文本和交互元素。同时,示例代码还包含了一个 AlertDialog 组件,用于显示与用户的交互过程。请注意,示例代码中的一些实现细节可能需要根据您的特定需求进行修改。
阅读全文