ทำให้ EditText ReadOnly


119

ฉันต้องการสร้างEditTextมุมมองแบบอ่านอย่างเดียว XML ในการทำโค้ดนี้ดูเหมือนจะเป็นandroid:editable="false"แต่ฉันต้องการทำในโค้ด

ฉันจะทำเช่นนี้ได้อย่างไร?



3
นอกจากนี้ยังเป็นที่น่าสังเกตว่ามีการเลิกใช้android:editable EditText
Derek W

วิธีที่น่าเชื่อถือที่สุดคือใช้UI.setReadOnly(myEditText, true)จากไลบรารีนี้ มีคุณสมบัติไม่กี่คนที่จะต้องมีการตั้งค่าที่คุณสามารถตรวจสอบอยู่ในรหัสที่มา
caw

3
ใช่ Derek พูดถูก ตอนนี้ใน XML คุณควรใช้android:inputType="none"และandroid:textIsSelectable="true"
Atul

คำตอบ:


135

กรุณาใช้รหัสนี้ ..

Edittext.setEnabled(false);

34
สิ่งนี้จะไม่เพียง แต่ 'ตั้งค่า' แบบอ่านอย่างเดียว แต่ยังปิดใช้งานการเลื่อนและคัดลอก :-(
josef

1
สิ่งนี้ปิดใช้งาน ไม่มีประโยชน์โดยเฉพาะอย่างยิ่งสำหรับ EditText แบบหลายบรรทัด
Atul

ลอง แต่เสียค่า?
fdurmus77

97

ถ้าคุณดูsetEnabled(false)แล้วคุณeditTextจะพิการ (สีเทา ฯลฯ ) คุณอาจไม่ต้องการเปลี่ยนมุมมองภาพของโปรแกรมแก้ไขของคุณ

setFocusable(false)วิธีที่ล่วงล้ำน้อยจะใช้

ฉันเชื่อว่าสิ่งนี้ตอบคำถามของคุณได้ใกล้เคียงกับเจตนาเริ่มต้นของคุณ


8
ซึ่งเป็นสิ่งที่ดี แต่ผู้ใช้ยังสามารถ "วาง" ในช่องข้อความได้
xtrem

14
สิ่งนี้ได้ผลดีสำหรับฉัน ฉันต้องการให้มันคลิกได้ดังนั้นฉันจึงไม่สามารถใช้ setEnabled (false) ได้ เพื่อหลีกเลี่ยงปัญหาที่สามารถวางได้ฉันเพิ่งใช้ android: longClickable = "false"
dt0

3
หากคุณใช้setFocusable(false)(และถึงแม้จะsetFocusableInTouchMode(false)มีsetClickable(false)) คุณยังสามารถเปลี่ยนค่าของeditTextการกดของคุณได้editTextเป็นเวลาสองสามร้อยมิลลิวินาทีและเลือกPasteตัวเลือกเว้นแต่คลิปบอร์ดของระบบจะว่างเปล่า ผมทดสอบกับ API ใช้ได้ใหม่ล่าสุดซึ่งเป็น23
patryk.beza

ได้ผลฉันสามารถเลื่อนและไม่เห็นเคอร์เซอร์
live-love

28

ในXMLการใช้งาน:

android:editable="false"

ตัวอย่างเช่น:

<EditText
    android:id="@+id/EditText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:editable="false" />

ตามที่Javadocที่editableแอตทริบิวต์ไม่ปรากฏที่จะเลิกใช้ (อย่างน้อยไม่เป็นระดับ API 23)
Greg Brown

8
@MichelJung พูดถูก คุณต้องใช้android:inputType="none"
Ata Iravani

1
คำถามนี้หาวิธีทำให้เท็จที่แก้ไขได้ผ่านโค้ด Java ไม่ใช่ XML!
saeed khalafinejad

7
ฉันกำลังพยายามandroid:inputType="none"และข้อมูลยังแก้ไขได้
BlueMonkMN

24

สิ่งนี้ใช้ได้กับฉัน:

EditText.setKeyListener(null);

5
สิ่งนี้จะดี แต่ผู้ใช้ยังสามารถ "วาง" ในช่องได้ ยกนิ้วให้เลยแม้ว่ามันจะดูเหมือนแฮ็ค ฉันหวังว่าพวกเขาจะมี setEditable () API
xtrem

15

ที่ดีที่สุดคือการใช้TextViewแทน


8
ตามขั้นตอนการใช้แอปของเขาอาจเป็นเพราะเขาจำเป็นต้องทำให้มันสามารถแก้ไขได้ในบางครั้งและในบางครั้งก็ไม่สามารถแก้ไขได้
Muhammed Refaat

15
editText.setInputType(InputType.TYPE_NULL);

ตามเอกสารนี้จะป้องกันไม่ให้แสดงแป้นพิมพ์อ่อน นอกจากนี้ยังป้องกันการวางอนุญาตให้เลื่อนและไม่เปลี่ยนแปลงลักษณะการมองเห็นของมุมมอง อย่างไรก็ตามวิธีนี้ยังป้องกันการเลือกและคัดลอกข้อความภายในมุมมอง

จากการทดสอบของฉันการตั้งค่าsetInputTypeที่จะน่าจะเป็นหน้าที่เทียบเท่ากับค่าเสื่อมราคาTYPE_NULL android:editable="false"นอกจากนี้android:inputType="none"ดูเหมือนว่าจะไม่มีผลอย่างชัดเจน


ตกลงตอนนี้ใช้ได้ผลและอย่างที่คุณบอกว่าใช้android:inputType="none"ไม่ได้อีกต่อไป
Goke Obasa

1
น่าเสียดายที่นี่ไม่ได้ป้องกันการพิมพ์ลงในฟิลด์หากแป้นพิมพ์เสมือนเปิดอยู่แล้ว (เช่นผู้ใช้แตะที่ฟิลด์ที่แก้ไขได้ก่อนจากนั้นแป้นพิมพ์เสมือนนี้จะไม่ปิด) นอกจากนี้ยังไม่ป้องกันการพิมพ์ลงในฟิลด์จากแป้นพิมพ์ภายนอก
jk7

11

android: editable = "false"เลิกใช้งานแล้ว ดังนั้นคุณจึงไม่สามารถใช้เพื่อทำให้ข้อความแก้ไขเป็นแบบอ่านอย่างเดียวได้

ฉันได้ทำสิ่งนี้โดยใช้วิธีแก้ปัญหาต่อไปนี้ ที่นี่ฉันได้ใช้

หุ่นยนต์: inputType = "ไม่มี"

หุ่นยนต์: textIsSelectable = "true"

หุ่นยนต์: ที่สามารถโฟกัส = "false"

ลองดูสิ :)

