Выбрать + скопировать текст в 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", но без этого курсор присутствует даже без выбора.

user291701
источник
Альтернативой было бы использование 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="" />
Milind
источник
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" />
skd
источник
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.

Гибольт
источник