如何使用DialogFragment和FragmentManager制作一个日期选择器?

4

我做这个已经有一段时间了,但似乎无法弄清楚。我对Android开发不太熟悉,请谅解。我之前不太了解如何创建日期选择器,所以学会了使用过时的方法来试试。我用了这篇教程来加快速度:

http://developer.android.com/resources/tutorials/views/hello-datepicker.html

但现在我需要改变它,主要是不再使用过时的代码,所以我四处寻找,找到了两篇教程,尤其是这一篇:

http://www.kylebeal.com/2011/11/android-datepickerdialog-and-the-dialogfragment/

问题是,有些代码看起来很奇怪,特别是这部分:

//create new DateDialogFragment
DateDialogFragment ddf = DateDialogFragment.newInstance(this, R.string.set_date, date);

ddf.setDateDialogFragmentListener(new DateDialogFragmentListener() {

    @Override
    public void dateDialogFragmentDateSet(Calendar date) {
        // update the fragment
        mDateDetailFragment.updateDate(date);
    }
});

ddf.show(getSupportFragmentManager(), "date picker dialog fragment");

那应该是在它运行的活动类中运行的。所以我有点明白代码的其余部分正在发生什么,随时可以查看其余部分,因为这可能会有所帮助。该代码基本上遵循与原始showDialog()代码几乎相同的路线。实现DatePickerDialog.onDateSetListener,并返回一个新的DatePickerDialog,唯一显而易见的例外是它使用了DialogFragment。但这就是我迷失的地方。部分原因是因为我不确定onCreateDialog()返回新的DatePickerDialog的位置。如果您查看我说不合理的代码,mDateDetailFragment和getSupportFragmentManager()都没有被实例化或出现在其他任何地方,所以我无法使教程代码正常工作。Android文档还提到,应该使用DialogFragment和FragmentManager而不是使用showDialog(),但此处只使用了DialogFragment。所以,像标题一样,我应该如何以非过时的形式创建DatPicker?我请不要让我去链接,只是说看这里。我已经这样做了。相信我。如果没有,至少解释一下我错过了什么,使这一切都有意义。另外,如果有人能告诉我onCreateDialog()方法将DatePickerDialog发送到哪里,那将非常有帮助。我只是想弄清楚所有这些,而不是复制和粘贴代码(即使它也无法工作)。非常感谢您抽出时间阅读这篇文章,如果需要任何澄清,请询问。
3个回答

4

根据您的帖子顺序:

1) onCreateDialog返回对话框到DialogFragment。

2) 我不知道mDateDetailFragment.updateDate(date);这一行……我认为他可能遗漏了一些代码。 编辑 找到了它,在他完整演示的zip文件的其中一个类中。

3) 您正在使用片段管理器(这是getSupportFragmentManager()部分):

ddf.show(getSupportFragmentManager(), "date picker dialog fragment");

好的,话说回来,以下是我如何实现它的(我使用了一个DateSlider,但是用一个Datepicker代替应该对你来说很简单)。

在调用DialogFragment的碎片/活动中:

DialogFragment newFragment = new DateDialog();
newFragment.show(getFragmentManager(), "dialog"); 

我的DialogFragment:

public class DateDialog extends DialogFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    private DateSlider.OnDateSetListener mDateSetListener = new DateSlider.OnDateSetListener() {
        public void onDateSet(DateSlider view, Calendar selectedDate) {
            MemberAddFragment.startTxt.setText(String.format("%tB %te, %tY", selectedDate, selectedDate, selectedDate));
        }
    };

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Calendar c = Calendar.getInstance();  // Get calendar instance to use in DateSlider
        return new AlternativeDateSlider(getActivity(),mDateSetListener,c,null,null);  // return DateSlider dialog to DialogFragment
    }
}

希望这能帮助你消除困惑。

非常感谢你所花费的时间!有一件事我不理解,getSupportFragmentManager()是如何获取FragmentManager的?这个在他的代码中吗?我应该已经注意到了。我感觉自己太蠢了。 - Andy
这就是片段管理器(在使用支持库时)。如果您不使用支持库,则应该是 getFragmentManager。无论使用哪个版本,都是调用框架来提供片段管理器。 - Barak
算了,我找到了。Activity类。我没有假设。 - Andy
我不想打扰你,但我一直在试图理解这段代码,但由于我从未使用过片段,我真的不知道它们如何组合起来与DatePickerDialog一起工作。既然你已经看过代码,能否帮助我找出哪些类实际上直接与DatePicker一起工作,以便我可以专注于那个部分。我只是不知道实际上是什么在相互作用。再次抱歉如果我打扰到你了。 - Andy

3
我知道这个问题已经有答案了,但我想为其他遇到同样问题的人添加自己的答案。我将我之前提供的示例代码简化成了只有两个类。Kbeal很慷慨地提供了教程,做得非常好,但是包含了许多不必要的信息。所以,根据我对对话框的了解以及从Kbeal的教程和关于片段的研究中所学到的内容,我在GitHub上提供了一个DatePickerDialog的实现。 https://github.com/Zeroe31890/DateDialogFragment 你只需要复制粘贴这两个类、一个布局文件和修改Android清单文件,就能够直接运行它。比其他教程都要简单得多。如果有任何可以改进的地方,请指出。享受吧!

这个例子比我找到的其他例子更接近在屏幕旋转时工作(大多数崩溃而不是仅更新调用活动的值失败)。虽然牺牲了灵活性,但通过传递按钮的ID而不是回调,并在 onDateSet() 中使用 getActivity.findViewById() 获取按钮以便调用 setText(),我能够使它适合我的目的。 - Dan Is Fiddling By Firelight

0

帖子的作者在这里:听起来你已经全部弄清楚了。我在找到这篇文章之前回答了你在我的帖子中的问题,不过Barak已经很好地回答了它们。如果你还没有这样做,请下载示例应用程序的完整源代码。我认为这将有助于填补你仍然存在的任何遗漏。


所以我最终有机会去看一眼。我知道为什么我困惑了。我肯定越来越好,但我从未使用过片段,DatePicker如何与之配合现在更让我困惑了lol。我会继续吸收并分解它,以便更清楚地理解它,因为我需要学习它,但如果您有机会给我发送电子邮件(我在您的博客上提供了),并帮助我更彻底地解决问题,那将是很棒的。如果没有,我完全理解,并且非常感谢这篇文章一开始就帮了我很多忙。祝您拥有美好的一天。 - Andy

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