从Android TextView复制文本

16

我有一个包含的。

我想要启用长按行为,类似于,它会显示默认上下文菜单,包括"全选"、"剪切"、"复制"等项。

是否有一种简单的方法可以为启用此功能?


目前我正在注册一个上下文菜单,并使用剪贴板管理器复制TextView的整个文本。但似乎应该有一种默认的方法来完成这个任务。 - Erdal
实际上,上下文菜单是为此而设计的。您可以随意自定义它。您还可以查看AlertDialog类。通常不用于此目的,但您可以通过长按调用它。但是,如果我没记错的话,您最多只能使用3个按钮。 - Sephy
还有一件事,我不知道是否建议这样做,但您可以尝试将您的列表视图放在一个帧布局中,并添加另一个视图/布局,但其可见性为gone。当单击列表中的元素并更新其内容时,将其可见性设置为visible。 - Sephy
你是如何解决这个问题的? - pandre
6个回答

21

我认为我有一个解决方案。只需调用
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 复制文本的人。


感谢您的帖子,这正是我需要的API 2.1。起初它没有起作用,后来发现我必须从清单XML中删除以下内容:android:configChanges="keyboardHidden"。 - Alan
4
它确实有效。虽然它复制的文本是在用户实际点击复制之前进行的。这可能会让人感到困惑并覆盖他们的剪贴板。另一种方法是在onContextItemSelected中执行复制操作。您已经将菜单选项ID设置为视图ID,但没有使用它。此外,请确保在针对API 11以下的设备进行示例时导入android.text.ClipboardManager而不是android.content.ClipboardManager。 - Mike Venzke
当菜单项被点击时,我该如何进行复制? - Raj Suvariya
MenuItem item = menu.add(0, v.getId(), 0, "复制"); item.setOnMenuItemClickListener(e->{ //将接收到的View强制转换为TextView,以便获取其文本 TextView textView = (TextView) v; //将TextView的文本放入剪贴板 ClipboardManager clipboard = (ClipboardManager)requireContext().getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setPrimaryClip(ClipData.newPlainText("Text", textView.getText().toString())); return true; }); - undefined

8
要让用户能够复制TextView的一部分或全部内容并粘贴到其他地方,可以将XML属性{@link android.R.styleable#TextView_textIsSelectable android:textIsSelectable}设置为"true"或调用{@link #setTextIsSelectable setTextIsSelectable(true)}方法。

这是唯一最简单和正确的解决方案。谢谢。 - Vitaly

7
实际上,您不必自己开发此功能。您只需要使用EditText而不是TextView,同时将EditText的android:editable设置为false即可。我的代码在这里:
R.layout.edittext.xml
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="40dip"
android:editable="false" 
android:background="@null"
android:textColor="#FFFFFF"/>

ListItemCopyTextActivity.java

public class ListItemCopyTextActivity extends Activity {    

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LinearLayout ll = new LinearLayout(this);
    ListView lv = new ListView(this);

    String[] values = new String[15];
    for (int i = 0; i < 15; i++) {
        values[i] = "ListItem NO." + i;
    }

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            R.layout.edittext, values);
    lv.setAdapter(adapter);

    ll.addView(lv, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

    setContentView(ll);

    }
}

您可以长按该项,选择“选择文本”,“复制”,“剪切”,“粘贴”等操作。

2
对我不起作用。如果editable为false,我会得到“TextView不支持文本选择。操作模式已取消。”使用android:textIsSelectable对我来说是一个好的解决方案。 - Edwin Evans

1
你可能想在你的ListView上注册一个onItemLongClickListener,然后根据所选项目,为用户提供你选择的任何选项。

0

这是解决方案

 <TextView
        android:id="@+id/textID"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:clickable="true"
        android:focusable="true"
        android:text="Terms and Conditions"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

重写 setOnLongClickListener

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    textID.setTextIsSelectable(true)
    textID. setOnLongClickListener {
       val clipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
       val clip = ClipData.newPlainText("Copied String",  textID.text)
       clipboardManager.setPrimaryClip(clip)
       true // Or false if not consumed
   }
}

预期的行为将类似于下面的图像

enter image description here


只需在您的TextView布局中添加android:textIsSelectable="true"即可。非常简单!无需更改其他布局或代码行。 - Vitaly

0

我有一个解决方案,但它可能并不是非常有用。

只需使用这种方法:

txtDescDetail.setCursorVisible(true);

我希望能够做到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接