AngryHacker
AngryHacker

Reputation: 61606

How to replicate android:editable="false" in code?

In the layout you can set the EditText widget to be non-editable via the android:editable attribute.

How can I do this in code? I need to make the EditText widget to be editable depending on conditions.

Upvotes: 48

Views: 60938

Answers (14)

kajibu
kajibu

Reputation: 174

try this:

 mEditText.setFilters(new InputFilter[]{new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (XXX) {
                return "";
            } else {
                return null;
            }
        }
    }});

Upvotes: -1

Anirudh Sharma
Anirudh Sharma

Reputation: 7974

I guess

Edittext.setEnabled(false); 

through code

and

android:enabled="false"

through xml.Also check this post on SO.

They should work and you can enable again programatically Edittext.setEnabled(true);

Upvotes: 3

Josef Pfleger
Josef Pfleger

Reputation: 74527

I think an InputFilter that rejects all changes is a good solution:

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) : "";
        }
    }
});

Edit: dlazar suggested (below) to change the return to dst.subSequence(dstart, dend) to overcome behavior that removes words.

Upvotes: 13

Babasaheb
Babasaheb

Reputation: 703

You can try this:

        mEditText.setFocusable(false);
        mEditText.setClickable(false);
        mEditText.setFocusableInTouchMode(false);
        mEditText.setLongClickable(false);
        mEditText.setInputType(InputType.TYPE_NULL);

This will completely disable EditText, disable long press if you don't want user to open edit text options.

Upvotes: 6

abhi
abhi

Reputation: 759

android:editable="false" 
android:inputType="none" 

in your xml or

EditText mEdit = (EditText) findViewById(R.id.yourid);
mEdit.setEnabled(false);

or

EditText mEdit = (EditText) findViewById(R.id.yourid);
mEdit.setKeyListener(null);

Upvotes: 6

Bobby Schultz
Bobby Schultz

Reputation: 1

The only solution I have found for this scenario is to create 2 layouts. One is editable and one is not. You may have to create more than 2 layouts based on various conditions. Store the conditions in SharedPreferences or other means and load the relevant layout based on conditions after restarting the Activity. Here's an example:

in onCreate() of the activity:

    configuration = new Configuration(this.getSharedPreferences(Configuration.SHARED_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE));
    manualSettingsMode = configuration.isManualSettingsMode();
    if(manualSettingsMode){
        setContentView(R.layout.editableconfigurationsettings);
    }else {
        setContentView(R.layout.configurationsettings);
    }

The activity can be restarted based on testing for condition and calling functions as:

private void setManualEditing(){
    configuration.set_isManualSettingsMode(true);
    this.recreate();
}

private void setAutoEditing(){
    configuration.set_isManualSettingsMode(false);
    this.recreate();
}

Hope this helps. There really has to be a better solution, but this is what I've been doing. Ideally, one would be able to do this on individual fields and not have to reload the activity / layouts. -bobby

Upvotes: 0

atpanos
atpanos

Reputation: 473

I just tried this myself,

To disable editing text:

.setFocusable(false);

this also sets setFocusableInTouchMode to false!

To enable editing text:

setFocusableInTouchMode(true);

this also sets setFocusable to true;

Upvotes: 32

Timo
Timo

Reputation: 3404

I wanted to also point out an alternative solution that works nicely if you are creating new instances of an EditView. You can override the method getDefaultEditable() as suggested by the docs to return false. E.g.

EditText view = new EditText(DiscountCalculator.this) {
    public boolean getDefaultEditable() {
        return false;
    }
};

Upvotes: 1

Gerry
Gerry

Reputation: 459

editText.setFocusable(false);
editText.setClickable(false);

this ensure the EditText control can't be selected and focused, so it can't be edited.

Upvotes: 45

pjz
pjz

Reputation: 43057

Have you tried setText(java.lang.CharSequence, android.widget.TextView.BufferType) ? It's described as:

Sets the text that this TextView is to display (see setText(CharSequence)) and also sets whether it is stored in a styleable/spannable buffer and whether it is editable.

(emphasis mine)

Upvotes: 3

Christopher Perry
Christopher Perry

Reputation: 39225

The best way to do this is with this single line of code:

textView.setKeyListener(null);

The docs say for this method:

Sets the key listener to be used with this TextView. This can be null to disallow user input.

Upvotes: 16

forgemo
forgemo

Reputation: 4884

I think the correct way to achieve the desired effect is:

mEditView.setText("my text", BufferType.NORMAL);

If you want to switch between editable and non-editable you can do the following:

// Switch to non-editable
mEditView.setText(mEditView.getText(), BufferType.NORMAL);

// Switch back to editable
mEditView.setText(mEditView.getText(), BufferType.EDITABLE);

Upvotes: -1

dlazar
dlazar

Reputation: 31

[Posting a new answer, since I can't comment on Josef's answer.]

The input filter works fine, but it has a subtle bug in it: typing over a selection will delete all the text.

For example, say you have the text "foo" in the EditText. If you select it all (e.g., by double-clicking on it) and type 'a', the text will disappear. This is because the InputFilter will be called as:

filter("a", 0, 1, "foo", 0, 3);

The proposed input filter will return the empty string in this case (because src.length() < 1 is false), which explains the missing text.

The solution is to simply return dst.subSequence(dstart, dend) in the filter function. This will work fine even for deletions.

Upvotes: 3

Will
Will

Reputation: 20191

I do not see a related method for that attribute in the EditText class. However, there are other similar things you could use such as android:focus/setFocusable(boolean) or create another TextView whose android:editable="false" and use setVisiblilty() to switch between the editable and not editable views. If you use View.GONE the user will never know there are two EditTexts.

If your feeling ambitious you could probably do something with the EditText's onTextChanged listener like having it react with a setText.

Upvotes: 3

Related Questions