在 TextView 中选择 + 复制文本?

Posted

技术标签:

【中文标题】在 TextView 中选择 + 复制文本?【英文标题】:Select + copy text in a TextView? 【发布时间】:2011-08-26 22:01:20 【问题描述】:

有没有办法让用户在 TextView 中选择/复制文本?我需要与 EditText 相同的功能,您可以在其中长按控件并获取全选/复制的弹出选项,但我需要控件看起来像 TextView。

尝试了一些方法,例如让 EditText 使用 editable="none" 选项或 inputType="none",但这些仍然保留了 EditText 的框架背景,这是我不想要的,

谢谢

------- 更新 ----------

这是 99%,我想要的只是选择高亮可见(橙色的东西)。除此之外它很好,但可以忍受这个:

<EditText 
  android:layout_
  android:layout_
  android:editable="false"
  style="?android:attr/textViewStyle"
  android:textColor="@color/white"
  android:textAppearance="@android:style/TextAppearance.Medium"
  android:cursorVisible="false"
  android:background="@null" />

我猜这是因为 cursorVisible="false" 造成的,但即使没有进行任何选择,光标也存在。

【问题讨论】:

另一种方法是使用 WebView 而不是 TextView 来显示文本。 [***.com/questions/18042308/… [1]: ***.com/questions/18042308/… ***.com/questions/18042308/… 【参考方案1】:

android:textIsSelectable 有效(至少在 ICS 中 - 我还没有检查过早期版本)

<TextView
    android:id="@+id/deviceIdTV"
    android:layout_
    android:layout_
    android:textIsSelectable="true"
    android:text="" />

【讨论】:

但是如何复制呢?我可以突出显示文本,但没有出现复制菜单。 当您摆弄光标时,这不会导致崩溃。 你能告诉我如何让它在列表视图中工作吗? 工具栏上创建的漂亮,甚至是默认的复制菜单 @ZhouHao 我应用这个并且可以很好地复制粘贴。【参考方案2】:

Text View 需要启用,可聚焦,longClickable 和 textIsSelectable

<TextView
    android:layout_
    android:layout_
    android:text=""
    android:id="@+id/pwTextView"
    android:enabled="true"
    android:textIsSelectable="true"
    android:focusable="true"
    android:longClickable="true" />

【讨论】:

这是最好的解决方案。 为什么textIsSelectable不够用?只有这个选项对我有用 或者可以在代码java代码中使用textview.setTextIsSelectable(true) 只需使用textIsSelectableis 为我完成这项工作 不知何故,textIsSelectable 适用于某些情况,但不适用于其他情况。有时,相同的布局并不总是适用于 textIsSelectable 而是不同的文本。但是,此解决方案似乎并不能使其更好地工作,因此问题可能来自其他地方。【参考方案3】:

我认为我有更好的解决方案。 只需致电registerForContextMenu(yourTextView);

您的TextView 将被注册以接收上下文菜单事件。

然后在您的Activity 中覆盖onCreateContextMenu

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) 
    //user has long pressed your TextView
    menu.add(0, v.getId(), 0, "text that you want to show in the context menu - I use simply Copy");

    //cast the received View to TextView so that you can get its text
    TextView yourTextView = (TextView) v;

    //place your TextView's text in clipboard
    ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
    clipboard.setText(yourTextView.getText());

希望这可以帮助您和其他任何想从TextView 复制文本的人

【讨论】:

这允许用户在哪里选择要复制的文本位?它不只是复制所有内容,这不是原始问题吗? 请注意,这会导致文本立即被复制,无论他们是否从菜单中选择“复制”。为了仅在选择适当的项目时进行复制,您还需要覆盖 onContextItemSelected(),或者向菜单项添加点击处理程序。 ClipboardManager.setText(CharSequence text) 在 API 级别 11 中已弃用。请改用 setPrimaryClip(ClipData)。这将创建一个包含给定文本的 ClippedItem 并将其设置为主剪辑。它没有标签或图标。关于复制粘贴的好读物:link 我想在文本选择后打开对话框。那么您能提供任何建议吗?【参考方案4】:
textview1.setTextIsSelectable(true);

这将使用户能够在长按时或像我们通常那样选择和复制文本

【讨论】:

【参考方案5】:

我正在尝试实现相同的功能,您的问题帮助我正确设置了 editext 布局。那谢谢啦! :)

然后我意识到,如果光标打开,突出显示实际上是可见的。 但是我就像您不希望在长按文本之前看到光标,所以我像您一样将光标隐藏在 layout.xml 文件中,并添加了一个用于长按的事件监听器并仅在选择开始时显示光标.

所以在你的 Activity 的 onCreate 部分添加监听器:

public TextView htmltextview;

public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ...

    htmltextview.setOnLongClickListener(new OnLongClickListener()

        public boolean onLongClick(View v) 
            htmltextview.setCursorVisible(true);
            return false;
        
    );


瞧,开头没有光标,如果你长按,光标会出现在选择边界处。

希望我能帮上忙。

干杯, 调频

【讨论】:

【参考方案6】:

以编程方式使用 Kotlin(手动复制)

button.setTextIsSelectable(true)

或者,添加 Kotlin 属性扩展

var TextView.selectable
    get() = isTextSelectable
    set(value) = setTextIsSelectable(value)

然后调用

textview.selectable = true
// or
if (textview.selectable)  ...

以编程方式使用 Kotlin(自动复制)

如果您想在用户长按查看时自动复制,这是所需的基本代码:

myView.setOnLongClickListener   
    val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
    val clip = ClipData.newPlainText("Copied String", myString)
    clipboardManager.setPrimaryClip(clip)
    true // Or false if not consumed

您可能需要添加 Toast 以确认它发生了

或者,添加一个 Kotlin 扩展函数

myView.copyOnHold() // pass custom string to not use view contents

fun TextView.copyOnHold(customText: String? = null) 
    setOnLongClickListener 
        val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
        val clip = ClipData.newPlainText("Copied String", customText ?: text)
        clipboardManager.setPrimaryClip(clip)
        true // Or false if not consumed
    

使用 Xml(手动复制)

将此添加到您的&lt;TextView&gt;

android:textIsSelectable="true"

注意:所有这些都需要android:enabled="true"android:focusable="true",它们是TextView 的默认值。

【讨论】:

【参考方案7】:

我也在尝试做类似的事情,但仍然需要一种自定义方法来处理 TextView 中文本的突出显示。我在LongClick 操作上触发了突出显示和复制。

这就是我使用SpannableString 管理的方式:

SpannableString highlightString = new SpannableString(textView.getText());
highlightString.setSpan(new BackgroundColorSpan(ContextCompat.getColor(getActivity(), R.color.gray))
            , 0, textView.getText().length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(highlightString);
copyToClipboard(urlToShare);

和复制功能:

public void copyToClipboard(String copyText) 
    ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clip = ClipData.newPlainText("url", copyText);
    clipboard.setPrimaryClip(clip);
    Toast toast = Toast.makeText(getActivity(), "Link is copied", Toast.LENGTH_SHORT);
    toast.show();

我希望它对最终解决这个问题的人有所帮助:)

【讨论】:

【参考方案8】:

只需使用这个简单的库: GitHub: Selectable TextView

【讨论】:

以上是关于在 TextView 中选择 + 复制文本?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过在textView中按long来选择和复制文本? [重复]

文本可以在 textView 中选择但不可编辑

文本选择能够但不能在textView中编辑

textViewDidChangeSelection 方法认为 textView.text 为空

android 怎样在程序中设置TextView中显示的值

如何把Tex格式的文件转化为Word 格式