Select + copy text in a TextView?

Is there a way to allow the user to select / copy text in a TextView? I need the same functionality of EditText where you can long-press the control and get the popup options of select all / copy, but I need the control to look like a TextView.

Tried a few things like making an EditText use the editable="none" option or inputType="none", but those still retain the framed background of an EditText, which I don't want,

Thanks

------- Update ----------------------

This is 99% there, all I'd want is for the selection hilight to be visible (the orange stuff). Other than that it's good, could live with this though:

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

I guess it's being caused because of cursorVisible="false" but without that the cursor is present even without any selection being made.

95786 次浏览

I think I have a better solution. Just call
registerForContextMenu(yourTextView);

and your TextView will be registered for receiving context menu events.

Then override onCreateContextMenu in your Activity

@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());
}

Hope this helps you and anyone else looking for a way to copy text from a TextView

android:textIsSelectable works (at least in ICS - I haven't yet checked in earlier versions)

<TextView
android:id="@+id/deviceIdTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:text="" />

I'm trying to implement the same, and your question helped me to set my editext layout correctly. So Thanks! :)

Then I realized, that the highlight will actually be visible if the cursor is on. But I just like you do not want to see a cursor before long clicking on the text, so I hide the cursor in the layout.xml file just like you, and added an eventlistener for long click and display the cursor only when a selection starts.

So add the listener in your Activity in the onCreate section:

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;
}
});


}

And voilá, no cursor at the beginning, and if you long-click, the cursor appears with the selection boundaries.

I hope I could help.

Cheers, fm

Just use this simple library: GitHub: Selectable TextView

Text View needs to be enabled, focusable, longClickable and textIsSelectable

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

I was also trying to do something similar but still needed a custom approach with manipulation of highlighting of text in TextView. I triggered highlight and copying on LongClick action.

This is how I managed using 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);

and the copy function:

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();
}

I hope it's helpful for someone who ends up on this question :)

textview1.setTextIsSelectable(true);

This will enable user to select and copy text on long clicking or as we do usually

Using Kotlin Programmatically (Manual Copy)

button.setTextIsSelectable(true)

Or, add a Kotlin property extension

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

Then call

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

Using Kotlin Programmatically (Auto-Copy)

If you want to auto-copy when user long-presses you view, this is the base code required:

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
}

You may want to add a Toast to confirm it happened

Or, add a Kotlin extension function

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
}
}

Using Xml (Manual Copy)

Add this to your <TextView>

android:textIsSelectable="true"

NOTE: All of these require android:enabled="true" and android:focusable="true", which are the default values for a TextView.

I have found it doesn't work the first time I double click, but it works there after ( at least in android 11). This told me it needed to get focus. So, in the onCreate event, I first made the text view selectable, then I requested the focus to shift to the text view. Now I'm not saying the text view can lose focus and the first attempted selection will work. Not guaranteed. What is guaranteed is once it has focus, it'll work every time until it loses focus again. Don't forget about androids animations. So allow at least a half second for the non overridable animation to play out when the keyboard is hiding.

// In onCreate


TextView1.setTextIsSelectable( true );
// Allow animations to play out.


timer = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView1.requestFocus();
}
});
}
};
_timer.schedule(timer, (int)(1000));
}