<EditText
         android:id="@+id/et_newsgpa_university"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:hint="@string/hint_educational_institute"
         android:textSize="@dimen/regular_text"
         android:inputType="none"
         android:textIsSelectable="true"
         android:focusable="false"
         android:maxLines="1"
         android:imeOptions="actionNext"/>

มันไม่ได้เป็นแบบอ่านอย่างเดียวจริงๆคุณยังสามารถวางค่าลงในข้อความแก้ไขในโค้ดนี้ได้ android:enabled="false"อาจเป็นทางเลือกที่ดี
eVader

7
editText.setEnabled(false);
editText.setFilters(new InputFilter[] { new InputFilter() {
    public CharSequence filter(CharSequence src, int start, int end,
            Spanned dst, int dstart, int dend) {
        return src.length() < 1 ? dst.subSequence(dstart, dend) : "";
    }
} });

สิ่งนี้จะให้ตัวกรอง EditText ที่ไม่สามารถแก้ไขได้ ก่อนอื่นคุณต้องใส่ข้อความที่คุณต้องการในฟิลด์แก้ไขข้อความจากนั้นใช้ตัวกรองนี้


2
ทางออกที่ดีและมีโค้ดน้อยกว่า TextWatcher สิ่งนี้ช่วยให้ผู้ใช้สามารถเลือก & คัดลอกข้อความ แต่ไม่เปลี่ยนข้อความโดยพิมพ์หรือตัดหรือวาง คำสั่งส่งคืนสามารถทำให้ง่ายขึ้นได้เพียงreturn dst.subSequence(dstart, dend);
jk7

