当前位置: 首页 > 知识库问答 >
问题:

果冻豆日期选择器对话---有办法取消吗?

巩俊远
2023-03-14

---主持人注意:今天(7月15日),我注意到这里已经有人面临这个问题。但我不确定是否适合将此作为副本关闭,因为我认为我对该问题提供了更好的解释。我不确定我是否应该编辑另一个问题并将此内容粘贴到那里,但我不愿意太多地更改其他人的问题---

我有点奇怪。

我认为问题不取决于您基于哪个SDK构建。重要的是设备操作系统的版本。

DatePickerDialog已更改(?)在果冻豆中,现在只提供完成按钮。以前的版本包括取消按钮,这可能会影响用户体验(不一致,肌肉记忆从以前的Android版本)。

复制:创建一个基本项目。在创建时将其放入onCreate

DatePickerDialog picker = new DatePickerDialog(
        this,
        new OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker v, int y, int m, int d) {
                Log.d("Picker", "Set!");
            }
        },
        2012, 6, 15);
picker.show();

预期:对话框中会出现“取消”按钮。

当前:取消按钮不会出现。

截图:4.0.3(OK)和4.1.1(可能有误?)。

对话框调用它真正应该调用的侦听器,然后始终调用OnDateSetListenerlistener。取消仍然调用set方法,而设置它调用该方法两次。

复制:使用#1代码,但在下面html" target="_blank">添加代码(您将看到这解决了#1,但仅在视觉上/UI):

picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d("Picker", "Cancel!");
            }
        });

预期:

  • 按后退键或在对话框外单击不应执行任何操作

当前:

  • 按BACK键或单击对话框外打印Picker Set!.
  • 按下取消打印选择器取消!然后是Picker Set!.
  • 按下设置打印拾取器设置!然后是Picker Set!.

显示行为的日志行:

07-15 12:00:13.415: D/Picker(21000): Set!

07-15 12:00:24.860: D/Picker(21000): Cancel!
07-15 12:00:24.876: D/Picker(21000): Set!

07-15 12:00:33.696: D/Picker(21000): Set!
07-15 12:00:33.719: D/Picker(21000): Set!
  • DatePickerFragment包装它并不重要。我为你简化了这个问题,但我已经测试过了

共有3个答案

郭永安
2023-03-14

在修复错误之前,我建议不要使用DatePickerDialog或TimePickerDialog。使用定制的AlertDialog和TimePicker/DatePicker小部件;

更改TimePickerDialog与;

    final TimePicker timePicker = new TimePicker(this);
    timePicker.setIs24HourView(true);
    timePicker.setCurrentHour(20);
    timePicker.setCurrentMinute(15);

    new AlertDialog.Builder(this)
            .setTitle("Test")
            .setPositiveButton(android.R.string.ok, new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.d("Picker", timePicker.getCurrentHour() + ":"
                            + timePicker.getCurrentMinute());
                }
            })
            .setNegativeButton(android.R.string.cancel,
                    new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                int which) {
                            Log.d("Picker", "Cancelled!");
                        }
                    }).setView(timePicker).show();

将DatePickerDialog更改为;

    final DatePicker datePicker = new DatePicker(this);
    datePicker.init(2012, 10, 5, null);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        datePicker.setCalendarViewShown(false);
    }

    new AlertDialog.Builder(this)
            .setTitle("Test")
            .setPositiveButton(android.R.string.ok, new OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.d("Picker", datePicker.getYear() + " "
                            + (datePicker.getMonth() + 1) + " "
                            + datePicker.getDayOfMonth());
                }
            })
            .setNegativeButton(android.R.string.cancel,
                    new OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog,
                                int which) {
                            Log.d("Picker", "Cancelled!");
                        }
                    }).setView(datePicker).show();
隗高旻
2023-03-14

我将在David Cesarino发布的解决方案上添加我自己的即兴片段,以防您不使用Fragments,并希望在所有版本(2.1到4.1)中找到一种简单的方法来修复它:

