132

I want to make a read-only EditText view. The XML to do this code seems to be android:editable="false", but I want to do this in code.

How can I do this?

Adrian Toman
  • 11,316
  • 5
  • 48
  • 62
warna
  • 1,343
  • 2
  • 10
  • 8
  • See the link http://developer.android.com/reference/android/widget/TextView.html#attr_android:editable – ReNa Jun 17 '11 at 09:52
  • 4
    It is also worth noting that `android:editable` is deprecated for `EditText`. – Derek W May 15 '14 at 21:41
  • 1
    The most reliable way to do this is using `UI.setReadOnly(myEditText, true)` from [this library](https://github.com/delight-im/Android-BaseLib). There are a few properties that have to be set, which you can check out [in the source code](https://github.com/delight-im/Android-BaseLib/blob/62299c79d100e38627600907e755d563de072234/Source/src/im/delight/android/baselib/UI.java#L264). – caw Mar 09 '15 at 15:36
  • 3
    Yes Derek is right. Now in XML you should use `android:inputType="none"` and `android:textIsSelectable="true"` – Atul Apr 08 '17 at 05:47

24 Answers24

144

Please use this code..

Edittext.setEnabled(false);
Mehul Mistri
  • 15,037
  • 14
  • 70
  • 94
Nikhil
  • 16,194
  • 20
  • 64
  • 81
105

If you setEnabled(false) then your editText would look disabled (gray, etc). You may not want to change the visual aspect of your editor.

A less intrusive way would be to use setFocusable(false).

I believe that this answers your question closer to your initial intent.

Flexo
  • 87,323
  • 22
  • 191
  • 272
  • 9
    This is good, but the user can still "Paste" in the text field. – xtrem Jan 06 '13 at 21:51
  • 15
    This worked great for me. I needed it to be clickable so I couldn't use setEnabled(false). To get around the paste-able issue, I just did android:longClickable="false" – dt0 Mar 18 '14 at 21:40
  • 3
    If you use `setFocusable(false)` (and even `setFocusableInTouchMode(false)` with `setClickable(false)`) you can still change value of your `editText` pressing your `editText` for a [few hundred milliseconds](http://developer.android.com/reference/android/view/ViewConfiguration.html#getLongPressTimeout%28%29) and selecting `Paste` option unless [system clipboard](http://developer.android.com/guide/topics/text/copy-paste.html) is empty. I tested it with newest available API which is [23](http://developer.android.com/about/versions/marshmallow/android-6.0.html). – patryk.beza Mar 31 '16 at 12:05
  • This works, I am able to scroll and not see the cursor. – live-love Feb 11 '18 at 20:26
31

In XML use:

android:editable="false"

As an example:

<EditText
    android:id="@+id/EditText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:editable="false" />
Martin Zeitler
  • 1
  • 19
  • 155
  • 216
MD SHAHIDUL ISLAM
  • 14,325
  • 6
  • 82
  • 89
24

This works for me:

EditText.setKeyListener(null);
igorinov
  • 429
  • 3
  • 6
  • 5
    This would have been good, but the user can still "paste" in the field. Thumbs up anyways, even though this looks like a hack. I wish they had a setEditable() API. – xtrem Jan 06 '13 at 21:49
22
editText.setInputType(InputType.TYPE_NULL);

As per the docs this prevents the soft keyboard from being displayed. It also prevents pasting, allows scrolling and doesn't alter the visual aspect of the view. However, this also prevents selecting and copying of the text within the view.

From my tests setting setInputType to TYPE_NULL seems to be functionally equivalent to the depreciated android:editable="false". Additionally, android:inputType="none" seems to have no noticeable effect.

Adrian Toman
  • 11,316
  • 5
  • 48
  • 62
  • Agreed, this works for now, and like you said `android:inputType="none"` doesn't work anymore. – Goke Obasa Jan 12 '17 at 09:05
  • 1
    Unfortunately this does not prevent typing into the field if the virtual keyboard is already open (i.e. user taps on an editable field first, then on this one - virtual keyboard does not close). Also it doesn't prevent typing into the field from an external keyboard. – jk7 Apr 25 '17 at 00:47
19

android:editable="false" has been deprecated. Therefore you cant use it to make the edit text readonly.

I have done this using the bellow solution. Here I have used

android:inputType="none"

android:textIsSelectable="true"

android:focusable="false"

Give it try :)

<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"/>
Fran Marzoa
  • 4,293
  • 1
  • 37
  • 53
Chanaka Fernando
  • 2,176
  • 19
  • 19
  • It is not really readonly, you can still paste values to edittext in this code. `android:enabled="false"` may be a good alternative. – Elif Aug 28 '18 at 13:03
  • Adding `android:longClickable="false"` will prevent pasting – Matthew Sep 07 '20 at 20:57
16

The best is by using TextView instead.

Egor
  • 39,695
  • 10
  • 113
  • 130
8
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) : "";
    }
} });

This will give you uneditable EditText filter. you first need to put the text you want on the editText field and then apply this filter.

Barney
  • 2,355
  • 3
  • 22
  • 37
