Wybrać + skopiować tekst w TextView?


106

Czy istnieje sposób, aby zezwolić użytkownikowi na zaznaczanie / kopiowanie tekstu w TextView? Potrzebuję tej samej funkcji EditText, w której można długo nacisnąć kontrolkę i uzyskać wyskakujące opcje zaznacz wszystko / kopiuj, ale potrzebuję, aby kontrolka wyglądała jak TextView.

Próbowałem kilku rzeczy, takich jak ustawienie EditText przy użyciu opcji editable = "none" lub inputType = "none", ale te nadal zachowują oprawione tło EditText, czego nie chcę,

Dzięki

------- Aktualizacja ----------------------

To jest 99%, wszystko czego bym chciał, to żeby hilight selekcji był widoczny (pomarańczowe rzeczy). Poza tym jest dobrze, ale można z tym żyć:

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

Wydaje mi się, że jest to spowodowane przez kursorVisible = "false", ale bez tego kursor jest obecny nawet bez dokonywania wyboru.


Alternatywą byłoby użycie WebView zamiast TextView do wyświetlenia tekstu.
— aleb


Odpowiedzi:


221

android: textIsSelectable działa (przynajmniej w ICS - jeszcze nie sprawdzałem we wcześniejszych wersjach)

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

15
Tylko poziom API 11 i
— nowsze

10
Ale jak skopiować? Mogę zaznaczyć tekst, ale nie pojawiło się menu kopiowania.
— Bagusflyer

1
czy to nie powoduje awarii, kiedy bawisz się kursorami.
— Shubham

1
czy możesz dać mi znać, jak to działa w widoku listy?
— Ramesh Kumar

Piękne, nawet domyślne menu kopiowania utworzone na pasku narzędzi
— Farid

56

Widok tekstu musi być włączony, możliwy do zaznaczenia, longClickable i 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
To najlepsze rozwiązanie.
— Brave

9
Dlaczego textIsSelectableto za mało? to działa dla mnie tylko z tą opcją
— herau

4
Lub możesz użyć textview.setTextIsSelectable(true)w kodzie java.
— berrytchaks

1
Po prostu używam textIsSelectableisdo pracy za mnie
— crgarridos

1
jakoś textIsSelectabledziała w niektórych przypadkach, ale nie w innych. Czasami ten sam układ nie zawsze działa tylko z tekstem textIsSelectable, ale z innym tekstem. Jednak to rozwiązanie nie wydaje się działać lepiej, więc problem może pochodzić z innego miejsca.
— Simon Ninon,

23

Myślę, że mam lepsze rozwiązanie. Zadzwoń
registerForContextMenu(yourTextView);

a Twoja TextViewzostanie zarejestrowana do otrzymywania zdarzeń z menu kontekstowego.

Następnie nadpisz onCreateContextMenuw swoimActivity

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

Mam nadzieję, że pomoże to Tobie i każdemu, kto szuka sposobu na skopiowanie tekstu z pliku TextView


Gdzie to pozwala użytkownikowi wybrać, które fragmenty tekstu mają być kopiowane? Czy nie kopiuje wszystkiego, co nie jest pierwotnym pytaniem?
— James Moore

4
Prawdopodobnie warto zauważyć, że powoduje to natychmiastowe skopiowanie tekstu, niezależnie od tego, czy wybiorą z menu opcję „Kopiuj”. Aby kopiować tylko wtedy, gdy wybrany został odpowiedni element, należałoby również nadpisać onContextItemSelected () lub dodać moduł obsługi kliknięcia do elementu menu.
— Faisal

ClipboardManager.setText(CharSequence text)został uznany za przestarzały na poziomie API 11. Użyj setPrimaryClip(ClipData)zamiast tego. Spowoduje to utworzenie ClippedItem przechowującego podany tekst i ustawienie go jako klipu podstawowego. Nie ma etykiety ani ikony. Dobra lektura na temat kopiowania i wklejania: link
— Marilia

Chcę otworzyć okno dialogowe po zaznaczeniu tekstu. Czy możesz więc przedstawić jakąś sugestię?
— Anand Savjani

9
textview1.setTextIsSelectable(true);

Umożliwi to użytkownikowi zaznaczanie i kopiowanie tekstu po długim kliknięciu lub tak jak zwykle


6

Próbuję zaimplementować to samo, a twoje pytanie pomogło mi poprawnie ustawić układ mojego pliku editext. Więc dziękuję! :)

Wtedy zdałem sobie sprawę, że podświetlenie będzie faktycznie widoczne, jeśli kursor jest włączony. Ale ja tak jak ty nie chcesz widzieć kursora przed długim kliknięciem tekstu, więc ukrywam kursor w pliku layout.xml, tak jak ty, i dodałem Eventlistener dla długiego kliknięcia i wyświetlam kursor tylko wtedy, gdy zaczyna się zaznaczanie .

Więc dodaj odbiorcę do swojej aktywności w sekcji 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;
        }
    });

}

I voilá, na początku nie ma kursora, a długie kliknięcie spowoduje wyświetlenie kursora z granicami zaznaczenia.

Mam nadzieję, że mógłbym pomóc.

Pozdrawiam, fm


5

Próbowałem też zrobić coś podobnego, ale nadal potrzebowałem niestandardowego podejścia z manipulacją podświetlaniem tekstu w TextView. Uruchomiłem podświetlanie i kopiowanie w LongClickakcji.

Oto jak poradziłem sobie z użyciem 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);

oraz funkcja kopiowania:

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

Mam nadzieję, że komuś, kto trafi na to pytanie, będzie pomocne :)


4

Używanie Kotlin programowo (kopiowanie ręczne)

button.setTextIsSelectable(true)

Lub dodaj rozszerzenie właściwości Kotlin

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

Wtedy zadzwoń

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

Używanie Kotlin programowo (automatyczne kopiowanie)

Jeśli chcesz automatycznie kopiować, gdy użytkownik długo naciska na przeglądarkę, jest to wymagany kod podstawowy:

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
}

Możesz dodać, Toastaby potwierdzić, że to się stało

Lub dodaj funkcję rozszerzenia 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
    }
}

Korzystanie z XML (kopiowanie ręczne)

Dodaj to do swojego <TextView>

android:textIsSelectable="true"

UWAGA: Wszystkie te wymagają android:enabled="true"i android:focusable="true", które są wartościami domyślnymi dla pliku TextView.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.