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, как в здесь
Ответы
Ответ 1
Когда я тестирую свое приложение, метод onDateSet вызывается дважды после принятия выбора даты и один раз, когда я отменил.
Я добавил проверку в методе onDateSet с представлением параметров, что-то вроде этого
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){
if (view.isShown()) {
updateDate(year, monthOfYear, dayOfMonth);
}
}
Надеюсь, вы будете служить
Ответ 2
Мне все еще не удалось найти аккуратное исправление. Я скорее нашел обходное решение, поэтому событие не срабатывает дважды. Обходной путь выглядит следующим образом:
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");
}
}};
Ответ 3
Вместо обратного вызова 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 вызывается дважды.
Ответ 4
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(" "));
}
Ответ 5
Возможно, измените слушателя, добавив переменные экземпляра, таким образом, вы можете проверить, не отличаются ли они от последнего вызова метода:
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));
Ответ 6
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");
}
}
};
Ответ 7
Пожалуйста, проверьте мой ответ здесь. Это для TimePickerDialog, но также применимо к DatePickerDialog. Вы можете создать настраиваемый диалог, он почти одинаково быстрый и простой и просто работает.
fooobar.com/questions/116926/...
Ответ 8
Не нужно добавлять этот код под Jelly beans
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth){
if (view.isShown()) {
updateDate(year, monthOfYear, dayOfMonth);
}
}
Ответ 9
Имеет ту же проблему только в версии Android версии 4.2, она отлично работает с 2.2 (звонит слушателю даты только один раз). Я использую datepicker внутри диалогового фрагмента с обратным вызовом для действий. Чтобы "решить" проблему, я использовал одно и то же обходное решение, чем вы, поэтому я поддержал ваш ответ, так как я не нашел для него объяснений.