Android中的EditText onClickListener


85

我想要一个EditText,当按下它时会创建一个DatePicker。所以我写了下面的代码:

    mEditInit = (EditText) findViewById(R.id.date_init);
    mEditInit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showDialog(DATEINIT_DIALOG);
        }

    });

但是当我按下EditText时,动作是典型的:光标在等待键入文本,而是显示我想要的对话框。


您应该使用微调器而不是EditText对话框。
瑞安·R

Answers:


129

当EditText获得焦点时,键盘似乎会弹出。为防止这种情况,请将focusable设置为false:

<EditText
    ...
    android:focusable="false"
    ... />

在不同的制造商的Android操作系统上,此行为可能有所不同,但是在我测试过的设备上,我发现这已足够。如果键盘仍然弹出,则使用提示代替文本似乎也有帮助:

myEditText.setText("My text");    // instead of this...
myEditText.setHint("My text");    // try this

完成此操作后,您的点击监听器将按预期工作:

myEditText.setOnClickListener(new OnClickListener() {...});

这似乎可行,但是当您键入一个字段并在键盘上单击“下一步”时,它将跳过该字段,并将焦点集中在false上。
Sterling Diaz

59

通常,您希望与EditText的正常行为具有最大的兼容性。

所以,你应该使用android:focusable="false"的,是的,视图将只是不可聚焦了它的日子也不好过。例如,背景可绘制对象将不再显示其“按下”状态。

相反,您应该执行以下操作:

myEditText.setInputType(InputType.TYPE_NULL);
myEditText.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // showMyDialog();
    }
});
myEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            // showMyDialog();
        }
    }
});

通过将输入类型设置为TYPE_NULL,可以防止弹出软件键盘。

通过设置OnClickListenerOnFocusChangeListener,您可以确保对话框在用户单击该EditText字段时(无论是获得焦点(第一次单击)还是随后的单击)始终打开。

仅仅设置android:inputType="none"还是setInputType(InputType.TYPE_NULL)并不总是足够的。对于某些设备,android:editable="false"尽管已弃用XML,但也应设置XML。如果它不再起作用,它将被忽略(因为不支持所有XML属性)。


当我这样做时,对话框将在关闭后重新打开,因为edittext再次获得了焦点。可以解决吗?
AdamMc331 '16

@ McAdam331也许该EditText组件是您布局中的唯一小部件吗?您可以尝试添加android:focusable="true"到父版面吗?
caw 2016年

1
@caw感谢您的回复,但最终还是使用onTouch使它起作用。谢谢!
AdamMc331 '16

而已。工作正常。
雪晴

31

我有同样的问题。该代码很好,但是请确保将EditText的可聚焦值更改为false。

<EditText
android:id="@+id/date"
android:focusable="false"/>

希望这对遇到类似问题的人有所帮助!


4
也不要设置enabled =“ false”,这将禁用
onClickListener

25

默认工作方式EditText:第一次单击时会聚焦,而在第二次单击时会处理,onClickListener因此您需要禁用焦点。然后,首先单击“onClickListener将”处理。

为此,您需要将此android:focusableInTouchMode="false"属性添加到EditText。而已!

像这样:

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusableInTouchMode="false"
        android:inputType="text" />

4
它可以工作,但是EditText无法编辑,并且光标不会出现。
CoolMind

17

这是我实施的解决方案

mPickDate.setOnKeyListener(new View.OnKeyListener() {

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        showDialog(DATE_DIALOG_ID);
        return false;
    }
});

要么

mPickDate.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        showDialog(DATE_DIALOG_ID);

    }
});

自己查看差异。问题是因为(如RickNotFred之类的)TextView显示日期并通过DatePicker编辑。TextEdit不是主要用途。如果要重新弹出DatePicker,则需要输入Delete(第一种情况)或de focus(第二种情况)。

射线


2
除非您添加一个我刚刚与onFocusChangeListener一起使用的onClickListener。这将起作用:-)
neteinstein 2011年

第二种解决方案对我有用,谢谢!:)
Celtik

9

如果对EditText使用OnClick操作,例如:

Java的

