Сделать EditText доступным только для чтения


119

Я хочу сделать представление только для чтения EditText. XML для выполнения этого кода кажетсяandroid:editable="false" , но я хочу сделать это в коде.

Как я могу это сделать?



3
Также стоит отметить, что android:editableдля EditText.
Derek W

Самый надежный способ сделать это - использовать UI.setReadOnly(myEditText, true)из этой библиотеки . Необходимо установить несколько свойств, которые вы можете проверить в исходном коде .
карканье

3
Да, Дерек прав. Теперь в XML вы должны использовать android:inputType="none"иandroid:textIsSelectable="true"
Атул

Ответы:


135

Пожалуйста, используйте этот код ..

Edittext.setEnabled(false);

34
это не только сделает доступным только для чтения, но также отключает прокрутку и копирование :-(
josef

1
Это отключает. Бесполезно, особенно для многострочного EditText.
Атул

попробовать это, но потерял ценность?
fdurmus77 02

97

Если ты setEnabled(false)тогда твойeditText будет выглядеть отключенным (серый и т. Д.). Возможно, вы не захотите изменять внешний вид вашего редактора.

Менее навязчивым способом было бы использовать setFocusable(false) .

Я считаю, что это ответ на ваш вопрос ближе к вашему первоначальному намерению.


8
Это хорошо, но пользователь все еще может «Вставить» в текстовое поле.
xtrem 06

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).
Грег Браун

8
@MichelJung прав. вы должны использоватьandroid:inputType="none"
Ата Иравани

1
Вопрос ищет способ сделать редактируемую ложь через код Java, а не XML!
Саид Халафинеджад

7
Я пытаюсь, android:inputType="none"но данные все еще можно редактировать.
BlueMonkMN

24

Это работает для меня:

EditText.setKeyListener(null);

5
Это было бы хорошо, но пользователь все еще может «вставить» в поле. В любом случае палец вверх, хотя это похоже на взлом. Я бы хотел, чтобы у них был API setEditable ().
xtrem 06

15

Лучше всего использовать TextViewвместо этого.


8
согласно его потоку приложения, возможно, ему нужно сделать его редактируемым в некоторых случаях, а в других
Мухаммед Рефаат

15
editText.setInputType(InputType.TYPE_NULL);

Согласно документам это предотвращает отображение мягкой клавиатуры. Это также предотвращает вставку, позволяет прокручивать и не изменяет визуальный аспект представления. Однако это также предотвращает выбор и копирование текста в представлении.

Из моих тестов установки , setInputTypeчтобы , TYPE_NULLкажется, функционально эквивалентен амортизируется android:editable="false". Кроме того, android:inputType="none"похоже, не имеет заметного эффекта.


Согласен, сейчас это работает и, как вы сказали, android:inputType="none"больше не работает.
Гоке Обаса

1
К сожалению, это не мешает вводить текст в поле, если виртуальная клавиатура уже открыта (т.е. пользователь сначала нажимает на редактируемое поле, а затем на это - виртуальная клавиатура не закрывается). Также это не мешает набирать текст в поле с внешней клавиатуры.
jk7

11

android: editable = "false" устарел. Поэтому вы не можете использовать его, чтобы текст редактирования был доступен только для чтения.

Я сделал это с помощью решения ниже. Здесь я использовал

андроид: inputType = "нет"

андроид: textIsSelectable = "истина"

андроид: фокусируемые = «ложь»

Попробуйте :)

<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. вам сначала нужно поместить нужный текст в поле editText, а затем применить этот фильтр.


2
Хорошее решение и меньше строк кода, чем TextWatcher. Это позволяет пользователю выбирать и копировать текст, но не изменять текст, набирая или ВЫРЕЗАТЬ или ВСТАВИТЬ. Оператор возврата можно упростить до простоreturn dst.subSequence(dstart, dend);
jk7

Мой предыдущий комментарий относился только к оператору setFilters () без отключения поля EditText.
jk7

Спасибо, это единственное решение, которое мне подходит! Вызывает разочарование то, что что-то работающее было обесценено и заменено чем-то (inputType = "none"), которое все еще не работает, и с нежелательным побочным эффектом (многострочный ввод). Обратите внимание, что изменение, предложенное @ jk7, является жизненно важным, потому что с исходным оператором return, если вы выберете часть исходного текста и введете что-то, вы в конечном итоге замените выбранный текст пустой строкой, возвращаемой фильтром. В этом случае длина src не равна нулю, и пустая строка имеет значение.
Paul L

6

написания этих двух строк более чем достаточно для вашей работы.

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

Намного полезнее установить нулевое значение слушателя, чем отключить его.
Умберто Кастаньеда


3

Попробуйте использовать

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

Это по-прежнему позволяет фокусировать его, нажимая вкладку с клавиатуры
AlanKley

3
android:editable

Если установлено, указывает, что у TextViewнего есть метод ввода. Это будет текстовый, если не указано иное. Ибо TextViewпо умолчанию это false. Ибо EditTextпо умолчанию это правда.

Должно быть booleanзначение, либо trueили false.

Это также может быть ссылка на ресурс (в форме @[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цвет на серый, поэтому необходимо установить цвет текста.


Пожалуйста, добавьте также несколько пояснений.
BlackBeard

1

это моя реализация (немного длинная, но полезная для меня!): С помощью этого кода вы можете сделать EditView доступным только для чтения или обычным. даже в состоянии только для чтения текст может быть скопирован пользователем. вы можете изменить фон, чтобы он отличался от обычного 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, он устанавливает для флагов focusable, focusableInTouchMode, clickable и longClickable одно и то же значение ...

Однако мне пришлось явно установить focusable и focusableInTouchMode в значение 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

Установите это в XML-файле EdiTextView

android:focusable="false"

1
Вопрос в том, как сделать его доступным только для чтения программно, а не в XML.
jk7

0

Как android:editable=""не рекомендуется,

Настройка

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

сделает его доступным только для чтения.

Однако пользователи по-прежнему смогут вставлять в поле или выполнять любые другие действия с длительным щелчком. Чтобы отключить это, просто переопределите onLongClickListener ().
В Котлине:

  • 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));
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.