《Android权威编程指南》挑战练习:更多对话框

问题:首先看一个简单的练习。另写一个名为 TimePickerFragment 的对话框fragment,允许用户使用 TimePicker 组件选择crime发生的具体时间。在 CrimeFragment 用户界面上再添加一个按钮,以显示 TimePickerFragment 视图界面。


1:首先创建dialog_time.xml视图,内容为

<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialog_date_picker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:calendarViewShown="false">

</DatePicker>

2:在fragment_crime.xml中添加按钮

    <Button
        android:id="@+id/crime_time"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

3:直接复制一份DatePickerFragment.class来修改,大多都是差不多的

4:首先思考一下,Date对象是包含日期和时间的,所以修改的时候只修改时间就可以了

按照流程,打开CrimeFragment页面时,按钮上必须显示时间,新增一个updateTime方法,

直接在CrimeFragment#onCreateView方法中调用

  private void updateTime() {
        mTimeButton.setText(DateFormat.format("h:mm a", mCrime.getDate()));
    }

用来顺便指定时间显示的格式

5:点击按钮后弹出TimePicker对话框,需要显示刚刚按钮上显示的时间

TimePickerFragment#onCreateDialog

        Date date = (Date) getArguments().getSerializable(ARG_DATE);     //获取从前一个fragment传进来的date
        final Calendar calendar = Calendar.getInstance();                //获得日历
        calendar.setTime(date);                                            更正日历的时间为Crime对象的时间

        final int year = calendar.get(Calendar.YEAR);                    //获取Crime对象的日期的年月日时分
        final int month = calendar.get(Calendar.MONTH);
        final int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mTimePicker.setHour(hour);                                //设置时间选择器对话框的
            mTimePicker.setMinute(minute);
        } else {
            mTimePicker.setCurrentHour(hour);
            mTimePicker.setCurrentMinute(minute);
        }
CrimeFragment#onCreateView

  private Button mTimeButton;                                            //定义全局按钮
   mTimeButton = v.findViewById(R.id.crime_time);                        //实例化视图按钮
        mTimeButton.setOnClickListener(new View.OnClickListener() {       
            @Override
            public void onClick(View v) {
                FragmentManager manager = getFragmentManager();
                TimePickerFragment dialog = TimePickerFragment.newInstance(mCrime.getDate());
                dialog.setTargetFragment(CrimeFragment.this, REQUEST_TIME);        //设置目标Fragment,也就是前一个Fragment
                dialog.show(manager, DIALOG_TIME);              //第一个参数是FragmentManager,它会自动管理弹出的日历对话框,第二个是TAG
            }
        });

6:当选好时间后点击确定,从TimePicker中获取时间,写入到mCrime中,这里麻烦的地方是需要在两个Fragment中传递数据

从TimePicker中获取时间:TimePickerFragment#onCreateDialog

        return new AlertDialog.Builder(getActivity())
                .setView(view)
                .setTitle(R.string.time_picker_title)
                .setNegativeButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        int hour, minute;
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            hour = mTimePicker.getHour();                                //从TimePicker中获取时间
                            minute = mTimePicker.getMinute();
                        } else {
                            hour = mTimePicker.getCurrentHour();
                            minute = mTimePicker.getCurrentMinute();
                        }
                        Date date = new GregorianCalendar(year, month, day, hour, minute).getTime();    //创建一个阳历
                        sendResult(Activity.RESULT_OK, date);                //这个方法会自动回调CrimeFragment#onActivityResult方法
                    }
                })
                .create();
    private void sendResult(int resultCode, Date date) {      //这个方法会自动回调CrimeFragment#onActivityResult方法
        if (getTargetFragment() == null) {
            return;
        }
        Intent intent = new Intent();                    //传递数据
        intent.putExtra(EXTRA_DATE, date);        //这个EXTRA_DATE一直都是使用的DatePickerFragment中的常亮,毕竟两个按钮共用一个Date

        //调用目标Fragment的onActivityResult,给他返回数据
        getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
    }

7:回调CrimeFragment中的onActivityResult方法,处理按钮上显示的日期

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);    //获取刚刚intent中的日期
        mCrime.setDate(date);                                                        //同时设置到Crime对象的date属性中
        if (requestCode == REQUEST_DATE) {                
            updateDate();                
        }
        if (requestCode == REQUEST_TIME) {                                            //根据请求类型处理不同的结果
            updateTime();                                                        //更新第二个按钮的显示
            updateDate();                                      //更新第一个按钮的显示,要不然第一个按钮要等到重新打开这个页面才会更新
        }
    }
8:第5步CrimeFragment#onCreateView方法里有个
TimePickerFragment.newInstance(mCrime.getDate());

如果是复制的要把DatePickerFragment改成TimePickerFragment。

    public static TimePickerFragment newInstance(Date date) {
        Bundle bundle = new Bundle();
        bundle.putSerializable(ARG_DATE, date);

        TimePickerFragment fragment = new TimePickerFragment();
        fragment.setArguments(bundle);

        return fragment;
    }
DatePickerFragment#EXTRA_DATE常量必须改成public,要不然TimePickerFragment无法访问。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值