场景:同一个activity管理下的一个fragmentA,启动对话框fragment
对话框属于一种fragment,特别的是安卓内部已经设置好,不需要你为它设置容器。只需要你按需要启动,就会浮现在窗口。
①一般来说,对话框fragment是可以在fragmentA下不断启动,销毁的。而fragmentA不变。因此可以在fragmentA中通过创建对话框fragment实例的方式,启动你的对话框fragment。对话框fragment其实是继承自DialogFragment的子类,需要为编写。
②对话框fragment是有内容的,包括title,button和其他自定义的布局。在对话框fragment类中进行定义(对话框fragment实例被生成,它的视图就确定下来)
③fragmentA有时候需要和对话框fragment进行通信。
由于对话框fragment是被fragmentA创建的,所以由fragmentA传向对话框fragment的通信方法通过newInstance方法即可。
而由对话框fragment传向fragmentA的通信方式利用了TargetFragment的方法。
代码实现:
①编写对话框fragment子类
public class DatePickerFragment extends DialogFragment {
private DatePicker mDatePicker;
public static DatePickerFragment newInstance(Date date) {
Bundle args = new Bundle();
args.putSerializable("date",date);
DatePickerFragment fragment = new DatePickerFragment();
fragment.setArguments(args);
return fragment;
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Date date = (Date) getArguments().getSerializable("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)+1;
View v = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_date,null);
mDatePicker = (DatePicker) v.findViewById(R.id.dialog_date_picker);
mDatePicker.init(year,month,day,null);
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.date_picker_title)
.setPositiveButton("确定", 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(date, Activity.RESULT_OK);
}
})
.setView(v)
.create();
}
private void sendResult(Date date,int resultCode){
if(getTargetFragment() == null){
return;
}
Intent intent = new Intent();
intent.putExtra("date",date);
getTargetFragment().onActivityResult(getTargetRequestCode(),resultCode,intent);
}
}
继承自DialogFragment 。
覆盖onCreateDialog方法。return语句部分实现了title和button(字符,监听器),view对象。
②启动对话框
mDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Date date = mCrime.getDate();
FragmentManager fm = getFragmentManager();
DatePickerFragment dialog = DatePickerFragment.newInstance(date);
dialog.setTargetFragment(CrimeFragment.this,0);
dialog.show(fm,"date");
}
});
使用DialogFragment.show方法,需要传入FragmentManager 。
③fragmentA向对话框fragment发送数据:
利用newInstance方法和Arguments。前面学过,不再讲。
④对话框fragment向fragmentA发送数据:
就是在点击对话框按钮,关闭对话框的时候进行数据的发送。
首先要建立fragmentA和对话框fragment的联系:
dialog.setTargetFragment(CrimeFragment.this,0);
然后实现对话框按钮监听,见①代码。关注sendResult部分。
最后覆盖fragmentA的onActivityResult方法(自动调用),fragmentA接收的数据在onActivityResult处理。
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode != Activity.RESULT_OK){
return;
}
if(requestCode == 0){
Date date =(Date) data.getSerializableExtra("date");
mCrime.setDate(date);
mDateButton.setText(mCrime.getDate().toString());
}
}