DArkO
  • 15,880
  • 12
  • 60
  • 88
  • 2
    A good solution, and less lines of code than a TextWatcher. This allows user to select & copy text but not change text by typing or CUT or PASTE. The return statement can be simplified to just `return dst.subSequence(dstart, dend);` – jk7 Oct 27 '17 at 20:50
  • My previous comment was referring to just the setFilters() statement without disabling the EditText field. – jk7 Oct 27 '17 at 21:38
  • Thanks, this is the only solution that works for me! It is frustrating that something working was depreciated, and replaced with something (inputType="none") that is still not working, and with unwanted side-effect (multi-line input). Please note the change suggested by @jk7 is vital, because with the original return statement, if you select part of your original text, and type something, you will end up replacing the selected text with the empty string returned by the filter. In this case src length is non-zero, and the empty string is having effect. – Paul L Sep 28 '18 at 02:07
6

writing this two line is more than enough for your work.

yourEditText.setKeyListener(null); 
yourEditText.setEnabled(false);
Gautam
  • 7,868
  • 12
  • 64
  • 105
Vishal Pandey
  • 696
  • 8
  • 7
5

set in XML

android:inputType="none" 
IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
3

Try overriding the onLongClick listener of the edit text to remove context menu:

EditText myTextField = (EditText)findViewById(R.id.my_edit_text_id);
myTextField.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});
Jimmy Ilenloa
  • 1,989
  • 21
  • 21
  • 3
    I have used android:editable="false" and android:focusable="false", then overrided onLongclick and got the result I wanted – JannGabriel May 28 '13 at 02:18
3
android:editable

If set, specifies that this TextView has an input method. It will be a textual one unless it has otherwise been specified. For TextView, this is false by default. For EditText, it is true by default.

Must be a boolean value, either true or false.

This may also be a reference to a resource (in the form @[package:]type:name) or theme attribute (in the form ?[package:][type:]name) containing a value of this type.

This corresponds to the global attribute resource symbol editable.

Related Methods

Asif Patel
  • 1,744
  • 1
  • 20
  • 27
jclafuente
  • 193
  • 1
  • 5
3

If you just want to be able to copy text from the control but not be able to edit it you might want to use a TextView instead and set text is selectable.

code:

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


The documentation of setTextIsSelectable says:

When you call this method to set the value of textIsSelectable, it sets the flags focusable, focusableInTouchMode, clickable, and longClickable to the same value...

However I had to explicitly set focusable and focusableInTouchMode to true to make it work with touch input.

A.J.Bauer
  • 2,803
  • 1
  • 26
  • 35
3

Use this code:

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

Disabling editText gives a read-only look and behavior but also changes the text-color to gray so setting its text color is needed.

3

Try using

editText.setEnabled(false);
editText.setClickable(false);
skynet
  • 9,898
  • 5
  • 43
  • 52
kannappan
  • 2,250
  • 3
  • 25
  • 35
1

this is my implementation (a little long, but useful to me!): With this code you can make EditView Read-only or Normal. even in read-only state, the text can be copied by user. you can change the backgroud to make it look different from a 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;
    }
}

the benefit of this code is that, the EditText is displayed as normal EditText but the content is not changeable. The return value should be kept as a variable to one be able revert back from read-only state to normal.

to make an EditText read-only, just put it as:

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

and to make it normal use tw from previous statement:

setReadOnly(editText, false, tw);
Ali sh
  • 464
  • 5
  • 14
1

This worked for me, taking several of the suggestions above into account. Makes the TextEdit focusable, but if user clicks or focuses, we show a list of selections in a PopupWindow. (We are replacing the wacky Spinner widget). TextEdit xml is very generic...

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);
    }
}  
Johnny O
  • 587
  • 4
  • 4
1

This was the only full simple solution for me.

editText.setEnabled(false);   // Prevents data entry
editText.setFocusable(false); // Prevents being able to tab to it from keyboard
AlanKley
  • 4,592
  • 8
  • 40
  • 53
1

As android:editable="" is deprecated,

Setting

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

will make it "read-only".

However, users will still be able to paste into the field or perform any other long click actions. To disable this, simply override onLongClickListener().
In Kotlin:

  • myEditText.setOnLongClickListener { true }

suffices.

Chad Mx
  • 1,266
  • 14
  • 17
1

My approach to this has been creating a custom TextWatcher class as follows:

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

Then you just add that watcher to any field you want to be read only despite being enabled:

editText.addTextChangedListener(new ReadOnlyTextWatcher(editText));
Fran Marzoa
  • 4,293
  • 1
  • 37
  • 53
0

I had no problem making EditTextPreference read-only, by using:

editTextPref.setSelectable(false);

This works well when coupled with using the 'summary' field to display read-only fields (useful for displaying account info, for example). Updating the summary fields dynamically snatched from 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());
        }
    }
}
Jason Harmon
  • 129
  • 5
0

Set this in EdiTextView xml file

android:focusable="false"
0

in java file:

Edittext.setEnabled(false);

in xml file:

android:editable="false" 
karim333
  • 1
  • 3
0

These 2 lines makes ur edittext selectable and at the same time not editable (it doesn't even show the soft keyboard):

editText.setInputType(InputType.TYPE_NULL);
editText.setTextIsSelectable(true);
Arezz
  • 1
  • 2