Chọn + sao chép văn bản trong TextView?


106

Có cách nào để cho phép người dùng chọn / sao chép văn bản trong TextView không? Tôi cần chức năng tương tự của EditText nơi bạn có thể nhấn và giữ điều khiển và nhận các tùy chọn bật lên của chọn tất cả / sao chép, nhưng tôi cần điều khiển để trông giống như TextView.

Đã thử một vài thao tác như tạo EditText bằng cách sử dụng tùy chọn editable = "none" hoặc inputType = "none", nhưng những thứ đó vẫn giữ nguyên nền trong khung của EditText mà tôi không muốn,

Cảm ơn

------- Cập nhật ----------------------

Đây là 99% ở đó, tất cả những gì tôi muốn là làm cho vùng chọn hiển thị (thứ màu cam). Ngoài ra, nó tốt, có thể sống với điều này mặc dù:

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

Tôi đoán nó được gây ra bởi vì con trỏ có thể thay đổi được = "false" nhưng không có con trỏ đó hiện diện ngay cả khi không có bất kỳ lựa chọn nào được thực hiện.


Một giải pháp thay thế sẽ là sử dụng WebView thay vì TextView để hiển thị văn bản.
aleb


Câu trả lời:


221

android: textIsSelectable hoạt động (ít nhất là trong ICS - Tôi chưa đăng ký các phiên bản trước đó)

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

15
Chỉ API cấp 11 trở lên
Thierry-Dimitri Roy

10
Nhưng làm thế nào để sao chép? Tôi có thể đánh dấu văn bản, nhưng không có menu sao chép nào xuất hiện.
Bagusflyer

1
Đây không phải là nguyên nhân gây ra lỗi khi bạn loay hoay với các con trỏ.
Shubham

1
bạn có thể cho tôi biết cách làm cho nó hoạt động trong listview không?
Ramesh Kumar

Menu sao chép đẹp, thậm chí mặc định được tạo trên thanh công cụ
Farid

56

Chế độ xem văn bản cần được bật, có thể lấy tiêu điểm, có thể nhấp vào dài và có thể chọn văn bản

<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
Đây là giải pháp tốt nhất.
Brave

9
Tại sao textIsSelectablelà không đủ? nó hoạt động với tôi chỉ với tùy chọn này
herau

4
Hoặc bạn có thể sử dụng textview.setTextIsSelectable(true)trong mã java mã.
berrytchaks

1
Chỉ cần sử dụng textIsSelectableislàm công việc cho tôi
crgarridos

1
bằng cách nào đó, textIsSelectablehoạt động đối với một số trường hợp, nhưng không hoạt động đối với những trường hợp khác. Đôi khi, cùng một bố cục không phải lúc nào cũng hoạt động chỉ với textIsSelectable mà là một văn bản khác. Tuy nhiên, giải pháp này dường như không làm cho nó hoạt động tốt hơn, vì vậy vấn đề có thể đến từ một nơi khác.
Simon Ninon

23

Tôi nghĩ rằng tôi có một giải pháp tốt hơn. Chỉ cần gọi
registerForContextMenu(yourTextView);

và bạn TextViewsẽ được đăng ký nhận các sự kiện menu ngữ cảnh.

Sau đó ghi đè lên onCreateContextMenutrong bạnActivity

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

Hy vọng điều này sẽ giúp bạn và bất kỳ ai khác đang tìm cách sao chép văn bản từ TextView


Điều này cho phép người dùng chọn bit văn bản nào được sao chép ở đâu? Nó không chỉ sao chép mọi thứ, đó không phải là câu hỏi ban đầu?
James Moore

4
Có thể lưu ý rằng điều này khiến văn bản được sao chép ngay lập tức, bất kể họ có chọn "Sao chép" từ menu hay không. Để chỉ sao chép khi mục thích hợp được chọn, bạn cũng cần ghi đè onContextItemSelected () hoặc thêm trình xử lý nhấp chuột vào mục menu.
Faisal

ClipboardManager.setText(CharSequence text)không được dùng nữa trong API cấp 11. Hãy sử dụng setPrimaryClip(ClipData)thay thế. Điều này tạo ra một ClippedItem giữ văn bản đã cho và đặt nó làm clip chính. Nó không có nhãn hoặc biểu tượng. Đọc hay về copy-paste: link
Marilia

Tôi muốn mở hộp thoại sau khi chọn văn bản. Vì vậy, bạn có thể cung cấp bất kỳ gợi ý cho nó?
Anand Savjani

9
textview1.setTextIsSelectable(true);

Điều này sẽ cho phép người dùng chọn và sao chép văn bản khi nhấp lâu hoặc như chúng tôi thường làm


6

Tôi đang cố gắng triển khai tương tự và câu hỏi của bạn đã giúp tôi đặt chính xác bố cục editext của mình. Vì vậy, Cảm ơn! :)

Sau đó, tôi nhận ra rằng điểm nổi bật sẽ thực sự hiển thị nếu con trỏ được bật. Nhưng tôi cũng giống như bạn không muốn nhìn thấy con trỏ trước khi nhấp lâu vào văn bản, vì vậy tôi ẩn con trỏ trong tệp layout.xml giống như bạn và thêm một eventlistener để nhấp lâu và chỉ hiển thị con trỏ khi bắt đầu lựa chọn .

Vì vậy, hãy thêm người nghe vào Hoạt động của bạn trong phần 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;
        }
    });

}

Và voilá, không có con trỏ ở đầu, và nếu bạn nhấp lâu, con trỏ sẽ xuất hiện với các ranh giới lựa chọn.

Tôi hy vọng tôi có thể giúp đỡ.

Chúc mừng, fm


5

Tôi cũng đang cố gắng làm điều gì đó tương tự nhưng vẫn cần một cách tiếp cận tùy chỉnh với thao tác làm nổi bật văn bản trong TextView. Tôi đã kích hoạt đánh dấu và sao chép khi LongClickhành động.

Đây là cách tôi quản lý bằng cách sử dụng 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);

và chức năng sao chép:

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

Tôi hy vọng nó hữu ích cho ai đó kết thúc câu hỏi này :)


4

Sử dụng Kotlin có lập trình (Sao chép thủ công)

button.setTextIsSelectable(true)

Hoặc thêm phần mở rộng thuộc tính Kotlin

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

Sau đó gọi

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

Sử dụng Kotlin có lập trình (Tự động sao chép)

Nếu bạn muốn tự động sao chép khi người dùng nhấn và giữ bạn xem, đây là mã cơ sở bắt buộc:

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
}

Bạn có thể muốn thêm một Toastđể xác nhận điều đó đã xảy ra

Hoặc, thêm chức năng mở rộng 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
    }
}

Sử dụng Xml (Sao chép thủ công)

Thêm cái này vào của bạn <TextView>

android:textIsSelectable="true"

LƯU Ý: Tất cả những điều này đều yêu cầu android:enabled="true"android:focusable="true"là giá trị mặc định cho a TextView.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.