Pilih + salin teks di TextView?

106

Apakah ada cara untuk mengizinkan pengguna memilih / menyalin teks dalam TextView? Saya memerlukan fungsionalitas EditText yang sama di mana Anda dapat menekan lama kontrol dan mendapatkan opsi popup pilih semua / salin, tetapi saya memerlukan kontrol agar terlihat seperti TextView.

Mencoba beberapa hal seperti membuat EditText menggunakan opsi editable = "none" atau inputType = "none", tetapi hal itu masih mempertahankan latar belakang berbingkai dari EditText, yang tidak saya inginkan,

Terima kasih

------- Perbarui ----------------------

Ini 99% di sana, yang saya inginkan adalah agar pemilihan hilight terlihat (hal-hal oranye). Selain itu bagus, bisa hidup dengan ini:

<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" />

Saya kira itu disebabkan karena cursorVisible = "false" tetapi tanpa itu kursor hadir bahkan tanpa pemilihan apa pun.

pengguna291701
sumber
Alternatifnya adalah dengan menggunakan WebView daripada TextView untuk menampilkan teks.
aleb

Jawaban:

221

android: textIsSelectable berfungsi (setidaknya di ICS - saya belum memeriksa di versi sebelumnya)

<TextView
    android:id="@+id/deviceIdTV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textIsSelectable="true"
    android:text="" />
Milind
sumber
15
Hanya API Level 11 dan lebih tinggi
Thierry-Dimitri Roy
10
Tapi bagaimana cara menyalin? Saya dapat menyorot teks, tetapi tidak ada menu salin yang muncul.
Bagusflyer
1
Bukankah ini yang menyebabkan crash, ketika Anda mengutak-atik kursor.
Shubham
1
dapatkah Anda memberi tahu saya cara membuatnya berfungsi di listview?
Ramesh Kumar
Indah, bahkan menu salin default dibuat di toolbar
Farid
56

Tampilan Teks harus diaktifkan, dapat difokuskan, dapat diklik panjang dan teksIsSeleksi

<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" />
skd
sumber
1
Ini solusi terbaik.
Berani
9
Kenapa textIsSelectabletidak cukup? ini bekerja untuk saya dengan hanya opsi ini
herau
4
Atau Anda dapat menggunakan textview.setTextIsSelectable(true)kode java kode.
berrytchaks
1
Hanya menggunakan textIsSelectableismelakukan pekerjaan untuk saya
crgarridos
1
entah bagaimana, textIsSelectableberfungsi untuk beberapa kasus, tetapi tidak untuk yang lain. Terkadang, tata letak yang sama tidak selalu berfungsi hanya dengan textIsSelectable tetapi dengan teks yang berbeda. Namun, solusi ini tampaknya tidak membuatnya berfungsi lebih baik, jadi masalahnya mungkin berasal dari tempat lain.
Simon Ninon
23

Saya rasa saya punya solusi yang lebih baik. Telepon saja
registerForContextMenu(yourTextView);

dan Anda TextViewakan terdaftar untuk menerima acara menu konteks.

Kemudian menimpa onCreateContextMenudi AndaActivity

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

Semoga ini bisa membantu Anda dan orang lain yang mencari cara untuk menyalin teks dari file TextView

pandre
sumber
Di mana ini memungkinkan pengguna untuk memilih potongan teks mana yang disalin? Bukankah itu hanya menyalin semuanya, yang bukan pertanyaan aslinya?
James Moore
4
Sebaiknya perhatikan bahwa ini menyebabkan teks segera disalin, terlepas dari apakah mereka memilih "Salin" dari menu atau tidak. Untuk menyalin hanya ketika item yang sesuai dipilih, Anda juga perlu mengganti onContextItemSelected (), atau menambahkan handler klik ke item menu.
Faisal
ClipboardManager.setText(CharSequence text)sudah usang di API level 11. Gunakan setPrimaryClip(ClipData)sebagai gantinya. Ini membuat ClippedItem yang menahan teks yang diberikan dan menetapkannya sebagai klip utama. Tidak ada label atau ikon. Bacaan yang baik tentang salin-tempel: tautan
Marilia
Saya ingin membuka dialog setelah pemilihan teks. Jadi bisakah Anda memberikan saran untuk itu?
Anand Savjani
9
textview1.setTextIsSelectable(true);

Ini akan memungkinkan pengguna untuk memilih dan menyalin teks dengan mengklik lama atau seperti yang biasa kita lakukan

Amitoj
sumber
6

Saya mencoba menerapkan hal yang sama, dan pertanyaan Anda membantu saya menyetel tata letak teks edit saya dengan benar. Jadi terima kasih! :)

Kemudian saya menyadari, bahwa highlight sebenarnya akan terlihat jika kursor menyala. Tapi saya suka Anda tidak ingin melihat kursor sebelum lama mengklik teks, jadi saya menyembunyikan kursor di file layout.xml seperti Anda, dan menambahkan eventlistener untuk klik lama dan menampilkan kursor hanya saat pemilihan dimulai .

Jadi tambahkan pendengar di Aktivitas Anda di bagian 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;
        }
    });

}

Dan voila, tidak ada kursor di awal, dan jika Anda mengklik lama, kursor muncul dengan batas pilihan.

Saya harap saya bisa membantu.

Salam, fm

fmarton
sumber
5

Saya juga mencoba melakukan sesuatu yang serupa tetapi masih membutuhkan pendekatan khusus dengan manipulasi penyorotan teks di TextView. Saya memicu sorotan dan menyalin LongClicktindakan.

Beginilah cara saya berhasil menggunakan 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);

dan fungsi salin:

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

Saya harap ini membantu seseorang yang akhirnya menjawab pertanyaan ini :)

Wahib Ul Haq
sumber
4

Menggunakan Kotlin Secara Terprogram (Salinan Manual)

button.setTextIsSelectable(true)

Atau, tambahkan ekstensi properti Kotlin

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

Kemudian panggil

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

Menggunakan Kotlin Secara Terprogram (Salin Otomatis)

Jika Anda ingin menyalin otomatis ketika pengguna menekan lama Anda melihat, ini adalah kode dasar yang diperlukan:

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
}

Anda mungkin ingin menambahkan Toastuntuk mengonfirmasi hal itu terjadi

Atau, tambahkan fungsi ekstensi 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
    }
}

Menggunakan Xml (Salinan Manual)

Tambahkan ini ke Anda <TextView>

android:textIsSelectable="true"

CATATAN: Semua ini memerlukan android:enabled="true"dan android:focusable="true", yang merupakan nilai default untuk a TextView.

Gibolt
sumber