Android 中的 EditText onClickListener

发布于 2024-08-23 13:52:44 字数 371 浏览 7 评论 0原文

我想要一个 EditText,它在按下时创建一个 DatePicker。所以我编写了以下代码:

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

    });

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

I want an EditText which creates a DatePicker when is pressed. So I write the following code:

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

    });

But when I press the EditText the action is the typical: a cursor waiting for typing text instead show the Dialog I want.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

蝶…霜飞 2024-08-30 13:52:44

当 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() {...});

The keyboard seems to pop up when the EditText gains focus. To prevent this, set focusable to false:

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

This behavior can vary on different manufacturers' Android OS flavors, but on the
devices I've tested I have found this to to be sufficient. If the keyboard still pops up, using hints instead of text seems to help as well:

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

Once you've done this, your on click listener should work as desired:

myEditText.setOnClickListener(new OnClickListener() {...});
ぶ宁プ宁ぶ 2024-08-30 13:52:44

通常,您希望与 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) 并不总是足够的。对于某些设备,您还应该在 XML 中设置 android:editable="false",尽管它已被弃用。如果它不再起作用,它将被忽略(因为所有 XML 属性都不支持)。

Normally, you want maximum compatibility with EditText's normal behaviour.

So you should not use android:focusable="false" as, yes, the view will just not be focusable anymore which looks bad. The background drawable will not show its "pressed" state anymore, for example.

What you should do instead is the following:

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

By setting the input type to TYPE_NULL, you prevent the software keyboard from popping up.

By setting the OnClickListener and OnFocusChangeListener, you make sure that your dialog will always open when the user clicks into the EditText field, both when it gains focus (first click) and on subsequent clicks.

Just setting android:inputType="none" or setInputType(InputType.TYPE_NULL) is not always enough. For some devices, you should set android:editable="false" in XML as well, although it is deprecated. If it does not work anymore, it will just be ignored (as all XML attributes that are not supported).

暖树树初阳… 2024-08-30 13:52:44

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

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

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

I had this same problem. The code is fine but make sure you change the focusable value of the EditText to false.

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

I hope this helps anyone who has had a similar problem!

鲜血染红嫁衣 2024-08-30 13:52:44

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

Default working of EditText:
On first click it focuses and on second click it handles onClickListener so you need to disable focus. Then on first click the onClickListener will handle.

To do that you need to add this android:focusableInTouchMode="false" attribute to your EditText. That's it!

Something like this:

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusableInTouchMode="false"
        android:inputType="text" />
不喜欢何必死缠烂打 2024-08-30 13:52:44

这是我实现的解决方案

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(第二种情况)。

射线

Here is the solution I implemented

mPickDate.setOnKeyListener(new View.OnKeyListener() {

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

OR

mPickDate.setOnFocusChangeListener(new View.OnFocusChangeListener() {

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

    }
});

See the differences by yourself.
Problem is since (like RickNotFred said) TextView to display the date & edit via the DatePicker. TextEdit is not used for its primary purpose.
If you want the DatePicker to re-pop up, you need to input delete (1st case) or de focus (2nd case).

Ray

允世 2024-08-30 13:52:44

如果您在 EditText 上使用 OnClick 操作,例如:

java:

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

});

或 kotlin:

editTextChooseDate.setOnClickListener {
        showDialog(DATEINIT_DIALOG)
    }

所以,如果您将以下行放入 EditTextxml 中:

android:inputType="无"
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>

If you use OnClick action on EditText like:

java:

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

});

or kotlin:

editTextChooseDate.setOnClickListener {
        showDialog(DATEINIT_DIALOG)
    }

So, it will work perfectly if you put into xml of your EditText the following lines:

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

For example:

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

or for 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>
标点 2024-08-30 13:52:44

请参阅https://gist.github.com/Reacoder/0b316726564f85523251

editText.setOnFocusChangeListener { _, hasFocus ->
    if (hasFocus) {
        // onClick(editText)
    }
}
editText.setOnTouchListener { _, motionEvent ->
    if (motionEvent.action == MotionEvent.ACTION_DOWN) {
        // onClick(editText)
    }
    false
}

===旧答案===

好话题。嗯,我已经这样做了。
在 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();
    }
};

See https://gist.github.com/Reacoder/0b316726564f85523251:

editText.setOnFocusChangeListener { _, hasFocus ->
    if (hasFocus) {
        // onClick(editText)
    }
}
editText.setOnTouchListener { _, motionEvent ->
    if (motionEvent.action == MotionEvent.ACTION_DOWN) {
        // onClick(editText)
    }
    false
}