public class FixedDatePickerDialog extends DatePickerDialog {
  //I use a Calendar object to initialize it, but you can revert to Y,M,D easily
  public FixedDatePickerDialog(Calendar dateToShow, Context context, OnDateSetListener callBack) {
    super(context, null, dateToShow.get(YEAR), dateToShow.get(MONTH), dateToShow.get(DAY_OF_MONTH));
    initializePicker(callBack);
  }

  public FixedDatePickerDialog(Calendar dateToShow, Context context, int theme,
    OnDateSetListener callBack) {
    super(context, theme, null, dateToShow.get(YEAR), dateToShow.get(MONTH), dateToShow.get(DAY_OF_MONTH));
    initializePicker(callBack);
  }

  private void initializePicker(final OnDateSetListener callback) {
    try {
      //If you're only using Honeycomb+ then you can just call getDatePicker() instead of using reflection
      Field pickerField = DatePickerDialog.class.getDeclaredField("mDatePicker");
      pickerField.setAccessible(true);
      final DatePicker picker = (DatePicker) pickerField.get(this);
      this.setCancelable(true);
      this.setButton(DialogInterface.BUTTON_NEGATIVE, getContext().getText(android.R.string.cancel), (OnClickListener) null);
      this.setButton(DialogInterface.BUTTON_POSITIVE, getContext().getText(android.R.string.ok),
          new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                picker.clearFocus(); //Focus must be cleared so the value change listener is called
                callback.onDateSet(picker, picker.getYear(), picker.getMonth(), picker.getDayOfMonth());
              }
          });
    } catch (Exception e) { /* Reflection probably failed*/ }
  }
}
南宫阳冰
2023-03-14

注:固定为Lollipop,来源于此。客户端使用的自动类(与所有Android版本兼容)也已更新。

>

Bundle b = new Bundle();
b.putInt(DatePickerDialogFragment.YEAR, 2012);
b.putInt(DatePickerDialogFragment.MONTH, 6);
b.putInt(DatePickerDialogFragment.DATE, 17);
DialogFragment picker = new DatePickerDialogFragment();
picker.setArguments(b);
picker.show(getActivity().getSupportFragmentManager(), "frag_date_picker");

这就是一切!我仍然将答案保留为“已接受”的原因是,我仍然更喜欢我的解决方案,因为它在客户端代码中占用的空间非常小,它解决了基本问题(在框架类中调用侦听器),在配置更改中工作良好,它将代码逻辑路由到以前的Android版本中的默认实现,而没有受到此错误的困扰(请参阅类源代码)。

好的,看起来这确实是一个bug,其他人已经填充了它。第34833期。

我发现问题可能出在DatePickerDialog中。java。内容如下:

private void tryNotifyDateSet() {
    if (mCallBack != null) {
        mDatePicker.clearFocus();
        mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(),
                mDatePicker.getMonth(), mDatePicker.getDayOfMonth());
    }
}

@Override
protected void onStop() {
    tryNotifyDateSet();
    super.onStop();
}

我猜可能是:

@Override
protected void onStop() {
    // instead of the full tryNotifyDateSet() call:
    if (mCallBack != null) mDatePicker.clearFocus();
    super.onStop();
}

现在,如果有人能告诉我如何向Android提交补丁/bug报告,我很乐意。同时,我提出了一个可能的解决方案(简单),作为DatePickerDialog的附加版本。java在那里的问题上。

在构造器中将侦听器设置为null,然后创建自己的按钮\u POSITIVE按钮。就这样,详情如下。

出现此问题的原因是DatePickerDialog。正如您在源代码中看到的,java调用了一个全局变量(mCallBack),该变量存储在构造函数中传递的侦听器:

    /**
 * @param context The context the dialog is to run in.
 * @param callBack How the parent is notified that the date is set.
 * @param year The initial year of the dialog.
 * @param monthOfYear The initial month of the dialog.
 * @param dayOfMonth The initial day of the dialog.
 */
