เลือก + คัดลอกข้อความใน TextView?


106

มีวิธีอนุญาตให้ผู้ใช้เลือก / คัดลอกข้อความใน TextView หรือไม่? ฉันต้องการฟังก์ชั่นเดียวกันของ EditText ที่คุณสามารถกดปุ่มควบคุมค้างไว้และรับตัวเลือกป๊อปอัพของ select all / copy แต่ฉันต้องการตัวควบคุมให้ดูเหมือน TextView

ลองทำสองสามอย่างเช่นการสร้าง EditText ให้ใช้ตัวเลือก editable = "none" หรือ inputType = "none" แต่ยังคงพื้นหลังกรอบของ EditText ซึ่งฉันไม่ต้องการ

ขอบคุณ

------- อัพเดท ----------------------

นี่คือ 99% ที่นั่นทั้งหมดที่ฉันต้องการคือให้ hilight การเลือกมองเห็นได้ (สิ่งที่เป็นสีส้ม) นอกจากนั้นยังดีสามารถอยู่ได้ด้วยสิ่งนี้แม้ว่า:

<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 เพื่อแสดงข้อความ
aleb


คำตอบ:


222

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 ขึ้นไปเท่านั้น
Thierry-Dimitri Roy

10
แต่จะลอกยังไง? ฉันไฮไลต์ข้อความได้ แต่ไม่มีเมนูคัดลอกปรากฏขึ้น
Bagusflyer

1
สิ่งนี้ไม่ได้ทำให้เกิดความผิดพลาดเมื่อคุณเล่นซอกับเคอร์เซอร์
Shubham

1
คุณช่วยบอกวิธีทำให้มันใช้งานได้ใน listview ได้ไหม
Ramesh Kumar

สวยงามแม้กระทั่งเมนูคัดลอกเริ่มต้นที่สร้างขึ้นบนแถบเครื่องมือ
Farid

56

ต้องเปิดใช้งาน Text View, focusable, 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)ใน code java code
berrytchaks

1
แค่ใช้textIsSelectableisทำงานให้ฉัน
crgarridos

1
อย่างใดก็textIsSelectableใช้ได้กับบางกรณี แต่ไม่ใช่อย่างอื่น บางครั้งเค้าโครงเดียวกันอาจใช้ไม่ได้กับแค่ textIsSelectable เสมอไป แต่เป็นข้อความที่แตกต่างกัน อย่างไรก็ตามวิธีนี้ดูเหมือนจะไม่ช่วยให้ทำงานได้ดีขึ้นดังนั้นปัญหาอาจมาจากที่อื่น
Simon Ninon

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


สิ่งนี้ช่วยให้ผู้ใช้เลือกบิตของข้อความที่จะคัดลอกได้ที่ไหน? ไม่ใช่แค่คัดลอกทุกอย่างซึ่งไม่ใช่คำถามดั้งเดิม?
James Moore

4
เป็นเรื่องดีที่จะทราบว่าสิ่งนี้ทำให้ข้อความถูกคัดลอกทันทีไม่ว่าพวกเขาจะเลือก "คัดลอก" จากเมนูหรือไม่ก็ตาม ในการคัดลอกเฉพาะเมื่อมีการเลือกรายการที่เหมาะสมคุณจะต้องแทนที่ onContextItemSelected () ด้วยหรือเพิ่มตัวจัดการการคลิกลงในรายการเมนู
Faisal

ClipboardManager.setText(CharSequence text)เลิกใช้แล้วใน API ระดับ 11 ใช้setPrimaryClip(ClipData)แทน สิ่งนี้จะสร้าง ClippedItem ที่เก็บข้อความที่กำหนดและตั้งเป็นคลิปหลัก ไม่มีป้ายกำกับหรือไอคอน อ่านดีๆเกี่ยวกับ copy-paste: link
Marilia

ฉันต้องการเปิดกล่องโต้ตอบหลังจากเลือกข้อความ คุณสามารถให้คำแนะนำได้หรือไม่?
Anand Savjani

9
textview1.setTextIsSelectable(true);

สิ่งนี้จะช่วยให้ผู้ใช้สามารถเลือกและคัดลอกข้อความเมื่อคลิกแบบยาวหรือตามปกติ


6

ฉันกำลังพยายามใช้สิ่งเดียวกันนี้และคำถามของคุณช่วยให้ฉันตั้งค่าเค้าโครงข้อความแก้ไขได้อย่างถูกต้อง ขอบคุณมาก! :)

จากนั้นฉันก็รู้ว่าไฮไลต์จะมองเห็นได้จริงหากเคอร์เซอร์เปิดอยู่ แต่ฉันชอบที่คุณไม่ต้องการเห็นเคอร์เซอร์ก่อนที่จะคลิกข้อความเป็นเวลานานดังนั้นฉันจึงซ่อนเคอร์เซอร์ในไฟล์ 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 แบบเป็นโปรแกรม (Manual Copy)

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
}

คุณอาจต้องการเพิ่ม a 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.


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.