mEditInit = (EditText) findViewById(R.id.date_init);
mEditInit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        showDialog(DATEINIT_DIALOG);
    }

});

或科特琳:

editTextChooseDate.setOnClickListener {
        showDialog(DATEINIT_DIALOG)
    }

因此,如果xmlEditText输入以下几行内容,它将非常有效:

android:inputType =“ none

android:focusable =“ false” android:cursorVisible =“ false”

例如:

<EditText
            android:id="@+id/date_init" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=""
            android:hint="Select Date"
            android:inputType="none"
            android:focusable="false"
            android:cursorVisible="false"/>

或用于MaterialDesign

<com.google.android.material.textfield.TextInputLayout
        android:id="@+id/layoutEditTextChooseDate"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent">

    <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/date_init" 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=""
            android:hint="Select Date"
            android:inputType="none"
            android:focusable="false"                      
            android:cursorVisible="false"/>

</com.google.android.material.textfield.TextInputLayout>

8

恕我直言,我不同意RickNotFred的说法:

当EditText获得焦点时弹出对话框似乎是非标准界面。

当用户按下EditText时,显示一个对话框来编辑日期与默认情况非常相似,即显示键盘数字键盘。日期与EditText一起显示的事实向用户表示日期可能会更改。将日期显示为不可编辑的TextView会向用户发出信号,表示日期可能不会更改。


7

好话题。好吧,我已经这样做了。在XML文件中:

<EditText
    ...
    android:editable="false"
    android:inputType="none" />

在Java代码中:

txtDay.setOnClickListener(onOnClickEvent);
txtDay.setOnFocusChangeListener(onFocusChangeEvent);

private View.OnClickListener onOnClickEvent = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        dpDialog.show();
    }
};
private View.OnFocusChangeListener onFocusChangeEvent = new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus)
            dpDialog.show();
    }
};

6

以下内容非常适合我。

首先将日期选择器小部件的输入设置为“ none”,以防止弹出软键盘:

<EditText android:inputType="none" ... ></EditText>

然后添加这些事件侦听器以显示包含日期选择器的对话框:

// Date picker
EditText dateEdit = (EditText) findViewById(R.id.date);
dateOfBirthEdit.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            showDialog(DIALOG_DATE_PICKER);
        }
        return false;
    }
});

dateEdit.setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) {
            showDialog(DIALOG_DATE_PICKER);
        } else {
            dismissDialog(DIALOG_DATE_PICKER);
        }
    }
});

最后一件事。为了确保从日期选择器中正确复制键入的天,月或年,请datePicker.clearFocus()在获取值之前调用,例如通过getMonth()


简单修复:可以肯定的是,在每个showDialog之前都要先执行dismissDialog。
卢卡斯·巴托

5

这对我有用:

mEditInit = (EditText) findViewById(R.id.date_init);
mEditInit.setKeyListener(null);
mEditInit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if(hasFocus)
            {
                mEditInit.callOnClick();
            }
        }
    });
mEditInit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        showDialog(DATEINIT_DIALOG);
    }

});

3

这对我有用

设置为false

<EditText android:id="@+id/dob"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Date of Birth"
android:inputType="none"
android:editable="false"

/>

然后为OnFocusChange添加事件侦听器

private  View.OnFocusChangeListener onFocusChangeDOB= new View.OnFocusChangeListener() {

@Override
 public void onFocusChange(View v, boolean hasFocus) {
   if (hasFocus){
     showDialog(DATE_DIALOG_ID);
   }
 }
};

3
当心运行Android 2.3.x的摩托罗拉手机。如果EditText在可滚动区域中的某处,则在滚动时,Motorola会自动将焦点移到周围。这意味着您可以向下滚动,当EditText获得焦点时,将弹出日期对话框,这是令人惊讶且糟糕的。
埃里克·伯克

2

正如狄龙·凯恩斯(Dillon Kearns)所建议的那样,将焦点设置为false可以很好地工作。但是,如果您的目标是在单击EditText时取消键盘,则可能要使用:

mEditText.setInputType(0);

2

为什么没有人提及setOnTouchListener?使用起来setOnTouchListener很容易并且可以,如果侦听器已经使用了该事件,则返回true,否则返回false。

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.