我爱编程

DailogFragment 使用

2018-04-12  本文已影响0人  YueJZ

对话框能引起用户的注意,也可以接收用户的输入。我们为应用添加对话框,可以修改日期。如图:

对话框

图中的对话框是 AlertDialog 类的一个实例。AlertDialog 类是常用的多用途 Dialog 子类。
学习了 AlertDialog,在此总结一下,同时也包括 fragment 间数据传输的问题。

创建 DailogFragment

一般是建议将 AlertDialog 封装在DialogFragment (Fragment 的子类)实例中使用,这样可以使用 FragementManager 管理对话框,可以更加灵活的显示对话框。当然,不使用 DialogFragment 也可以显示 AlertDialog 视图。
另外,如果旋转设备, AlertDialog 会消失,而封装在 fragment 中的 AlertDialog 则不会出现此问题。

要显示对话框,首先完成以下任务:

先为对话框添加资源

value/strings.xml

<string name="date_picker_title">Date of crime:</string>

创建 DialogFragment,选择 AppCompat 的版本是 android.support.v7.app.AlertDialog

DatePickerFragment.java

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

在以上代码中,以流接口的形式创建了 AlertDialog 实例。首先,将 Context 参数传入 AlertDialog.Builder 类的方法中,返回一个 AlertDialog.Builder 实例。然后调用 AlertDialog.setTitle(...) 和 AlertDialog.setPositiveButton(int, DialogInterface.OnclickLister),setPositiveButton(...) 传入的两个参数分别是字符串资源和 DialogInterface.OnclickLister 接口的对象。代码中传入的资源 ID 是 Android 的 OK 常量;至于监听器等会儿实现,先传入 null。最后调用 AlertDialog.creat() 返回配置的 AlertDialog 实例。
Android 中有3种用于对话的按钮:positivi、negative、neutral,代表确定,否定,和中立

显示 DialogFragment

和其他 fragment 一样,DialogFragment 实例也是由托管 activity 的FragmentManager 管理的,要将 DialogFragment 添加给 FragmentManager 管理并放置到屏幕上,可调用以下两个方法:

public void show(FragmentManager, String);
public void show(FragmentTransaction, String);

String 是可唯一识别 FragmentManager 队列中的 DialogFragment。两个方法都行,但是 传入 FragmentTransaction,需要自己负责创建事务并提交;传入 FragmentManager 参数,系统会自动创建并提交事务。
这里我们传入的是 FragmentManager。

CrimeFragment.java

public class CrimeFragment extends Fragment {

private static final String DIALOG_DATE = "DialogDate";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
mDateButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager manager = getFragmentManager();
                DatePickerFragment dialog = new DatePickerFragment();
                dialog.show(manager,DIALOG_DATE);
            }
        });
}

到这里我们运行程序,已经能看到对话框了。

设置对话框显示内容

接下来,使用 AlertDialog.Build 的 setView(...) 方法,给 AlertDialog 对话框添加 DatePicker 组件。
先来设置 DatePicker 的布局,创建 dialog_date.xml 布局文件。

layout/dialog_date.xml

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

实例化 DialogPicker 视图并添加到对话框。

DatePickerFragment .java

public class DatePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(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 间数据的传递

现在需要实现同一个 activity 托管的两个 fragment 之间的数据传递。

CrimeFragment 与 DatePickerFragment 的对话

首先来看传递数据给 DatePickerFragment。要传递 crime 日期给 DatePickerFragment,需要将它保存在 DatePickerFragment 的 argument bundle 中。创建和设置 fragment argument 通常是在 newInstance() 方法中完成。

DatePickerFragment.java

public static final String EXTRA_DATE = "con.bingnerdranch.android.criminalintent.date";

private DatePicker mDatePicker;

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 中,用 DatePickerFragment.newInstance(Date) 方法替换 DatePickerFragment 的构造方法。

CrimeFragment.java

public class CrimeFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    mDateButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager manager = getFragmentManager();
               // DatePickerFragment dialog = new DatePickerFragment();
                DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());
                dialog.setTargetFragment(CrimeFragment.this,REQUEST_DATE);
                dialog.show(manager,DIALOG_DATE);
    }
}

DatePickerDialogFragment 使用的 Date 中的信息来初始化 DatePicker 对象。但是 DatePicker 对象的初始化需要整数形式的年月日。Date 是时间戳,无法直接提供整数,我们还需要创建一个 Calender 对象,用 Date 对象配置它,获得年月日。

DatePickerFragment.java

public class DatePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final 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);
}

GitHub地址

上一篇 下一篇

猜你喜欢

热点阅读