Open a DatePickerDialog on Click of EditText takes two clicks

Developer picture Developer · Aug 16, 2013 · Viewed 69.2k times · Source

I want to open a Calendar on the click of Edit text. After that I want to set the date which the user selects from the Calendar in the edit text. Problem is that, only when I click on the EditText for the second time then the calendar open. Please help me to resolve the issue(why calendar don't open for the first time).

EditText XML code

<EditText
            android:id="@+id/dateofBirth"
            android:layout_width="290dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="10dp"
            android:maxLines="1"
            android:hint="dd/mm/yyyy" />

Activity Code

public void informationPopUp() {
        final Dialog dialog= new Dialog(MainActivity.this,R.style.Dialog_Fullscreen);
        dialog.setContentView(R.layout.details_dialog); 
        dateofBirth = (EditText)dialog.findViewById(R.id.dateofBirth);

        dialog.show();
         myCalendar = Calendar.getInstance();

       final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {

            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear,
                    int dayOfMonth) {
                // TODO Auto-generated method stub
                myCalendar.set(Calendar.YEAR, year);
                myCalendar.set(Calendar.MONTH, monthOfYear);
                myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                updateLabel();
            }


        };

        dateofBirth.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                showDialog(DATE_DIALOG_ID);
              }
        });

    }
     private void updateLabel() {
         String myFormat = "MM/dd/yy"; //In which you need put here
         SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
         dateofBirth.setText(sdf.format(myCalendar.getTime()));
     }

     protected Dialog onCreateDialog(int id) {
            final Calendar now = Calendar.getInstance();

            switch (id) {
            case DATE_DIALOG_ID:
                // set date picker as current date
                DatePickerDialog _date =   new DatePickerDialog(this, date,myCalendar
                        .get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
                        myCalendar.get(Calendar.DAY_OF_MONTH)){
                    @Override

                    public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth){   

                        if (year > now.get(Calendar.YEAR))

                            view.updateDate(myCalendar
                                    .get(Calendar.YEAR), myCalendar
                                    .get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH));

                        if (monthOfYear > now.get(Calendar.MONTH) && year == now.get(Calendar.YEAR))
                            view.updateDate(myCalendar
                                    .get(Calendar.YEAR), myCalendar
                                    .get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH));

                        if (dayOfMonth > now.get(Calendar.DAY_OF_MONTH) && year == now.get(Calendar.YEAR) && 
                                monthOfYear == now.get(Calendar.MONTH))
                            view.updateDate(myCalendar
                                    .get(Calendar.YEAR), myCalendar
                                    .get(Calendar.MONTH), myCalendar.get(Calendar.DAY_OF_MONTH));
                            }
                };
                return _date;
            }
            return null;
        } 

I am not understanding what I have done wrong. Please suggest a solution.

Answer

Arun Shankar picture Arun Shankar · Aug 16, 2013

I'll try to address your problem, but I am not completely sure about the first reason.

  1. The calendar opening only on the second click is because you are using an edittext. On the first click, your Edit Text will get focus. then the second click only calls the onClickListener.

    If you are not looking forward to edit the date set manually (using keyboard), then why not using a TextView to display the selected Date?

  2. The problem with the date not updating in editText is occurring because you are not setting the DateSetListener in your code. You need to set that to notify the system that a Date was set. The DateChange listener only returns the date while you are changing the date, and it doesn't appear that you are setting the date in the EditText.

Try this code:

            Calendar cal = Calendar.getInstance(TimeZone.getDefault());
            DatePickerDialog datePicker = new DatePickerDialog(this,
                R.style.AppBlackTheme,
                datePickerListener,
                cal.get(Calendar.YEAR), 
                cal.get(Calendar.MONTH),
                cal.get(Calendar.DAY_OF_MONTH));

            datePicker.setCancelable(false);
            datePicker.setTitle("Select the date");

            return datePicker;
        }
    } catch (Exception e) {
        showMsgDialog("Exception",
            "An error occured while showing Date Picker\n\n"
            + " Error Details:\n" + e.toString(), "OK");
    }
    return null;
}


private DatePickerDialog.OnDateSetListener datePickerListener = new DatePickerDialog.OnDateSetListener() {

    // when dialog box is closed, below method will be called.
    public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {
        String year1 = String.valueOf(selectedYear);
        String month1 = String.valueOf(selectedMonth + 1);
        String day1 = String.valueOf(selectedDay);
        TextView tvDt = (TextView) findViewById(R.id.tvDate);
        tvDt.setText(day1 + "/" + month1 + "/" + year1);
    }
};

In this, I am updating the date to a TextView with the ID "tvDate". I advise using a TextView instead of EditText and try this code.

Update

If you need to use EditText and load the calender in the first click, then try setting an onFocusListner to the editText instead of onClickListner.

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus) {
           // Show your calender here 
        } else {
           // Hide your calender here
        }
    }
});