Выбрать + скопировать текст в TextView?


106

Есть ли способ разрешить пользователю выбирать / копировать текст в TextView? Мне нужна та же функциональность, что и EditText, где вы можете долго нажимать на элемент управления и получать всплывающие варианты выбора всех / копирования, но мне нужно, чтобы элемент управления выглядел как TextView.

Пробовал несколько вещей, например, заставить EditText использовать параметр editable = "none" или inputType = "none", но они по-прежнему сохраняют рамочный фон EditText, который мне не нужен,

Спасибо

------- Обновить ----------------------

Здесь 99%, все, что я хочу, - это чтобы подсветка выделения была видна (оранжевый материал). В остальном это хорошо, но с этим можно жить:

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

Я предполагаю, что это происходит из-за cursorVisible = "false", но без этого курсор присутствует даже без выбора.


Альтернативой было бы использование WebView вместо TextView для отображения текста.
алеб


Ответы:


221

android: textIsSelectable работает (по крайней мере, в ICS - я еще не проверял в более ранних версиях)

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

15
Только API уровня 11 и выше
Тьерри-Димитри Рой,

10
Но как скопировать? Я могу выделить текст, но меню копирования не появилось.
Bagusflyer

1
Разве это не вызывает сбой, когда вы возитесь с курсорами.
Шубхам

1
вы можете дать мне знать, как заставить его работать в режиме списка?
Рамеш Кумар,

Красивое, даже стандартное меню копирования, созданное на панели инструментов
Фарид

56

Text View должен быть включен, фокусируемый, longClickable и 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
Это лучшее решение.
Brave

9
Почему textIsSelectableне хватает? у меня работает только с этой опцией
herau

4
Или вы можете использовать textview.setTextIsSelectable(true)в коде java code.
berrytchaks

1
Просто использую, textIsSelectableisсделай работу за меня
crgarridos

1
как-то textIsSelectableработает для одних случаев, но не для других. Иногда один и тот же макет не всегда работает только с textIsSelectable, а с другим текстом. Однако это решение, похоже, не улучшает его работу, поэтому проблема может исходить откуда-то еще.
Саймон Нинон

23

Думаю, у меня есть решение получше. Просто позвони
registerForContextMenu(yourTextView);

и вы TextViewбудете зарегистрированы для получения событий контекстного меню.

Затем переопределите onCreateContextMenuв своем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());
}

Надеюсь, это поможет вам и всем, кто ищет способ скопировать текст из TextView


Где это позволяет пользователю выбирать, какие фрагменты текста копируются? Разве он не просто копирует все, что не является исходным вопросом?
Джеймс Мур

4
Вероятно, полезно отметить, что это вызывает немедленное копирование текста, независимо от того, выбрали ли они «Копировать» в меню. Чтобы копировать только тогда, когда был выбран соответствующий элемент, вам также необходимо переопределить onContextItemSelected () или добавить обработчик щелчка к элементу меню.
Faisal

ClipboardManager.setText(CharSequence text)устарела на уровне API 11. Используйте setPrimaryClip(ClipData)вместо этого. Это создает ClippedItem, содержащий данный текст, и устанавливает его в качестве основного клипа. У него нет ярлыка или значка. Хорошее чтение о копипасте: ссылка
Марилия

Я хочу открыть диалог после выделения текста. Можете ли вы предложить что-нибудь по этому поводу?
Ананд Савджани 02

9
textview1.setTextIsSelectable(true);

Это позволит пользователю выбирать и копировать текст при долгом нажатии или, как мы обычно делаем


6

Я пытаюсь реализовать то же самое, и ваш вопрос помог мне правильно настроить макет редактируемого текста. Так что спасибо! :)

Потом я понял, что подсветка будет видна, если наведен курсор. Но мне просто нравится, что вы не хотите видеть курсор перед долгим щелчком по тексту, поэтому я скрываю курсор в файле layout.xml, как и вы, и добавляю прослушиватель событий для длительного щелчка и отображаю курсор только при запуске выделения .

Итак, добавьте слушателя в свою Activity в разделе 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;
        }
    });

}

И вуаля, нет курсора в начале, и если вы долго щелкаете, курсор появляется с границами выделения.

Я надеюсь, что смогу помочь.

Ура, FM


5

Я тоже пытался сделать что-то подобное, но все же мне нужен был индивидуальный подход с манипуляциями с выделением текста в TextView. Я активировал выделение и копирование по LongClickдействию.

Вот как мне удалось использовать 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);

и функция копирования:

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

Надеюсь, это будет полезно для тех, кто ответит на этот вопрос :)


4

Программное использование Kotlin (ручное копирование)

button.setTextIsSelectable(true)

Или добавьте расширение свойства Kotlin

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

Тогда позвони

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

Программное использование Kotlin (автоматическое копирование)

Если вы хотите автоматически копировать, когда пользователь долго нажимает на вас при просмотре, это необходимый базовый код:

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
}

Вы можете добавить, Toastчтобы подтвердить, что это произошло

Или добавьте функцию расширения 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
    }
}

Использование Xml (ручное копирование)

Добавьте это в свой <TextView>

android:textIsSelectable="true"

ПРИМЕЧАНИЕ. Все это требует android:enabled="true"и android:focusable="true", которые являются значениями по умолчанию для файла TextView.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.