Открытие DatePickerDialog при нажатии EditText занимает два клика

Я хочу открыть Календарь по щелчку Редактировать текст. После этого я хочу установить дату, которую пользователь выбирает из календаря в тексте редактирования. Проблема в том, что только когда я нажимаю на EditText во второй раз, открывается календарь. Пожалуйста, помогите мне решить проблему (why calendar don't open for the first time).

EditText XML-код

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

Код действия

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

Я не понимаю, что я сделал не так. Пожалуйста, предложите решение.


person Developer    schedule 16.08.2013    source источник
comment
stackoverflow.com/questions/18211684/. проверьте это здесь, я использовал текстовое представление, чтобы установить дату в текст. изменить соответственно   -  person Raghunandan    schedule 16.08.2013
comment
@Raghunandan то же самое, что я сделал, первая проблема заключается в том, что при втором щелчке календарь открывается, после чего он не устанавливает значение в тексте редактирования.   -  person Developer    schedule 16.08.2013
comment
ссылка, которую я предоставил, работает даже для второго клика. я не вижу в этом проблемы   -  person Raghunandan    schedule 16.08.2013
comment
@Raghunandan, я говорю, что при первом нажатии календарь не открывается, во второй раз, когда я нажимаю, календарь открывается. Итак, не могли бы вы посмотреть, в чем проблема в моем коде?   -  person Developer    schedule 16.08.2013
comment
проверьте это developer.android.com/guide/topics/ui/controls/ pickers.html. использовать фрагмент средства выбора даты. вы можете проверить первый комментарий для справки   -  person Raghunandan    schedule 16.08.2013
comment
@Raghunandan В ЧЕМ ПРОБЛЕМА В МОЕМ КОДЕ   -  person Developer    schedule 16.08.2013
comment
Вы не вызываете updateLabel(); в OnDateSetListener диалогового окна. Вы вызываете не того слушателя date.   -  person Mohsin Naeem    schedule 16.08.2013
comment
вызовите updateLabel(); в прослушивателе onCreateDialog.   -  person Mohsin Naeem    schedule 16.08.2013
comment
если я сделаю это, он автоматически установит сегодняшнюю дату в editetx   -  person Developer    schedule 16.08.2013
comment
как? Вам нужно позвонить в onDateChanged   -  person Mohsin Naeem    schedule 16.08.2013
comment
не могли бы вы подсказать, почему при первом нажатии не открывается календарь   -  person Developer    schedule 16.08.2013


Ответы (18)


Я попытаюсь решить вашу проблему, но я не совсем уверен в первой причине.

  1. Календарь открывается только при втором щелчке, потому что вы используете текст редактирования. При первом щелчке ваш текст редактирования получит фокус. то второй щелчок вызывает только onClickListener.

    Если вы не хотите редактировать дату, установленную вручную (с помощью клавиатуры), то почему бы не использовать TextView для отображения выбранной даты?

  2. Проблема с датой, которая не обновляется в editText, возникает из-за того, что вы не устанавливаете DateSetListener в своем коде. Вам нужно установить это, чтобы уведомить систему о том, что дата была установлена. Слушатель DateChange возвращает дату только тогда, когда вы меняете дату, и не похоже, что вы устанавливаете дату в EditText.

Попробуйте этот код:

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

В этом я обновляю дату до TextView с идентификатором «tvDate». Я советую использовать TextView вместо EditText и попробовать этот код.

Обновлять

Если вам нужно использовать EditText и загрузить календарь в первый клик, попробуйте установить onFocusListner для editText вместо onClickListner.

editText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus) {
           // Show your calender here 
        } else {
           // Hide your calender here
        }
    }
});
person Arun Shankar    schedule 16.08.2013
comment
У меня возникла проблема с установкой даты. Но текст редактирования создает проблему. Вы правильно говорите, что текст редактирования создаст проблему фокуса. Но будет какой-то способ вызвать onClickListener в первый раз - person Developer; 16.08.2013
comment
Обновил ответ. пожалуйста, проверьте - person Arun Shankar; 16.08.2013
comment
я хочу, чтобы календарь открывался только при нажатии кнопки «Редактировать текст» - person Developer; 16.08.2013
comment
Тогда лучше заменить edittext на TextView и добавить к нему onClickListener. Если держите edittext, то попробуйте код в обновлении. Просьба сообщить результат - person Arun Shankar; 16.08.2013
comment
Можете ли вы помочь мне с этой функциональностью календаря установить ограничение на диалог выбора даты в android "> stackoverflow.com/questions/18272306/ - person Developer; 16.08.2013
comment
Для меня datePickerListener не определено, так как оно было объявлено ниже. Я поставил модификатор private, но это вызвало другую ошибку. - person Compaq LE2202x; 19.12.2013