ความคิดเห็นก่อนหน้าของฉันอ้างถึงเพียงคำสั่ง setFilters () โดยไม่ปิดใช้งานฟิลด์ EditText
jk7

ขอบคุณนี่เป็นทางออกเดียวที่เหมาะกับฉัน! เป็นเรื่องที่น่าผิดหวังที่มีบางสิ่งที่ใช้งานได้ถูกหักค่าเสื่อมราคาและแทนที่ด้วยบางสิ่ง (inputType = "none") ที่ยังใช้งานไม่ได้และมีผลข้างเคียงที่ไม่ต้องการ (อินพุตหลายบรรทัด) โปรดทราบว่าการเปลี่ยนแปลงที่แนะนำโดย @ jk7 นั้นมีความสำคัญเนื่องจากด้วยคำสั่งส่งคืนต้นฉบับหากคุณเลือกบางส่วนของข้อความต้นฉบับและพิมพ์ข้อความคุณจะต้องแทนที่ข้อความที่เลือกด้วยสตริงว่างที่ตัวกรองส่งคืน ในกรณีนี้ความยาว src ไม่ใช่ศูนย์และสตริงว่างจะมีผล
Paul L

6

การเขียนสองบรรทัดนี้มากเกินพอสำหรับงานของคุณ

yourEditText.setKeyListener(null); 
yourEditText.setEnabled(false);

มีประโยชน์มากกว่าตั้งค่า Listener ว่างมากกว่าปิดใช้งาน
Humberto Castañeda


3

ลองใช้

editText.setEnabled(false);
editText.setClickable(false);

สิ่งนี้ยังคงช่วยให้สามารถโฟกัสได้โดยการกดปุ่มแท็บจากแป้นพิมพ์
AlanKley

3
android:editable

หากตั้งค่าระบุว่าTextViewมีวิธีการป้อนข้อมูล ข้อความนี้จะเป็นข้อความเว้นแต่จะมีการระบุไว้เป็นอย่างอื่น สำหรับTextViewนี่เป็นเท็จโดยค่าเริ่มต้น สำหรับEditTextมันเป็นจริงโดยค่าเริ่มต้น

จะต้องเป็นbooleanค่าอย่างใดอย่างหนึ่งหรือtruefalse

นอกจากนี้ยังอาจเป็นการอ้างอิงถึงทรัพยากร (ในรูปแบบ@[package:]type:name) หรือแอตทริบิวต์ธีม (ในรูปแบบ?[package:][type:]name) ที่มีค่าประเภทนี้

สิ่งนี้สอดคล้องกับสัญลักษณ์ทรัพยากรแอตทริบิวต์ส่วนกลางที่แก้ไขได้

วิธีการที่เกี่ยวข้อง


2

ลองลบล้างฟัง onLongClick ของข้อความแก้ไขเพื่อลบเมนูบริบท:

EditText myTextField = (EditText)findViewById(R.id.my_edit_text_id);
myTextField.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});

3
ฉันใช้ android: editable = "false" และ android: focusable = "false" จากนั้นแทนที่ onLongclick และได้ผลลัพธ์ที่ต้องการ
JannGabriel

2

ใช้รหัสนี้:

editText.setEnabled(false);
editText.setTextColor(ContextCompat.getColor(context, R.color.black);

การปิดใช้งานeditTextจะให้รูปลักษณ์และลักษณะการทำงานแบบอ่านอย่างเดียวแต่ยังเปลี่ยนเป็นtext-colorสีเทาดังนั้นจึงจำเป็นต้องตั้งค่าสีข้อความ


กรุณาเพิ่มคำอธิบายด้วย
หนวดดำ

1

นี่คือการใช้งานของฉัน (ยาวไปหน่อย แต่มีประโยชน์กับฉัน!): ด้วยรหัสนี้คุณสามารถทำให้ EditView Read-only หรือ Normal แม้จะอยู่ในสถานะอ่านอย่างเดียวผู้ใช้สามารถคัดลอกข้อความได้ คุณสามารถเปลี่ยนพื้นหลังเพื่อให้ดูแตกต่างจาก EditText ปกติ

public static TextWatcher setReadOnly(final EditText edt, final boolean readOnlyState, TextWatcher remove) {
    edt.setCursorVisible(!readOnlyState);
    TextWatcher tw = null;
    final String text = edt.getText().toString();
    if (readOnlyState) {
            tw = new TextWatcher();

            @Override
            public void afterTextChanged(Editable s) {

            }
            @Override
            //saving the text before change
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            // and replace it with content if it is about to change
            public void onTextChanged(CharSequence s, int start,int before, int count) {
                edt.removeTextChangedListener(this);
                edt.setText(text);
                edt.addTextChangedListener(this);
            }
        };
        edt.addTextChangedListener(tw);
        return tw;
    } else {
        edt.removeTextChangedListener(remove);
        return remove;
    }
}

ประโยชน์ของรหัสนี้คือ EditText จะแสดงเป็น EditText ปกติ แต่เนื้อหาไม่สามารถเปลี่ยนแปลงได้ ควรเก็บค่าที่ส่งคืนไว้เป็นตัวแปรเพื่อให้สามารถเปลี่ยนกลับจากสถานะอ่านอย่างเดียวเป็นปกติได้

ในการทำให้ EditText อ่านอย่างเดียวเพียงแค่ใส่เป็น:

TextWatcher tw = setReadOnly(editText, true, null);

และเพื่อให้ใช้งานได้ตามปกติ tw จากคำสั่งก่อนหน้า:

setReadOnly(editText, false, tw);

1

สิ่งนี้ได้ผลสำหรับฉันโดยคำนึงถึงคำแนะนำหลายประการข้างต้น ทำให้ TextEdit โฟกัสได้ แต่ถ้าผู้ใช้คลิกหรือโฟกัสเราจะแสดงรายการตัวเลือกใน PopupWindow (เรากำลังเปลี่ยนวิดเจ็ต Spinner ที่แปลกประหลาด) TextEdit xml เป็นเรื่องธรรมดามาก ...

public void onCreate(Bundle savedInstanceState) {
    ....  
    fEditState = (EditText) findViewById(R.id.state_edit);

    fEditState.setLongClickable(false);
    fEditState.setKeyListener(null);
    fEditState.setFocusable(true);

    fEditState.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        public void onFocusChange(View v, boolean hasFocus)
        {
            if (hasFocus)
            {
               showStatesPopup();

            }
        }
    });

    fEditState.setOnClickListener(new Button.OnClickListener(){

        public void onClick(View arg0)
        {
           showStatesPopup();
        }
    });
    ....
}

private void showStatesPopup()
{
    // fPopupWindowStates instantiated in OnCreate()

    if (!fPopupWindowStates.isShowing()) {
        // show the list view as dropdown
        fPopupWindowStates.showAsDropDown(fEditState, -5, 0);
    }
}  

1

ถ้าคุณเพียงต้องการที่จะสามารถคัดลอกข้อความจากการควบคุม แต่ไม่สามารถที่จะแก้ไขมันคุณอาจต้องการที่จะใช้TextViewแทนและการตั้งค่าข้อความเป็นเลือก

รหัส:

myTextView.setTextIsSelectable(true);
myTextView.setFocusable(true);
myTextView.setFocusableInTouchMode(true);
// myTextView.setSelectAllOnFocus(true);

XML:

<TextView
    android:textIsSelectable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"     
    ...
/>
<!--android:selectAllOnFocus="true"-->


เอกสารของsetTextIsSelectableกล่าวว่า:

เมื่อคุณเรียกเมธอดนี้เพื่อตั้งค่าของ textIsSelectable จะตั้งค่าแฟล็กที่สามารถโฟกัสได้, focusableInTouchMode, คลิกได้และ longClickable เป็นค่าเดียวกัน ...

