DatePicker.OnDateChangedListener вызывается дважды

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

Мой графический интерфейс выглядит так:

<LinearLayout android:id="@+id/linearLayout1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" > <DatePicker android:id="@+id/datePicker" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="wrap_content" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" > </ListView> </LinearLayout> 

В то время как моя инициализация и обработка DatePicker выглядят следующим образом:

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); datePicker = (DatePicker) findViewById(R.id.datePicker); Calendar c = Calendar.getInstance(); year = c.get(Calendar.YEAR); month = c.get(Calendar.MONTH); day = c.get(Calendar.DAY_OF_MONTH); datePicker.init(year, month, day, dateSetListener); } private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { Calendar c = Calendar.getInstance(); c.set(year, monthOfYear, dayOfMonth); System.out.println ("TEST"); } }; 

В CatLog я вижу, что строка «TEST» выводится дважды, каждый раз, когда я играю с кнопками +/- на виджетах. В чем может быть проблема?

Примечание. Я специально отключил код для обновления списка, чтобы убедиться, что проблема не связана с ListView, как здесь

Solutions Collecting From Web of "DatePicker.OnDateChangedListener вызывается дважды"

Когда я тестирую свое приложение, метод onDateSet вызывается дважды после принятия выбора даты и один раз, когда я отменяю.

Я добавил проверку в методе onDateSet с представлением параметров, что-то вроде этого

 @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){ if (view.isShown()) { updateDate(year, monthOfYear, dayOfMonth); } } 

Надеюсь, вы служите

Мне все еще не удалось найти аккуратное решение. Я скорее нашел обходное решение, поэтому событие не срабатывает дважды. Обходной путь выглядит следующим образом:

 int timesCalled = 1; private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { Calendar c = Calendar.getInstance(); c.set(year, monthOfYear, dayOfMonth); timesCalled += 1; if ((timesCalled % 2) == 0) { System.out.println ("TEST"); } }}; 

Вместо обратного вызова onDateSet я переопределил метод onClick диалогового окна DatePickerDialog и обрабатывал только клики BUTTON_POSITIVE.

 public static class DatePickerFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Calendar c = Calendar.getInstance(); int initialYear = c.get(Calendar.YEAR); int initialMonth = c.get(Calendar.MONTH); int initialDay = c.get(Calendar.DAY_OF_MONTH); return new DatePickerDialog(getActivity(), null, initialYear, initialMonth, initialDay) { @Override public void onClick(DialogInterface dialog, int which) { if (which == BUTTON_POSITIVE) { int year = getDatePicker().getYear(); int month = getDatePicker().getMonth(); int day = getDatePicker().getDayOfMonth(); //TODO: Do your logic here } super.onClick(dialog, which); } }; } } 

Код остается ясным, но все же непонятно, почему onDateSet вызывается дважды.

 private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { Calendar c = Calendar.getInstance(); c.set(year, monthOfYear, dayOfMonth); updateDisplay(); } }; TextView datetext; datetext = (TextView) findViewById(R.id.selected_date); private void updateDisplay() { this.datetext.setText(new StringBuilder() // Month is 0 based so add 1 .append(mMonth + 1).append("-").append(mDay).append("-") .append(mYear).append(" ")); } 

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

 final DatePickerDialog datePickerDialog = new DatePickerDialog (this, new DatePickerDialog.OnDateSetListener() { private int year; private int month; private int day; @Override public void onDateSet (DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (this.year == year && this.month == monthOfYear && this.day == dayOfMonth) return; this.year = year; this.month = monthOfYear; this.day = dayOfMonth; calendar.set (year, month, day); int index = officeCalendar.indexOfKey (calendar.getTimeInMillis ()); if (index > -1) viewPager.setCurrentItem (index); } }, calendar.get (Calendar.YEAR), calendar.get (Calendar.MONTH), calendar.get (Calendar.DATE)); 
 private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() { boolean fired = false; public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (fired == true){ //Twince } else{ Calendar c = Calendar.getInstance(); c.set(year, monthOfYear, dayOfMonth); System.out.println ("TEST"); } } }; 

Пожалуйста, проверьте мой ответ здесь. Это для TimePickerDialog, но также применимо к DatePickerDialog. Вы можете создать настраиваемый диалог, он почти одинаково быстрый и простой и просто работает.

https://stackoverflow.com/a/25672760/940450

Не обязательно добавлять этот код под Jelly beans

 @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){ if (view.isShown()) { updateDate(year, monthOfYear, dayOfMonth); } } 

Имеет ту же проблему только в версии Android версии 4.2, она отлично работает с 2.2 (вызывает только прослушиватель дат). Я использую datepicker внутри диалоговогофрагмента, с обратным вызовом для действий. Чтобы «решить» проблему, я использовал то же обходное решение, что и вы, поэтому я поддержал ваш ответ, так как я не нашел объяснения.