Вибрати + скопіювати текст у 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.