Làm cho EditText ReadOnly


119

Tôi muốn tạo chế độ chỉ đọc EditText chế độ xem . Có vẻ như XML để thực hiện mã này android:editable="false", nhưng tôi muốn làm điều này trong mã.

Tôi có thể làm cái này như thế nào?



3
Nó cũng đáng lưu ý rằng android:editablekhông được dùng cho EditText.
Derek W

Cách đáng tin cậy nhất để làm điều này là sử dụng UI.setReadOnly(myEditText, true)từ thư viện này . Có một số thuộc tính phải được thiết lập, bạn có thể kiểm tra trong mã nguồn .
caw

3
Vâng, Derek đúng. Bây giờ trong XML, bạn nên sử dụng android:inputType="none"android:textIsSelectable="true"
Atul

Câu trả lời:


135

Vui lòng sử dụng mã này ..

Edittext.setEnabled(false);

34
điều này sẽ không chỉ 'set' chỉ đọc-nhưng cũng vô hiệu hóa di chuyển và sao chép :-(
Josef

1
Điều này vô hiệu hóa. Vô dụng, đặc biệt là đối với EditText nhiều dòng.
Atul

thử cái này nhưng bị mất giá trị?
fdurmus77,

97

Nếu bạn setEnabled(false)thì editTexttrông bạn sẽ bị vô hiệu hóa (xám, v.v.). Bạn có thể không muốn thay đổi khía cạnh trực quan của trình chỉnh sửa của mình.

Một cách ít xâm nhập hơn sẽ được sử dụng setFocusable(false).

Tôi tin rằng điều này trả lời câu hỏi của bạn gần hơn với ý định ban đầu của bạn.


8
Điều này là tốt, nhưng người dùng vẫn có thể "Dán" vào trường văn bản.
xtrem

14
Nó hiệu quả tuyệt vời đối với tôi. Tôi cần nó để có thể nhấp được vì vậy tôi không thể sử dụng setEnabled (false). Để giải quyết vấn đề có thể dán, tôi vừa thực hiện android: longClickable = "false"
dt0

3
Nếu bạn sử dụng setFocusable(false)(và ngay cả setFocusableInTouchMode(false)với setClickable(false)), bạn vẫn có thể thay đổi giá trị của lần editTextnhấn editTexttrong vài trăm mili giây và chọn Pastetùy chọn trừ khi khay nhớ tạm hệ thống trống. Tôi đã thử nghiệm nó với API mới nhất có sẵn là 23 .
patryk.beza,

Điều này hoạt động, tôi có thể cuộn và không nhìn thấy con trỏ.
live-love

28

Đang XMLsử dụng:

android:editable="false"

Ví dụ:

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

Theo Javadoc , editablethuộc tính này dường như không còn được dùng nữa (ít nhất, không phải ở cấp API 23).
Greg Brown

8
@MichelJung nói đúng. bạn phải sử dụngandroid:inputType="none"
Ata Iravani

1
Câu hỏi tìm cách làm cho có thể chỉnh sửa sai thông qua mã Java chứ không phải XML!
saeed khalafinejad

7
Tôi đang thử android:inputType="none"và dữ liệu vẫn có thể chỉnh sửa được.
BlueMonkMN

24

Điều này phù hợp với tôi:

EditText.setKeyListener(null);

5
Điều này có thể tốt, nhưng người dùng vẫn có thể "dán" vào trường. Dù sao thì cũng thích, mặc dù điều này trông giống như một vụ hack. Tôi ước họ có một API setEditable ().
xtrem

15

Tốt nhất là sử dụng TextViewthay thế.


8
theo dòng chảy ứng dụng của mình có thể ông cần để làm cho nó có thể chỉnh sửa một số lần và ở những người khác không
Muhammed Refaat

15
editText.setInputType(InputType.TYPE_NULL);

Theo tài liệu, điều này ngăn không cho bàn phím mềm được hiển thị. Nó cũng ngăn việc dán, cho phép cuộn và không làm thay đổi khía cạnh hình ảnh của chế độ xem. Tuy nhiên, điều này cũng ngăn cản việc chọn và sao chép văn bản trong dạng xem.

Từ thử nghiệm của tôi thiết lập setInputTypeđể TYPE_NULLcó vẻ là chức năng tương đương với khấu hao android:editable="false". Ngoài ra, android:inputType="none"dường như không có tác dụng đáng chú ý.


Đồng ý, điều này hiện hoạt động và như bạn đã nói android:inputType="none"không hoạt động nữa.
Goke Obasa

1
Thật không may, điều này không ngăn cản việc nhập vào trường nếu bàn phím ảo đã được mở (tức là người dùng nhấn vào trường có thể chỉnh sửa trước, sau đó vào trường này - bàn phím ảo không đóng). Ngoài ra, nó không ngăn cản việc nhập vào trường từ bàn phím bên ngoài.
jk7

11

android: editable = "false" không được dùng nữa. Do đó, bạn không thể sử dụng nó để làm cho văn bản chỉnh sửa chỉ đọc được.

Tôi đã làm điều này bằng cách sử dụng giải pháp dưới đây. Ở đây tôi đã sử dụng

android: inputType = "none"

android: textIsSelectable = "true"

android: focusable = "false"

Hãy thử :)

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