Добавьте это в свой текст редактирования, чтобы открыть средство выбора даты при первом нажатии. android:focusable="false"

person Arun Inbasekaran    schedule 12.06.2015
comment
На мой взгляд, это лучший ответ, поскольку это единственный подход без взлома. - person Automatico; 30.09.2015
comment
Несмотря на то, что у меня есть это в моем тексте редактирования, это не сработает. - person cafebabe1991; 18.11.2015
comment
Попробуйте этот код, чтобы ограничить появление клавиатуры при щелчке текстового поля редактирования. edittext.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0);} }); - person Arun Inbasekaran; 19.11.2015

В вашем xml установите для фокуса значение false

android:focusable="false"
person Prakash    schedule 05.01.2018

Просто сделай это

//Open the DatePicker dialgo in one click and also hide the soft keyboard.
youEditText.setInputType(InputType.TYPE_NULL);
youEditText.requestFocus();
person Lavekush Agrawal    schedule 01.10.2014

используйте setOnFocusChangeListener вместо OnCLickListner. Следующий код является примером, который я использую для той же цели.

editText_dob.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if(hasFocus){
                hideSoftKeyboard(RegisterationActivity.this);
                editText_dob.setRawInputType(InputType.TYPE_CLASS_TEXT);
                setDate(editText_dob);
            }
        }
    });
person Shafqat Jamil Khan    schedule 06.10.2016

сначала определите эти переменные в своей деятельности

    import android.app.AlertDialog;
    import android.app.DatePickerDialog;
    import android.app.TimePickerDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.util.Log;
    import android.view.View;
    import android.widget.DatePicker;
    import android.widget.TimePicker;

    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;

public class MainActivity extends Activity  {

    private int mYear, mMonth, mDay, mHour, mMinute;

затем использует эти методы:

1) для открытого модального окна выбора ДАТЫ

            public void openDatePicker() {
                // Get Current Date
                final Calendar c = Calendar.getInstance();
                mYear  = c.get(Calendar.YEAR);
                mMonth = c.get(Calendar.MONTH);
                mDay   = c.get(Calendar.DAY_OF_MONTH);
                //launch datepicker modal
                DatePickerDialog datePickerDialog = new DatePickerDialog(this,
                        new DatePickerDialog.OnDateSetListener() {
                            @Override
                            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                                Log.d(APIContanst.LOG_APP, "DATE SELECTED "+dayOfMonth + "-" + (monthOfYear + 1) + "-" + year);
                                //PUT YOUR LOGING HERE
                                //UNCOMMENT THIS LINE TO CALL TIMEPICKER
                               //openTimePicker();
                            }
                        }, mYear, mMonth, mDay);
                datePickerDialog.show();
            }

2) для открытого модального окна выбора времени

            public void openTimePicker() {
                // Get Current Time
                final Calendar c = Calendar.getInstance();
                mHour            = c.get(Calendar.HOUR_OF_DAY);
                mMinute          = c.get(Calendar.MINUTE);
                //launch timepicker modal
                TimePickerDialog timePickerDialog = new TimePickerDialog(this,
                        new TimePickerDialog.OnTimeSetListener() {
                            @Override
                            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                                Log.d(APIContanst.LOG_APP, "TIME SELECTED "+hourOfDay + "-" + minute + "-");
                            //PUT YOUR LOGIC HERE
                            }
                        }, mHour, mMinute, false);
                timePickerDialog.show();
            }