=== Old answer ===

Nice topic. Well, I have done so.
In XML file:

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

In Java-code:

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();
    }
};
愛上了 2024-08-30 13:52:44

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

当 EditText 获取时弹出对话框
焦点似乎不标准
界面。

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

IMHO I disagree with RickNotFred's statement:

Popping a dialog when an EditText gets
focus seems like a non-standard
interface.

Displaying a dialog to edit the date when the use presses the an EditText is very similar to the default, which is to display a keyboard or a numeric key pad. The fact that the date is displayed with the EditText signals to the user that the date may be changed. Displaying the date as a non-editable TextView signals to the user that the date may not be changed.

幸福不弃 2024-08-30 13:52:44

以下内容非常适合我。

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

<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()

The following works perfectly for me.

First set your date picker widget's input to 'none' to prevent the soft keyboard from popping up:

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

Then add these event listeners to show the dialog containing the date picker:

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

One last thing. To make sure typed days, months, or years are correctly copied from the date picker, call datePicker.clearFocus() before retrieving the values, for instance via getMonth().

你另情深 2024-08-30 13:52:44

这对我有用:

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

});

This Works For me:

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

});
狂之美人 2024-08-30 13:52:44

这是对我有用的

设置可编辑为 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);
   }
 }
};

Here is what worked for me

Set editable to 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"

/>

Then add an event listener for OnFocusChange

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

@Override
 public void onFocusChange(View v, boolean hasFocus) {
   if (hasFocus){
     showDialog(DATE_DIALOG_ID);
   }
 }
};
黯淡〆 2024-08-30 13:52:44

正如 Dillon Kearns 所建议的,将 focusable 设置为 false 效果很好。
但如果您的目标是在单击 EditText 时取消键盘,您可能需要使用:

mEditText.setInputType(0);

As Dillon Kearns suggested, setting focusable to false works fine.
But if your goal is to cancel the keyboard when EditText is clicked, you might want to use:

mEditText.setInputType(0);
嘿哥们儿 2024-08-30 13:52:44

为什么没有人提到setOnTouchListener?使用 setOnTouchListener 非常简单,如果侦听器已使用该事件,则返回 true,否则返回 false。

Why did not anyone mention setOnTouchListener? Using setOnTouchListener is easy and all right, and just return true if the listener has consumed the event, false otherwise.

别低头,皇冠会掉 2024-08-30 13:52:44

使用 OnFocusChangeListener 的解决方案的问题在于,它们将任何焦点增益解释为单击。这并不是 100% 正确:您的 EditText 可能会通过点击以外的其他方式获得焦点。

如果您严格关心点击并且想要一致地检测点击(无论焦点如何),您可以使用GestureDetector

editText.setOnConsistentClickListener { /* do something */ }

fun EditText.setOnConsistentClickListener(doOnClick: (View) -> Unit) {
    val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapUp(event: MotionEvent?): Boolean {
            doOnClick(this@setOnConsistentClickListener)
            return false
        }
    })

    this.setOnTouchListener { _, motionEvent -> gestureDetector.onTouchEvent(motionEvent) }
}

The problem with solutions using OnFocusChangeListener is that they interpret any focus gain as a click. This is not 100% correct: your EditText might gain focus from something else than a click.

If you strictly care about click and want to detect click consistently (regardless of focus), you can use a GestureDetector:

editText.setOnConsistentClickListener { /* do something */ }

fun EditText.setOnConsistentClickListener(doOnClick: (View) -> Unit) {
    val gestureDetector = GestureDetectorCompat(context, object : GestureDetector.SimpleOnGestureListener() {
        override fun onSingleTapUp(event: MotionEvent?): Boolean {
            doOnClick(this@setOnConsistentClickListener)
            return false
        }
    })

    this.setOnTouchListener { _, motionEvent -> gestureDetector.onTouchEvent(motionEvent) }
}
匿名的好友 2024-08-30 13:52:44

对于 kotlin,你可以使用这个

    editText!!.showSoftInputOnFocus = false

For kotlin, you could use this

    editText!!.showSoftInputOnFocus = false
潦草背影 2024-08-30 13:52:44

对于 EditTextTextInputEditText 使用以下属性

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

For EditText or TextInputEditText Use the Below Properties

  android:inputType="none"
  android:focusable="false"                      
  android:cursorVisible="false"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文