Nó không thực sự chỉ đọc, bạn vẫn có thể dán các giá trị vào văn bản chỉnh sửa trong mã này. android:enabled="false"có thể là một sự thay thế tốt.
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) : "";
    }
} });

Điều này sẽ cung cấp cho bạn bộ lọc EditText không thể chỉnh sửa. trước tiên bạn cần đặt văn bản bạn muốn vào trường editText và sau đó áp dụng bộ lọc này.


2
Một giải pháp tốt và ít dòng mã hơn TextWatcher. Điều này cho phép người dùng chọn và sao chép văn bản nhưng không thay đổi văn bản bằng cách nhập hoặc CẮT hoặc PASTE. Lệnh return có thể được đơn giản hóa để chỉreturn dst.subSequence(dstart, dend);
jk7

Nhận xét trước đây của tôi chỉ đề cập đến câu lệnh setFilters () mà không tắt trường EditText.
jk7

Cảm ơn, đây là giải pháp duy nhất phù hợp với tôi! Thật khó chịu khi một thứ gì đó đang hoạt động bị giảm giá trị và được thay thế bằng thứ gì đó (inputType = "none") vẫn không hoạt động và có tác dụng phụ không mong muốn (đầu vào nhiều dòng). Xin lưu ý rằng thay đổi do @ jk7 đề xuất là rất quan trọng, vì với câu lệnh trả về ban đầu, nếu bạn chọn một phần của văn bản gốc và nhập nội dung nào đó, bạn sẽ thay thế văn bản đã chọn bằng chuỗi trống được bộ lọc trả về. Trong trường hợp này, chiều dài src là khác 0 và chuỗi trống đang có hiệu lực.
Paul L

6

viết hai dòng này là quá đủ cho công việc của bạn.

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

Hữu ích hơn nhiều đặt bộ nghe là vô hiệu hóa nó.
Humberto Castañeda


3

Hãy thử sử dụng

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

Điều này vẫn cho phép nó có thể đặt tiêu điểm bằng tab đánh từ bàn phím
AlanKley

3
android:editable

Nếu được đặt, hãy chỉ định rằng điều này TextViewcó một phương thức nhập. Nó sẽ là một văn bản trừ khi nó đã được chỉ định khác. Đối với TextView, điều này là sai theo mặc định. Đối với EditText, nó đúng theo mặc định.

Phải là một booleangiá trị, truehoặc false.

Đây cũng có thể là tham chiếu đến tài nguyên (trong biểu mẫu @[package:]type:name) hoặc thuộc tính chủ đề (trong biểu mẫu ?[package:][type:]name) có chứa giá trị thuộc loại này.

Điều này tương ứng với biểu tượng tài nguyên thuộc tính toàn cục có thể chỉnh sửa.

Các phương pháp liên quan


2

Hãy thử ghi đè trình nghe onLongClick của văn bản chỉnh sửa để xóa menu ngữ cảnh:

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

