点击EditText打开DatePickerDialog需要两次点击才能打开

25

我希望在单击编辑文本时打开一个日历。然后,我想将用户从日历中选择的日期设置为编辑文本中的日期。问题是,只有当我第二次单击EditText时,才会打开日历。请帮助我解决这个问题(为什么第一次不会打开日历)。

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

我不理解我做错了什么,请给出解决方案。


@Raghunandan 我也遇到了同样的问题。在第二次点击后,日历会弹出,但之后它不会将值设置到编辑文本中。 - Developer
我提供的链接即使第二次点击也能正常工作,我认为这没有任何问题。 - Raghunandan
@Raghunandan,我的意思是第一次点击时它没有打开日历,在第二次点击时才打开了日历。所以你能否请看看我的代码有什么问题。 - Developer
هœ¨onCreateDialog监هگ¬ه™¨ن¸­è°ƒç”¨updateLabel();م€‚ - Mohsin Naeem
你需要调用 onDateChanged 方法来完成此编程任务。 - Mohsin Naeem
显示剩余6条评论
20个回答

39

我会尝试解决你的问题,但我不完全确定第一个原因。

  1. 选择日期时需要点击两次是因为你正在使用EditText。第一次点击时,你的EditText会获得焦点,只有第二次点击才会调用onClickListener。

    如果你不想手动编辑日期(使用键盘),为什么不使用TextView来显示所选日期呢?

  2. 在EditText中日期没有更新的问题是由于你没有在代码中设置DateSetListener。你需要设置它以通知系统日期已经被设置了。DateChangeListener只返回日期当你正在更改日期,并且你似乎没有将日期设置在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);
    }
};

在这里,我正在更新具有ID“tvDate”的TextView的日期。我建议使用TextView而不是EditText并尝试此代码。

更新

如果您需要使用EditText并在第一次单击时加载日历,则请尝试为editText设置onFocusListner而不是onClickListner。

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

1
我遇到了日期设置的问题。但是编辑文本框正在制造问题。你说得对,编辑文本框会导致焦点问题。但是肯定有一些方法可以在第一次调用 onClickListener。 - Developer
已更新答案,请查看。 - Arun Shankar
我想在单击编辑文本时打开日历。 - Developer
最好你把EditText替换为TextView,并给它添加一个onClickListener。如果你保留EditText,那么请尝试在更新中使用这段代码。请告知结果。 - Arun Shankar
你能帮我解决这个日历功能吗?https://dev59.com/WWMl5IYBdhLWcg3wmn_R#18272429?noredirect=1#18272429 - Developer
对我来说,datePickerListener未定义,因为它在下面声明。我加了修饰符private,但引起了另一个错误。 - Compaq LE2202x

15
在您的EditText中添加以下内容,以在第一次点击时打开日期选择器。 android:focusable="false"

在我看来,这是迄今为止最好的答案,因为它是唯一的非黑客方法。 - Automatico
即使我在EditText中有这个,它也不起作用。 - cafebabe1991
尝试使用此代码来防止点击编辑文本框时弹出键盘。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); } }); - Arun Inbasekaran

8
public class MainActivity extends Activity  {

 private Calendar cal;
 private int day;
 private int month;
 private int year;
 private EditText et;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

     et= (EditText) findViewById(R.id.edittext1);
      cal = Calendar.getInstance();
      day = cal.get(Calendar.DAY_OF_MONTH);
      month = cal.get(Calendar.MONTH);
      year = cal.get(Calendar.YEAR);


     et.setText(day+"/"+month+"/"+"/"+year);



      et.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            DateDialog(); 

        }
    });
     }


public void DateDialog(){

    OnDateSetListener listener=new OnDateSetListener() {

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

         et.setText(dayOfMonth+"/"+monthOfYear+"/"+year);

        }};

    DatePickerDialog dpDialog=new DatePickerDialog(this, listener, year, month, day);
    dpDialog.show();

}





}

6
在你的xml中,将focusable设置为false。
android:focusable="false"

5

只需要做这个

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

3

只需在您的EditText中使用此代码:

    android:focusable="false"

3

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

3

首先在您的活动中定义这些变量:

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

您还可以将这两种方法结合起来,在关闭日期选择器后打开时间选择器。

这些功能不需要使用插件。


2

尝试这段代码,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));
}

1
在你的EditText中添加这个。
 android:editable="false"
 android:focusable="false"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接