public DatePickerDialog(Context context,
        OnDateSetListener callBack,
        int year,
        int monthOfYear,
        int dayOfMonth) {
    this(context, 0, callBack, year, monthOfYear, dayOfMonth);
}

    /**
 * @param context The context the dialog is to run in.
 * @param theme the theme to apply to this dialog
 * @param callBack How the parent is notified that the date is set.
 * @param year The initial year of the dialog.
 * @param monthOfYear The initial month of the dialog.
 * @param dayOfMonth The initial day of the dialog.
 */
public DatePickerDialog(Context context,
        int theme,
        OnDateSetListener callBack,
        int year,
        int monthOfYear,
        int dayOfMonth) {
    super(context, theme);

    mCallBack = callBack;
    // ... rest of the constructor.
}

因此,诀窍是提供一个null监听器存储为监听器,然后滚动您自己的一组按钮(下面是#1中的原始代码,已更新):

    DatePickerDialog picker = new DatePickerDialog(
        this,
        null, // instead of a listener
        2012, 6, 15);
    picker.setCancelable(true);
    picker.setCanceledOnTouchOutside(true);
    picker.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d("Picker", "Correct behavior!");
            }
        });
    picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
        new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d("Picker", "Cancel!");
            }
        });
picker.show();

现在它将工作,因为我上面发布的可能的更正。

以及自DatePickerDialog以来。java在读取mCallback时检查null(从API 3/1.5的时代开始,它似乎——当然不能检查),它不会触发异常。考虑到Lollipop解决了这个问题,我不打算研究它:只需使用默认实现(在我提供的类中介绍)。

起初我担心不能调用clearFocus(),但我在这里进行了测试,日志行是干净的。所以我提议的那条线可能根本就没有必要,但我不知道。

正如我在下面的评论中指出的,这是一个概念,你可以从我的Google Drive帐户下载我正在使用的类。按照我使用的方式,默认系统实现用于不受bug影响的版本。

我采取了一些适合我需要的假设(按钮名称等),因为我想将客户机类中的样板代码减少到最低限度。完整使用示例:

class YourActivity extends SherlockFragmentActivity implements OnDateSetListener

// ...

Bundle b = new Bundle();
b.putInt(DatePickerDialogFragment.YEAR, 2012);
b.putInt(DatePickerDialogFragment.MONTH, 6);
b.putInt(DatePickerDialogFragment.DATE, 17);
DialogFragment picker = new DatePickerDialogFragment();
picker.setArguments(b);
picker.show(getActivity().getSupportFragmentManager(), "fragment_date_picker");

 类似资料:
  • 我在活动中使用了一个类来创建日期选择器对话框,它一直在工作,直到我迁移到android studio。以下是课程: 类StartDatePicker现在引发了一个错误:这个片段类应该是公共的。在我将其声明为public之后,它引发了另一个错误:这个片段内部类应该是静态的。我不想将其声明为静态的,因为私有void showDate(int year,int month,int day,int day

  • 我正在尝试实现日期选择器对话框,但该对话框显示只有一个日期,并显示日期的其余部分为空白,这可能是什么原因?

  • 我已经记录了用于从日期选择器中选择日期的selenium代码。在运行测试用例时,日期选择器会弹出并正确突出显示所选日期。但是没有选择日期。代码如下所示:- 此异常仅出现在记录的代码中。我使用的是selenium-server-standalone-2 . 45 . 0 jar。

  • 我正在使用媒体编解码器在jelly-bean上获取. mp4文件并在logcat中获取此文件 谁能告诉我这是什么吗?如何解决呢?

  • HTML与它的外观截图一起粘贴,如下所示。 HTML: 我曾经试过 甚至试图等待命令以使定位器被找到但没有成功。 WebDriverWait(驱动程序,100)。直到(预期条件.element可禁用)(By.css选择器 两者都不起作用,因为它无法识别元素。有人能帮我吗。如果可能,我们甚至可以单击“上一个”和“下一个”,以便我们也可以单击一些以前的日期吗?

  • 我试图在Android中创建一个日期对象,从日期选择器和时间选择器。我知道如何单独进行,但当我想使用日期选择器和时间选择器创建单个日期对象时 我试过这个 但是没有运气,因为它已被弃用。有人能给我指出一个资源吗?