также вы можете комбинировать два метода, чтобы открыть средство выбора времени после закрытия средства выбора даты.

Эти функции не требуют использования плагина

person Deyson    schedule 03.11.2016

Попробуйте этот код 100% работает

ЗАПИСАТЬ ЭТО В ONCREATE

et_dob.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            showDialog(DATE_DIALOG_ID);
        }

    });
    final Calendar calendar = Calendar.getInstance();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    if (et_dob.getText().toString() != null) {
        try {
            calendar.setTime(df.parse(et_dob.getText().toString()));
        } catch (java.text.ParseException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        mYear = calendar.get(Calendar.YEAR);
        mMonth = calendar.get(Calendar.MONTH);
        mDay = calendar.get(Calendar.DAY_OF_MONTH);
        SimpleDateFormat month_date = new SimpleDateFormat("MMM");
        month = month_date.format(calendar.getTime());
    } else {
        mYear = calendar.get(Calendar.YEAR);
        mMonth = calendar.get(Calendar.MONTH);
        mDay = calendar.get(Calendar.DAY_OF_MONTH);
        SimpleDateFormat month_date = new SimpleDateFormat("MMM");
        month = month_date.format(calendar.getTime());
    }

    if (cal_currentTime.compareTo(calendar) > 0)
        updateDisplay();

И ВСТАВЬТЕ ОСТАВШИЙСЯ КОД В ВАШ КЛАСС

static final int DATE_DIALOG_ID = 1;
private int mYear;
private int mMonth;
private int mDay;
private String month;
private String dateOfBirth;


@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DATE_DIALOG_ID:
        return new DatePickerDialog(this, mDateSetListener, mYear, mMonth,
                mDay);
    }
    return null;
}

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
    switch (id) {
    case DATE_DIALOG_ID:
        ((DatePickerDialog) dialog).updateDate(mYear, mMonth, mDay);
        break;
    }
}

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

    public void onDateSet(DatePicker view, int year, int monthOfYear,
            int dayOfMonth) {
        mYear = year;
        mMonth = monthOfYear;
        mDay = dayOfMonth;

        String dateSetter = (new StringBuilder().append(mYear).append("-")
                .append(mMonth + 1).append("-").append(mDay).append(""))
                .toString();
        final Calendar cal = Calendar.getInstance();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        if (dateSetter != null) {
            try {
                cal.setTime(df.parse(dateSetter));
            } catch (java.text.ParseException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            SimpleDateFormat month_date = new SimpleDateFormat("MMM");
            month = month_date.format(cal.getTime());
        }

        if (cal_currentTime.compareTo(cal) > 0)
            updateDisplay();
        else
            Toast.makeText(context, "Choose Proper date format",
                    Toast.LENGTH_SHORT).show();
    }
};

чтобы загрузить его для редактирования текста

private void updateDisplay() {
    dateOfBirth = (new StringBuilder()
            // Month is 0 based so add 1
            .append(mYear).append("-").append(mMonth + 1).append("-")
            .append(mDay).append("")).toString();
    et_dob.setText(new StringBuilder()
            // Month is 0 based so add 1
            .append(mDay).append("-").append(month).append("-")
            .append(mYear));
}
person Kartheek s    schedule 16.08.2013

Просто используйте это в своем EditText

    android:focusable="false"
person RatneZ    schedule 21.04.2016

Добавьте это в свой XML-файл EditText:

    android:clickable="false" 
    android:cursorVisible="false" 
    android:focusable="false" 
    android:focusableInTouchMode="false">

Таким образом, он будет работать как текстовое представление

person Touseef Ahmed    schedule 30.12.2015

