Android开发TextView实现长按复制文本功能的方法

上网查询Android开发实现长按复制文本功能的方法很多,有什么改写系统长按响应,有用EditView控件替换TextView的方法,还有自定义控件什么的,总之都比较麻烦,而且效果也不好。
        其实现在新的Android开发只需要增加一行代码就可以实现这个功能,在布局文件的TextView控件属性中增加这么一句就行:android:textIsSelectable="true"
        但查询资料说只有 android sdk 11(Android 3.0.x)起才支持,v11以下则不行了。我测试了一下在Android4没问题,2.3的系统不行,大家可以根据需求针对性测试下。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是 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 组件,用于显示与用户的交互过程。请注意,示例代码中的一些实现细节可能需要根据您的特定需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值