Fragment 和 Activity 之间的通信
备注: ——》表示数据的流向;
一,Fragment 与宿主 Activity 通信方式。
1,Activity ——》Fragment :宿主Activity可以在Fragment创建时传递参数给Fragment,Fragment 在 onCreate() 方法中通过 getArguments() 获取 Bundle 数据。
2,Activity ——》Fragment :宿主 Activity 通过 FragmentManager.findFragmentById() 或者 FragmentManager.findFragmentByTag() 获取Fragment 对象,并调用其方法,数据可以以参数形式传入。
3,Fragment ——》Activity:
3.1 fragment 通过 getActivty() 得到宿主对象,进而调用宿主方法传参数,但是不推荐!(因为耦合在一起,Fragment 没有了复用性)
3.2 接口回调:在 Fragment 中定义一个接口,然后在宿主 Activity 中实现接口
3.2.1:宿主 Activity 类实现该接口,Fragment 中的onAttach(Activity activity) 方法中为 接口句柄赋值。
3.2.2:匿名内部类性质的回调,在 Fragment 中写一个参数是接口对象的方法,在宿主 Activity 中调用此方法,参数使用匿名内部类,类似于 View 的 点击回调事件(这里也验证了非静态的匿名内部类,隐式持有当前对象!)
4,Fragment 《——》Activity:使用广播(杀鸡用牛刀)。
二,Fragment 之间的通信:
1, 在同一个Activity下的两个Fragment的通信:
FragmentA调用其宿主Activity的方法,宿主Activity再根据FragmentA的调用参数去调用FragmentB的方法并传递参数给B。
2, 不同Activity下的两个Fragment的通信:
-
首先能够保证两者都能够执行到onActivityResult()方法【文章前面有说到】
-
(A传给B)FragmentA通过startActivityForResult()【调用Fragment本身或者getActivity()都可以】的方式,把Intent数据等传到另一个Activity,然后让另一个Activity传值给FragmentB
-
(B返回给A)FragmentB处理完,通过getActivity().setResult()把返回的数据设置好,然后返回Activity,A再从它的onActivityResult中拿。
3,同一个Activity下,DialogFragment 与 Fragment的交互:
原理:FragmentA 中 new 一个 DialogFragment 对象,并让其 setTargetFragment() 来绑定目的 Fragment,等 DialogFragment 处理完数据,调用刚刚绑定的 FragmentA 的 onActivityResult() 把数据传回给 FragmentA 。
上关键代码:
Fragment 的代码
public class ContentFragment extends Fragment
{
//...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
//....
tv.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
EvaluateDialog dialog = new EvaluateDialog();
//注意setTargetFragment
dialog.setTargetFragment(ContentFragment.this, REQUEST_EVALUATE);
dialog.show(getFragmentManager(), EVALUATE_DIALOG);
}
});
return tv;
}
//接收返回回来的数据
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_EVALUATE)
{
String evaluate = data
.getStringExtra(EvaluateDialog.RESPONSE_EVALUATE);
Toast.makeText(getActivity(), evaluate, Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra(RESPONSE, evaluate);
getActivity().setResult(Activity.REQUEST_OK, intent);
}
}
}
DialogFragment 的代码
public class EvaluateDialog extends DialogFragment
{
private String[] mEvaluteVals = new String[] { "GOOD", "BAD", "NORMAL" };
public static final String RESPONSE_EVALUATE = "response_evaluate";
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Evaluate :").setItems(mEvaluteVals,
new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
setResult(which);
}
});
return builder.create();
}
// 设置返回数据
protected void setResult(int which)
{
// 判断是否设置了targetFragment
if (getTargetFragment() == null)
return;
Intent intent = new Intent();
intent.putExtra(RESPONSE_EVALUATE, mEvaluteVals[which]);
getTargetFragment().onActivityResult(ContentFragment.REQUEST_EVALUATE,
Activity.RESULT_OK, intent);
}
}