первым делом добавьте android:focusable="false" в xml. В коде Java установите только событие:

case R.id.edt_d_o_birth: {
            KeyboardUtils.hideSoftKeyboard(this);
            Calendar calendar = Calendar.getInstance(Locale.getDefault());
            DatePickerDialog datePickerDialog = new DatePickerDialog(RegisterActivity.this,
                    new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                    //todo       
                }
            },calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),calendar.get(Calendar.DAY_OF_MONTH));
            datePickerDialog.show();
            break;
        }
person Hai Rom    schedule 10.04.2017

100 % рабочий код

Реализовать implements View.OnClickListener

Внутри onCreate YourEditText.setOnClickListener(this);

@Override
    public void onClick(View v) {

        if (v == YourEditText) {

            // Get Current Date
            final Calendar c = Calendar.getInstance();
            mYear = c.get(Calendar.YEAR);
            mMonth = c.get(Calendar.MONTH);
            mDay = c.get(Calendar.DAY_OF_MONTH);


            DatePickerDialog datePickerDialog = new DatePickerDialog(this,
                    new DatePickerDialog.OnDateSetListener() {

                        @Override
                        public void onDateSet(DatePicker view, int year,
                                              int monthOfYear, int dayOfMonth) {

                            YourEditText.setText(dayOfMonth + "-" + (monthOfYear + 1) + "-" + year);

                        }
                    }, mYear, mMonth, mDay);
            datePickerDialog.show();
        }
}
person Harsh Singhal    schedule 02.05.2017

Добавьте это в свой EditText

 android:editable="false"
 android:focusable="false"
person Mehtab    schedule 10.10.2017

В файле layout.xml добавьте свойство android:focusable=false, это точно сработает

person uttam kumar sharma    schedule 08.03.2019

В файле XML добавьте свойство android:focusableInTouchMode="false" :

 <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusableInTouchMode="false"
        android:hint="Some text"/>
person Joseph Mathai    schedule 18.07.2019
comment
Добавление свойства уже было предложено в других ответах. Это не вносит ничего нового. - person Cindy Meister; 18.07.2019
comment
Другие предлагали несколько свойств, но это не обязательно. Вот почему я упомянул только этот android:focusableInTouchMode=false. - person Joseph Mathai; 18.07.2019

попробуй эти

         <EditText
            android:id="@+id/et_mDate"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="false"
            android:cursorVisible="false"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:hint="Enter A Date in dd/mm/YYYY "
            android:inputType="date"
            android:padding="8dp" />
person Ashif    schedule 05.02.2020

Благодаря Lavekush Agrawal, это работает для меня, просто напишите это в своем методе onCreate.

register_birthday.setInputType(InputType.TYPE_NULL);
register_birthday.requestFocus();
person Vicentex360    schedule 01.05.2020
comment
Поскольку это то же самое, что и уже данный ответ, лучший способ подтвердить этот ответ - проголосовать за существующий ответ @ Lavekush-Agrawal. Это помогает сфокусировать раздел ответов, а также повышает репутацию Лавекуша, тем самым вознаграждая участников, публикующих полезные сообщения. - person Tad Wohlrapp; 01.05.2020

проблема в том, что ваш текст редактирования фокусируется на первом щелчке, а затем при втором щелчке применяется событие щелчка. поэтому вам просто нужно установить фокус по умолчанию или, как я сделал это в xml, добавить один атрибут, как показано ниже:

android:focusableInTouchMode="false"

в sort замените свой xml ниже и повторите попытку:

<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:focusableInTouchMode="false"
        android:hint="dd/mm/yyyy" />
person harsh patel    schedule 22.10.2020

Если вы хотите открыть диалоговое окно в тексте редактирования одним щелчком мыши. Примерьте вот это.

editTextNmae.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
    if(hasFocus) {
       // call Date dialog box... 
    } else {
       // Hide Hide dialog box....
    }
}

});

person Vikrant Singh Rawat    schedule 20.05.2021