Seleziona + copia il testo in un TextView?


106

C'è un modo per consentire all'utente di selezionare / copiare il testo in un TextView? Ho bisogno della stessa funzionalità di EditText in cui puoi premere a lungo il controllo e ottenere le opzioni popup di seleziona tutto / copia, ma ho bisogno che il controllo assomigli a TextView.

Ho provato alcune cose come fare in modo che un EditText usi l'opzione editable = "none" o inputType = "none", ma quelle mantengono lo sfondo incorniciato di un EditText, cosa che non voglio,

Grazie

------- Aggiornare ----------------------

Questo è il 99% lì, tutto ciò che vorrei è che la selezione hilight sia visibile (la roba arancione). Oltre a questo è buono, potrebbe convivere con questo però:

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

Immagino che sia causato a causa di cursorVisible = "false" ma senza che il cursore sia presente anche senza che venga effettuata alcuna selezione.


Un'alternativa sarebbe usare un WebView invece di un TextView per visualizzare il testo.
aleb


Risposte:


221

android: textIsSelectable funziona (almeno in ICS - non ho ancora controllato nelle versioni precedenti)

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

15
Solo livello API 11 e superiori
Thierry-Dimitri Roy

10
Ma come copiare? Posso evidenziare il testo, ma non è apparso alcun menu di copia.
Bagusflyer

1
non è questo la causa del crash, quando giocherelli con i cursori.
Shubham

1
puoi farmi sapere come farlo funzionare in listview?
Ramesh Kumar

Bellissimo, anche il menu di copia predefinito creato sulla barra degli strumenti
Farid

56

La visualizzazione del testo deve essere abilitata, attivabile, longClickable e 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" />

1
Questa è la soluzione migliore.
Brave

9
Perché textIsSelectablenon è abbastanza? per me funziona solo con questa opzione
herau

4
Oppure puoi usare textview.setTextIsSelectable(true)nel codice codice java.
berrytchaks

1
textIsSelectableis
Sto

1
in qualche modo, textIsSelectablefunziona per alcuni casi, ma non per altri. A volte, lo stesso layout non funziona sempre solo con textIsSelectable ma con un testo diverso. Tuttavia, questa soluzione non sembra farlo funzionare meglio, quindi il problema potrebbe provenire da qualche altra parte.
Simon Ninon

23

Penso di avere una soluzione migliore. Chiama soltanto
registerForContextMenu(yourTextView);

e TextViewverrai registrato per ricevere gli eventi del menu contestuale.

Quindi sovrascrivi onCreateContextMenunel tuoActivity

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

Spero che questo aiuti te e chiunque altro cerchi un modo per copiare il testo da un file TextView


Dove questo consente all'utente di selezionare quali bit di testo vengono copiati? Non copia semplicemente tutto, che non è la domanda originale?
James Moore

4
Probabilmente è bene notare che questo fa sì che il testo venga copiato immediatamente, indipendentemente dal fatto che selezionino o meno "Copia" dal menu. Per copiare solo quando l'elemento appropriato è stato selezionato, è necessario eseguire l'override anche di onContextItemSelected () o aggiungere un gestore di clic alla voce di menu.
Faisal

ClipboardManager.setText(CharSequence text)è stato deprecato nel livello API 11. Utilizzare setPrimaryClip(ClipData)invece. Questo crea un ClippedItem che contiene il testo dato e lo imposta come clip principale. Non ha etichetta o icona. Buona lettura sul copia-incolla: link
Marilia

Voglio aprire la finestra di dialogo dopo la selezione del testo. Quindi puoi fornire qualche suggerimento per questo?
Anand Savjani

9
textview1.setTextIsSelectable(true);

Ciò consentirà all'utente di selezionare e copiare il testo facendo clic lunghi o come facciamo di solito


6

Sto cercando di implementare lo stesso e la tua domanda mi ha aiutato a impostare correttamente il mio layout editext. Quindi grazie! :)

Poi ho capito che l'evidenziazione sarà effettivamente visibile se il cursore è acceso. Ma mi piace solo che tu non voglia vedere un cursore prima di fare clic sul testo, quindi nascondo il cursore nel file layout.xml proprio come te e ho aggiunto un listener di eventi per un clic prolungato e visualizzo il cursore solo quando inizia una selezione .

Quindi aggiungi l'ascoltatore nella tua attività nella sezione 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;
        }
    });

}

E voilà, nessun cursore all'inizio, e se fai clic a lungo, il cursore appare con i bordi di selezione.

Spero di poterti aiutare.

Saluti, fm


5

Stavo anche cercando di fare qualcosa di simile, ma avevo ancora bisogno di un approccio personalizzato con la manipolazione dell'evidenziazione del testo in TextView. Ho attivato l'evidenziazione e la copia in LongClickazione.

Ecco come sono riuscito a utilizzare 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);

e la funzione di copia:

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

Spero sia utile per qualcuno che finisce su questa domanda :)


4

Utilizzo di Kotlin a livello di programmazione (copia manuale)

button.setTextIsSelectable(true)

Oppure aggiungi un'estensione della proprietà Kotlin

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

Allora chiama

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

Utilizzo di Kotlin a livello di codice (copia automatica)

Se si desidera eseguire la copia automatica quando l'utente preme a lungo sulla visualizzazione, questo è il codice di base richiesto:

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
}

Puoi aggiungere un Toastper confermare che è successo

Oppure aggiungi una funzione di estensione 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
    }
}

Utilizzo di Xml (copia manuale)

Aggiungi questo al tuo <TextView>

android:textIsSelectable="true"

NOTA: Tutti questi richiedono android:enabled="true"e android:focusable="true", che sono i valori predefiniti per un file TextView.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.