3
Tôi đã sử dụng android: editable = "false" và android: focusable = "false", sau đó ghi đè onLongclick và nhận được kết quả như mong muốn
JannGabriel

2

Sử dụng mã này:

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

Việc tắt editTextsẽ mang lại giao diện và hành vi chỉ đọc nhưng cũng thay đổi text-colormàu xám, vì vậy cần thiết lập màu văn bản của nó.


Vui lòng thêm một số giải thích là tốt.
Da đeneard

1

đây là cách triển khai của tôi (hơi dài, nhưng hữu ích với tôi!): Với mã này, bạn có thể đặt EditView ở chế độ Chỉ đọc hoặc Bình thường. ngay cả ở trạng thái chỉ đọc, người dùng có thể sao chép văn bản. bạn có thể thay đổi backgroud để làm cho nó trông khác với một EditText bình thường.

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

lợi ích của mã này là, EditText được hiển thị như EditText bình thường nhưng nội dung không thể thay đổi. Giá trị trả về nên được giữ dưới dạng một biến để có thể hoàn nguyên từ trạng thái chỉ đọc về trạng thái bình thường.

để đặt EditText ở chế độ chỉ đọc, chỉ cần đặt nó là:

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

và để làm cho nó bình thường, hãy sử dụng tw từ câu lệnh trước:

setReadOnly(editText, false, tw);

1

Điều này đã làm việc cho tôi, có tính đến một số đề xuất ở trên. Làm cho TextEdit có thể lấy tiêu điểm, nhưng nếu người dùng nhấp vào hoặc lấy tiêu điểm, chúng tôi sẽ hiển thị danh sách các lựa chọn trong PopupWindow. (Chúng tôi đang thay thế tiện ích Spinner lập dị). TextEdit xml rất chung chung ...

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

Nếu bạn chỉ muốn có thể sao chép văn bản từ điều khiển nhưng không thể chỉnh sửa nó, bạn có thể muốn sử dụng TextView thay thế và đặt văn bảnthể chọn .

mã:

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


Tài liệu của setTextIsSelectable cho biết:

Khi bạn gọi phương thức này để đặt giá trị của textIsSelectable, nó sẽ đặt các cờ có thể tiêu điểm, có thể tập trungInTouchMode, có thể nhấp và có thể nhấp vào cùng một giá trị ...

Tuy nhiên, tôi phải đặt rõ ràng là có thể lấy tiêu điểm và có thể lấy tiêu điểmInTouchMode thành true để làm cho nó hoạt động với đầu vào cảm ứng.


1

Đây là giải pháp đơn giản đầy đủ duy nhất cho tôi.

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

0

Tôi không gặp vấn đề gì khi đặt EditTextPreference ở chế độ chỉ đọc, bằng cách sử dụng:

editTextPref.setSelectable(false);

Điều này hoạt động tốt khi kết hợp với việc sử dụng trường 'tóm tắt' để hiển thị các trường chỉ đọc (ví dụ: hữu ích để hiển thị thông tin tài khoản). Cập nhật các trường tóm tắt được lấy động từ 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

Đặt điều này trong tệp xml EdiTextView

android:focusable="false"

1
Câu hỏi đặt ra là làm thế nào để làm cho nó ở chế độ chỉ đọc theo chương trình, không phải trong XML.
jk7

0

Như android:editable=""không được dùng nữa,

Cài đặt

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

sẽ làm cho nó "chỉ đọc".

Tuy nhiên, người dùng vẫn có thể dán vào trường hoặc thực hiện bất kỳ hành động nhấp dài nào khác. Để tắt tính năng này, chỉ cần ghi đè onLongClickListener ().
Trong Kotlin:

  • myEditText.setOnLongClickListener { true }

đủ.


0

Cách tiếp cận của tôi cho vấn đề này là tạo một lớp TextWatcher tùy chỉnh như sau:

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

Sau đó, bạn chỉ cần thêm người theo dõi đó vào bất kỳ trường nào bạn muốn chỉ được đọc mặc dù đã được bật:

editText.addTextChangedListener(new ReadOnlyTextWatcher(editText));
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.