Зробіть EditText ReadOnly


119

Я хочу зробити перегляд лише для читання EditText. XML для цього коду, схоже, є android:editable="false", але я хочу це зробити в коді.

Як я можу це зробити?


Дивіться посилання developer.android.com/reference/android/widget/…
ReNa

3
Варто також зазначити, що android:editableце застаріле для EditText.
Дерек Ш

Найнадійніший спосіб зробити це , використовуючи UI.setReadOnly(myEditText, true)з цією бібліотеки . Необхідно встановити кілька властивостей, які ви можете перевірити у вихідному коді .
каре

3
Так, Дерек має рацію. Тепер у XML ви повинні використовувати android:inputType="none"таandroid:textIsSelectable="true"
Atul

Відповіді:


135

Будь ласка, використовуйте цей код ..

Edittext.setEnabled(false);

34
це не тільки "встановить" лише для читання, але й відключить прокрутку та копіювання :-(
josef

1
Це вимикає. Марно особливо для багаторядкових EditText.
Атул

спробувати це, але втратили значення?
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атрибут не видається застарілим (принаймні, не як рівень 23 API).
Грег Браун

8
@MichelJung має рацію. ви повинні використовуватиandroid:inputType="none"
Ата Іравані

1
Питання шукає спосіб зробити помилковим для редагування код Java не XML!
saeed khalafinejad

7
Я намагаюся, android:inputType="none"і дані все ще можна редагувати.
BlueMonkMN

24

Це працює для мене:

EditText.setKeyListener(null);

5
Це було б добре, але користувач все одно може «вставити» в поле. Пальці все одно, хоча це схоже на злом. Я б хотів, щоб у них був API SetEditable ().
xtrem

15

Найкраще, використовуючи TextViewзамість цього.


8
відповідно до його потоку додатків, можливо, йому потрібно буде його редагувати кілька разів, а в інших немає
Мухаммед Рефаат

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" застаріло. Тому ви не можете використовувати його, щоб зробити текст редагування лише читати.

Я зробив це, використовуючи нижній розчин. Ось я і скористався

android: inputType = "немає"

android: textIsSelectable = "вірно"

android: focusable = "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. спочатку потрібно помістити потрібний текст у поле editText, а потім застосувати цей фільтр.


2
Хороше рішення і менше рядків коду, ніж TextWatcher. Це дозволяє користувачеві вибирати та копіювати текст, але не змінювати текст, ввівши CUT або PASTE. Заява про повернення може бути спрощена до простоreturn dst.subSequence(dstart, dend);
jk7

Мій попередній коментар стосувався лише оператора setFilters (), не вимикаючи поле EditText.
jk7

Дякую, це єдине рішення, яке працює для мене! Розчаровує те, що щось працююче знецінилося і замінилося чимось (inputType = "жоден"), яке все ще не працює, і небажаним побічним ефектом (багаторядковий ввід). Зверніть увагу, що зміна, запропонована @ jk7, є життєво важливою, тому що, якщо ви отримаєте частину оригінального тексту і введете щось, ви в остаточному підсумку заміните вибраний текст порожнім рядком, повернутим фільтром. У цьому випадку довжина src не дорівнює нулю, і порожня рядок має ефект.
Пол Л

6

написання цього двох рядків більш ніж достатньо для вашої роботи.

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

Набагато корисніше встановити слухача нульовим, ніж відключити його.
Умберто Кастаньеда


3

Спробуйте використовувати

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

Це все ще дозволяє зробити його фокусируемим, натискаючи вкладку з клавіатури
AlanKley

3
android:editable

Якщо встановлено, визначає, що для цього TextViewє метод введення. Він буде текстовим, якщо інше не вказано. Бо TextViewце за замовчуванням помилково. Бо 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 лише для читання або звичайного. навіть у стані лише для читання текст може бути скопійований користувачем. ви можете змінити backgroud, щоб він виглядав відмінним від звичайного 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, він встановлює прапорці, що фокусуються, фокусуються InTouchMode, можна натискати і 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

Встановіть це у Xdi-файлі 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.