使EditText只读


119

我想做一个只读EditText视图。用于执行此代码的XML似乎是android:editable="false",但是我想在代码中执行此操作。

我怎样才能做到这一点?



3
还值得注意的android:editable是不推荐使用EditText
德里克W

最可靠的方法来做到这一点是使用UI.setReadOnly(myEditText, true)这个库。必须设置一些属性,您可以在源代码中查看这些属性。
Caw

3
是的,德里克是对的。现在,在XML你应该使用android:inputType="none"android:textIsSelectable="true"
阿图尔

Answers:


135

请使用此代码。

Edittext.setEnabled(false);

34
这不仅会“设置”为只读,还会禁用滚动和复制:-(
josef

1
这将禁用。尤其对于多行EditText没用。
Atul 2015年

试试这个但失去价值?
fdurmus77 '18

97

如果你setEnabled(false)那么你的editText将看起来已禁用(灰色等)。您可能不想更改编辑器的外观。

较少干扰的方式是使用 setFocusable(false)

我相信这可以更接近您的初衷。


8
很好,但是用户仍然可以在文本字段中“粘贴”。
xtrem

14
这对我来说很棒。我需要它可单击,所以我不能使用setEnabled(false)。为了解决可粘贴的问题,我只是做了android:longClickable =“ false”
dt0 2014年

3
如果你使用setFocusable(false)(甚至setFocusableInTouchMode(false)setClickable(false)),你仍然可以改变你的价值editText按您editText几百毫秒和选择Paste选项,除非系统剪贴板是空的。我使用最新的可用API对其进行了测试,它是23
patryk.beza,2016年

这行得通,我能够滚动而看不到光标。
真爱

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"
Ata Iravani 2016年

1
这个问题寻求一种通过Java代码而不是XML使可编辑错误的方法!
saeed khalafinejad

7
我正在尝试android:inputType="none",数据仍然可编辑。
BlueMonkMN

24

这对我有用:

EditText.setKeyListener(null);

5
这本来不错,但是用户仍然可以在该字段中“粘贴”。无论如何,还是竖起大拇指,即使这看起来像是骇客。我希望他们有一个setEditable()API。
xtrem

15

最好是使用TextView代替。


8
根据他的应用程序流程,可能是他需要使它有时可编辑,而在其他时候则不可编辑
Muhammed Refaat

15
editText.setInputType(InputType.TYPE_NULL);

根据文档这可防止显示软键盘。它还可以防止粘贴,允许滚动并且不会改变视图的视觉外观。但是,这也会阻止在视图内选择和复制文本。

从我的测试来看,设置setInputTypeTYPE_NULL似乎在功能上等同于折旧android:editable="false"。此外,android:inputType="none"似乎没有明显的作用。


同意,此android:inputType="none"操作暂时有效,就像您所说的不再有效。
Goke Obasa

1
不幸的是,如果虚拟键盘已经打开,这不会阻止您在该字段中键入内容(即,用户首先点击可编辑字段,然后在该字段上点击-虚拟键盘不会关闭)。同样,它也不会阻止从外部键盘输入该字段。
jk7 2007年

11

android:editable =“ false”已被弃用。因此,您不能使用它来使编辑文本变为只读。

我使用波纹管解决方案来完成此操作。在这里我用过

android:inputType =“ none”

android:textIsSelectable =“ true”

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

它不是真正的只读,您仍然可以在此代码中将值粘贴到edittext。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语句可以简化为return dst.subSequence(dstart, dend);
jk7,2010年

我之前的评论是只引用setFilters()语句,而不禁用EditText字段。
jk7

谢谢,这是唯一适用于我的解决方案!令人沮丧的是,某些可用的东西已被折旧,并被替换为仍然无法使用的东西(inputType =“ none”),并带有不希望的副作用(多行输入)。请注意,@ jk7建议的更改至关重要,因为使用原始return语句,如果您选择了部分原始文本并输入了某些内容,最终将用过滤器返回的空字符串替换所选文本。在这种情况下,src长度为非零,并且空字符串有效。
Paul L




3
android:editable

如果设置,则指定它TextView具有输入法。除非另有说明,否则它将为文本格式。对于TextView,默认情况下为false。对于EditText,默认情况下为true。

必须是或的boolean值。truefalse

这也可以是对包含此类型值的资源(以形式@[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

在EdiTextView xml文件中进行设置

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));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.