今天在做项目的时候,用到了平时再也熟悉不过的Fragment,其中涉及到了Activity与Fragment之间的通信,这里总结一下在自己项目中的应用。
参考博客:
http://blog.csdn.net/lmj623565791/article/details/37970961
http://blog.csdn.net/lmj623565791/article/details/37992017
http://blog.csdn.net/lmj623565791/article/details/42628537
这里都是鸿洋有关Fragment详解,我就不班门弄斧,
主要讲的是自己的Fragment与Activity通信的实现。
简化一下业务逻辑:Activity中,有一个Textview,并且动态添加了一个Fragment,在Fragment中有两个Edittext,两个Button:
1.点击第一个Button的时候,在Activity中,得到Fragment里这两个Edittext的值;
2.点击第二个Button的时候,在Activity中,Textview的值进行更新
OK,上代码,边写边说:
首先是第一种通信方式,接口回调机制
1.布局文件:
activity的布局:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="这里的值将会改变" />
<LinearLayout
android:layout_marginTop="40dp"
android:id="@+id/fragment_ll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
fragment的布局:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/username_edt"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/password_edt"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/interface_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="接口按钮" />
<Button
android:id="@+id/broadcast_btn"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="广播按钮" />
</LinearLayout>
都很简单,没什么可说的。
2.代码实现:
在myfragment里面:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_fragment, container, false);
context = getActivity();
return view;
}
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
initview();
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
submit = (Submit) activity;
}
public interface Submit {
public void submit(String userStr, String passStr);
}
private void initview() {
userEdt = (EditText) getView().findViewById(R.id.username_edt);
passEdt = (EditText) getView().findViewById(R.id.password_edt);
inBtn = (Button) getView().findViewById(R.id.interface_btn);
inBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
submit = (Submit) getActivity();
submit.submit(userEdt.getText().toString().trim(), passEdt
.getText().toString().trim());
}
});
brBtn = (Button) getView().findViewById(R.id.broadcast_btn);
brBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
}
});
}
我写了一个接口,在接口里面写了提交的方法,携带两个参数,然后在activity中去实现这个接口
public interface Submit {
public void submit(String userStr, String passStr);
}
public class MainActivity extends Activity implements Submit {
TextView txt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initview();
}
@SuppressLint("NewApi")
private void initview() {
Fragment fragment = new MyFragment();
FragmentTransaction fm = getFragmentManager().beginTransaction();
fm.replace(R.id.fragment_ll, fragment);
fm.commit();
}
@Override
public void submit(String userStr, String passStr) {
Toast.makeText(getApplicationContext(),
"username:" + userStr + "password:" + passStr,
Toast.LENGTH_LONG).show();
}
什么时候去实现这个回调呢,在点击button的时候,首先需要申明这个接口对象,并且为之赋值,这里调用接口方法的是activity,所以将这个activity赋值给接口对象,强转类型即可。这里得到当前activity有两个方法:
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
submit = (Submit) activity;
}
在fragment的onattach生命周期中,onAttach(Activity),当Fragment与Activity发生关联时调用。
submit = (Submit) getActivity();
或者直接getActivity()也可以
得到接口对象以后,执行里面的方法,得到两个Edittext的值。最后一点击button,执行回调,activity中得到两个值并且进行简单的显示,这样就通过接口回调机制来完成了fragment向activity通信传值的一种方式。
可参考
接下来是第二种广播实现通信:
这个实现起来也比较简单,在宿主Activity里面注册广播,当需要通信的时候在Fragment中发送广播,宿主Activity中接受到广播,进行相应处理即可。这种方式比较灵活,也比较简单,没有接口回调那么多接口和处理。Fragment和Activity之间耦合度也较低。
在activity里面,动态注册了一个广播用来接收来自fragment的广播消息,当有消息传递时候,将值拿出来进行显示:
private IntentFilter intentFilter;
private BroadReceiver broadReceiver;
intentFilter = new IntentFilter();
intentFilter.addAction("android.text_change");
broadReceiver = new BroadReceiver();
registerReceiver(broadReceiver, intentFilter);
}
public class BroadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle data= intent.getExtras();
txt.setText(data.getString("text"));
}
在fragment里面,点击button发送广播,比较简单:
brBtn = (Button) getView().findViewById(R.id.broadcast_btn);
brBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent = new Intent("android.text_change");
intent.putExtra("text", "这里是通过广播传递的值,啦啦啦啦啦");
getActivity().sendBroadcast(intent);
}
});
最后贴上效果图:
Avtivity向对应跳转,加载的Fragment中传递数据,可以采用setArguements()方法,这个不是很复杂。
最后一种通信方式是eventbus,这个最近在学习中,以后贴上学习经验~~~