อย่างไรก็ตามฉันต้องตั้งค่า InTouchMode ที่โฟกัสได้และโฟกัสได้อย่างชัดเจนเป็น true เพื่อให้ทำงานกับอินพุตแบบสัมผัส


1

นี่เป็นวิธีง่ายๆเพียงวิธีเดียวสำหรับฉัน

editText.setEnabled(false);   // Prevents data entry
editText.setFocusable(false); // Prevents being able to tab to it from keyboard

0

ฉันไม่มีปัญหาในการทำให้ EditTextPreference เป็นแบบอ่านอย่างเดียวโดยใช้:

editTextPref.setSelectable(false);

ซึ่งจะทำงานได้ดีเมื่อใช้ร่วมกับการใช้ฟิลด์ 'สรุป' เพื่อแสดงฟิลด์แบบอ่านอย่างเดียว (มีประโยชน์สำหรับการแสดงข้อมูลบัญชีเป็นต้น) การอัปเดตฟิลด์สรุปแบบไดนามิกที่ดึงมาจากhttp://gmariotti.blogspot.com/2013/01/preferenceactivity-preferencefragment.html

private static final List<String> keyList;

static {
    keyList = new ArrayList<String>();
    keyList.add("field1");
    keyList.add("field2");
    keyList.add("field3");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);

    for(int i=0;i<getPreferenceScreen().getPreferenceCount();i++){
        initSummary(getPreferenceScreen().getPreference(i));
    }
}

private void initSummary(Preference p) {
    if (p instanceof PreferenceCategory) {
        PreferenceCategory pCat = (PreferenceCategory) p;
        for (int i = 0; i < pCat.getPreferenceCount(); i++) {
            initSummary(pCat.getPreference(i));
        }
    } else {
        updatePrefSummary(p);
    }
}

private void updatePrefSummary(Preference p) {
    if (p instanceof ListPreference) {
        ListPreference listPref = (ListPreference) p;
        p.setSummary(listPref.getEntry());
    }
    if (p instanceof EditTextPreference) {
        EditTextPreference editTextPref = (EditTextPreference) p;
        //editTextPref.setEnabled(false); // this can be used to 'gray out' as well
        editTextPref.setSelectable(false);
        if (keyList.contains(p.getKey())) {
            p.setSummary(editTextPref.getText());
        }
    }
}

0

ตั้งค่านี้ในไฟล์ EdiTextView xml

android:focusable="false"

1
คำถามจะถามว่าจะทำให้อ่านอย่างเดียวโดยใช้โปรแกรมได้อย่างไรไม่ใช่ใน XML
jk7

0

เนื่องจากandroid:editable=""เลิกใช้งานแล้ว

การตั้งค่า

  • android:clickable="false"
  • android:focusable="false"
  • android:inputType="none"
  • android:cursorVisible="false"

จะทำให้เป็น "อ่านอย่างเดียว"

อย่างไรก็ตามผู้ใช้จะยังคงสามารถวางลงในช่องหรือดำเนินการคลิกยาวอื่น ๆ ได้ หากต้องการปิดใช้งานเพียงแค่แทนที่ onLongClickListener ()
ใน Kotlin:

  • myEditText.setOnLongClickListener { true }

พอเพียง


0

แนวทางของฉันคือการสร้างคลาส TextWatcher ที่กำหนดเองดังนี้:

class ReadOnlyTextWatcher implements TextWatcher {
    private final EditText textEdit;
    private String originalText;
    private boolean mustUndo = true;

    public ReadOnlyTextWatcher(EditText textEdit) {
        this.textEdit = textEdit;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        if (mustUndo) {
            originalText = charSequence.toString();
        }
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        if (mustUndo) {
            mustUndo = false;
            textEdit.setText(originalText);
        } else {
            mustUndo = true;
        }
    }
}

จากนั้นคุณเพียงแค่เพิ่มผู้เฝ้าดูนั้นในฟิลด์ใด ๆ ที่คุณต้องการให้อ่านเท่านั้นแม้จะเปิดใช้งาน:

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