Fragment+DialogFragment
现在应用的开发基本上都是实现应用的碎片化(使用Fragment来显示内容),Fragment可以很好的使你的应用适用不同的屏幕显示。具体不在赘述,总之优点多多。
DialogFragment主要功能我们很容易从名字中看出,是用于显示对话框的,需要说明的是DialogFragment实例也是有托管的Activity的FragmentManager管理着的。
本次内容主要演示如何实现将FragmentDialog中的数据回调到Fragment的问题。
我们通过在FragmentDialog中展现出日历,然后回调选择的日历日期,显示到启动此对话框的Fragment上。
首先,我们先创建我们要托管的Activity,使其继承FragmentActivity。
这里我将托管的Activity命名为DialogFragmentActivity,并且设置显示的布局文件activity_dialog_fragment:
布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/frameLayout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</LinearLayout>
需要注意的是在布局文件中添加里一个帧布局,将用于显示fragment。
DialogFragmentActivity的代码如下:我们这里通过事务来提交我们要显示的Fragment。getSupportFragmentManager()是需要你Activity继承FragmentActivity或者其实现类才会有的。这里需要申明一下,fagment使用是用V4的兼容包,那么其它地方都需要统一使用。
public class DialogFragmentActivity extends FragmentActivity {
private FragmentManager fm;
public static final int RESULT_OK = 0x1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog_fragment);
fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.frameLayout_1, new ShowDialogFragment()).commit();
}
}
接下来是ShowDialogFragment的编写,此类为继承Fragment的类,此fragment我设置了两个按钮和一个显示等会我们需要从日历中回调的数据,代码如下,布局文件教简单不在给出。
public class ShowDialogFragment extends Fragment {
private final String TAG = "DialogDate";
private final int REQUEST_CODE = 0X2;
private EditText editText;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_fragment, container, false);
editText = (EditText) view.findViewById(R.id.showDate);
Button bn = (Button) view.findViewById(R.id.showDialog);
Button bn2 = (Button) view.findViewById(R.id.showMyViewDialog);
bn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
DialogFragment dialog = new DialogFragmentTest();
dialog.show(fm, TAG);
}
});
bn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
DialogFragment dialog = DialogFragmentTest2.newInstance();
dialog.setTargetFragment(ShowDialogFragment.this, REQUEST_CODE);
dialog.show(fm, TAG);
}
});
return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE) {
String s = data.getStringExtra(DialogFragmentTest2.EXTRA_DATA);
editText.setText(s);
}
}
}
接下来我们需要显示一个DialogFragment的测试,也就是上面看到的按钮一(bn):
public class DialogFragmentTest extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity()).setTitle("I am DialogFragment show")
.setIcon(R.mipmap.ic_launcher).create();
}
}
看看运行效果:
好了简单的DialogFragment这就测试完成了。
下面是本次内容要解决的问题的主要实现,也就是bn2点击所展示的DialogFragment这里命名为 DialogFragmentTest2。
public class DialogFragmentTest2 extends DialogFragment {
private String selectDay = "";
public static String EXTRA_DATA = "MYDATE";
public static DialogFragmentTest2 newInstance() {
DialogFragmentTest2 dialogFragmentTest2 = new DialogFragmentTest2();
return dialogFragmentTest2;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
//填充布局
View view = LayoutInflater.from(getActivity()).inflate(R.layout.mydialogview, null);
CalendarView calendarView = (CalendarView) view.findViewById(R.id.calendarView);
calendarView.setDate(System.currentTimeMillis());
//对日历选择进行监听,以更新selectDay的数据
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(CalendarView view, int year, int month, int dayOfMonth) {
selectDay = year + "-" + month + "-" + dayOfMonth;
Toast.makeText(getActivity(), selectDay, Toast.LENGTH_SHORT);
System.out.println(selectDay);
}
});
//返回此对话框,当然如果直接返回view也是可以的,不过这样的对话框仅仅只显示日历(也就是你填充的内容),这里为了更好的显示,于是加了如下的返回AlertDialog。
return new AlertDialog.Builder(getActivity()).setTitle("日志")
.setView(view).setNeutralButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
sendDate();
}
}).create();
看下运行效果:
当点击确定按钮是则把数据通过getTargetFragment().onActivityResult返回
public void sendDate() {
Intent intent = new Intent();
intent.putExtra(EXTRA_DATA, selectDay);
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
}
上面代码中主要就一下这行代码:
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
通过此可以返回数据到启动它的Fragment上
在ShowDialogFragment我们需要如下代码,以得到返回的值。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE) {
String s = data.getStringExtra(DialogFragmentTest2.EXTRA_DATA);
editText.setText(s);
}
}
选择好日期,点击确定即可得到数据: