Вибрати + скопіювати текст у 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
чи можете ви дозволити мені знати, як змусити його працювати у перегляді списку?
— Рамеш Кумар

Гарне, навіть за замовчуванням меню копій, створене на панелі інструментів
— Farid

56

Перегляд тексту повинен бути увімкнутим, орієнтованим, довгим натисканням та 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
Це найкраще рішення.
— Хоробрий

9
Чому textIsSelectableцього недостатньо? це працює для мене лише з цим варіантом
— herau

4
Або ви можете використовувати textview.setTextIsSelectable(true)в коді Java код.
— 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)була застаріла в рівні 11 API setPrimaryClip(ClipData). Це створює ClippedItem, що містить даний текст, і встановлює його як основний кліп. Він не має етикетки чи значка. Добре читати про copy-paste: посилання
— Марілія

Я хочу відкрити діалогове вікно після вибору тексту. Тож чи можете ви надати якісь пропозиції щодо цього?
— Ананд Савяні

9
textview1.setTextIsSelectable(true);

Це дасть можливість користувачеві вибирати та копіювати текст при тривалому натисканні або як ми зазвичай робимо


6

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

Тоді я зрозумів, що виділення буде дійсно видно, якщо курсор увімкнено. Але мені просто подобається, що ви не хочете бачити курсор перед довгим натисканням на текст, тому я ховаю курсор у файл layout.xml так само, як і ви, і додав eventlistener для тривалого клацання та відображення курсору лише тоді, коли розпочнеться вибір .

Тому додайте слухача до своєї активності в розділі 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;
        }
    });

}

І voilá, немає курсору на початку, і якщо ви довго натискаєте, з'явиться курсор із межами вибору.

Сподіваюся, я міг допомогти.

Ура, фм


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) { ...

Програмне використання Котліна (автоматичне копіювання)

Якщо ви хочете зробити автоматичне копіювання, коли користувач довго натискає на вас, це базовий код, необхідний:

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.