07 对话框

创建DialogFragment

将AlertDialog封装在DialogFragment实例中使用,这样FragmentManager管理对话框,可以更灵活地显示对话框。如果旋转设备,单独使用的AlertDialog会消失,而封装在fragment中的AlertDialog不会有此问题。

就CriminalIntent应用来说,我们首先会创建名为 DatePickerFragment 的DialogFragment 子类。然后,在 DatePickerFragment 中,创建并配置显示 DatePicker 组件的 AlertDialog 实例。DatePickerFragment 同样由 CrimePagerActivity 托管。

在这里插入图片描述

首先创建DatePickerFragment,并创建AlertDialog:

public class DatePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
                .setTitle(R.string.date_picker_title)
                .setPositiveButton(android.R.string.ok, null)
                .create();
    }
}

显示DialogFragment

和其他fragment一样,DialogFragment 实例也是由托管activity的 FragmentManager 管理着的。调用fragment实例的show(FragmentManager, String)方法,可将DialogFragment 添加给 FragmentManager 管理并放置到屏幕上。

CrimeFragment.java

private static final String DIALOG_DATE = "DialogDate";
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //...
    //在Button上显示日期
    mDateButton = view.findViewById(R.id.crime_date);
    mDateButton.setText(mCrime.getDate().toString());
    mDateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d(TAG, "点击了日期按钮...");
            Log.d(TAG, "日期:" + mCrime.getDate().toString());
            FragmentManager manager = getFragmentManager();
            DatePickerFragment dialog = new DatePickerFragment();
            dialog.show(manager, DIALOG_DATE);
        }
    });
    //...
}

设置对话框显示的内容

使用AlertDialog.Builder的setView(View)方法,添加DatePicker组件给
AlertDialog 对话框。该方法配置对话框,实现在标题栏与按钮之间显示传入的View对象。

首先配置DatePicker布局:

dialog_date.xml

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

然后添加DatePicker组件给AlertDialog 对话框:

DatePickerFragment.java

public class DatePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date, null);
        return new AlertDialog.Builder(getActivity())
            	.setView(view)
                .setTitle(R.string.date_picker_title)
                .setPositiveButton(android.R.string.ok, null)
                .create();
    }
}

fragment间的数据传递

传递数据给DatePickerFragment

DatePickerFragment.java

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

    DatePickerFragment fragment = new DatePickerFragment();
    fragment.setArguments(args);
    return fragment;
}

修改按钮单击事件:

CrimeFragment.onCreateView(LayoutInflater, ViewGroup, Bundle)

mDateButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FragmentManager manager = getFragmentManager();
        DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
        dialog.show(manager, DIALOG_DATE);
    }
});

获取Date对象并初始化DatePicker

DatePickerFragment.java

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    Date date = (Date) getArguments().getSerializable(ARG_DATE);

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);

    View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date, null);

    mDatePicker = view.findViewById(R.id.dialog_date_date_picker);
    mDatePicker.init(year, month, day, null);

    return new AlertDialog.Builder(getActivity())
            .setView(view)
            .setTitle(R.string.date_picker_title)
            .setPositiveButton(android.R.string.ok, null)
            .create();
}

返回数据给CrimeFragment

设置目标fragment

CrimeFragment.onCreateView(LayoutInflater, ViewGroup, Bundle)

mDateButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FragmentManager manager = getFragmentManager();
        DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
        dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);
        dialog.show(manager, DIALOG_DATE);
    }
});
传递数据给目标fragment

DatePickerFragment.java

public static final String EXTRA_DATE = "com.example.criminalintent.date";
private void sendResult(int resultCode, Date date) {
    if (getTargetFragment() == null) return;

    Intent intent = new Intent();
    intent.putExtra(EXTRA_DATE, date);

    getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
}

DatePickerFragment.onCreateDialog(Bundle)

//...
return new AlertDialog.Builder(getActivity())
        .setView(view)
        .setTitle(R.string.date_picker_title)
        .setPositiveButton(android.R.string.ok,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        int year = mDatePicker.getYear();
                        int month = mDatePicker.getMonth();
                        int day = mDatePicker.getDayOfMonth();

                        Date date = new GregorianCalendar(year, month, day).getTime();
                        sendResult(Activity.RESULT_OK, date);
                    }
                })
        .create();
响应DatePicker对话框

CrimeFragment.java

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != Activity.RESULT_OK) return;

    if (requestCode == REQUEST_DATE) {
        Date date = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
        mCrime.setDate(date);
        mDateButton.setText(mCrime.getDate().toString());
        Log.d(TAG, "日期已更改 -> " + mCrime.getDate().toString());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值