101

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.

1
  • 1
    You should use a spinner instead of an EditText dialog. Commented Sep 30, 2012 at 3:34

16 Answers 16

139

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() {...}); 
Sign up to request clarification or add additional context in comments.

1 Comment

This seems to work, but when you type in a field, and click Next on the keyboard, it skip the field with focusable on false.
67

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

4 Comments

When I do this, the dialog reopens after it closes because the edittext gains focus again. Any way around this?
@McAdam331 Is that EditText component the only widget in your layout, perhaps? Can you try adding android:focusable="true" to your parent layout?
@caw Thanks for responding, but I ended up getting it to work using onTouch. Thanks!
That's it. Working fine.
33

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!

1 Comment

Also don't set enabled="false", which will disable onClickListener
29

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

1 Comment

It works, but EditText becomes uneditable, and cursor doesn't appear.
18

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

2 Comments

unless you add a onClickListener which i just did together with a onFocusChangeListener. This will work :-)
The second solution has worked for me, thank you! :)
15

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> 

2 Comments

What's the point of making the EditText unfocusable if you can't type anything into it? Totally unpractical.
@Sphax Right, that would be impractical if you have to enter data in the field. But then again, but! The author of the question doesn't have that goal. He wants a dialog box to appear. In this case you don't need focus. Perhaps your task is slightly different. I don't know about that, and it is possible that in your case it will be necessary to turn on focusing. In this case, you will have to slightly modify this example for your own purposes. In any case, we all have to experiment all the time during development. Good luck in your project!
9

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

Comments

8

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.

Comments

6

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

1 Comment

Simple fix: Do dismissDialog before every showDialog, just to be sure.
5

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

Comments

3

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

1 Comment

Beware of Motorola phones running Android 2.3.x. If the EditText is somewhere in a scrollable area, Motorola will automatically move focus around when you scroll. This means you may scroll down and when the EditText gains focus, your date dialog pops up, which is surprising and bad.
2

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

Comments

2

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.

Comments

2

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

Comments

0

For kotlin, you could use this

 editText!!.showSoftInputOnFocus = false 

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

For EditText or TextInputEditText Use the Below Properties

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.