Android学习|Fragment——Avtivity与Fragment通信
一、 Fragment通信分类
1、Avtivity与Fragment的通信
2、Fragment与Avtivity的通信
3、Fragment与Fragment的通信
1、Avtivity与Fragment通信
a、原生方案:Bundle类作为通信数据保存的载体
Bundle可保存string,byte等多种类型数据,而对于自定义的实体类Bean的保存,可使用putParcelable(string key,Parcelable value)实现 。 Parcelable 通过序列化之类的实现的
然后activity中,通过创建的fragment,调用setArguments()传入数据bundle
传入的数据在fragment的整个生命周期中都可以进行使用
演示
前提:在上一篇Android学习|Fragment__01静态、动态添加Fragment的动态添加Fragment的代码的基础上更改。
在MainActivity.java的代码中,在onclick()方法中添加Bundle进行数据传输。
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt1: {
BlankFragment1 blankFragment1 = new BlankFragment1();
// 传入数据 给 blankFragment1
Bundle bundle = new Bundle();
bundle.putString("msg","this is a msg");
blankFragment1.setArguments(bundle);
replaceFragment(blankFragment1);
break;
}
case R.id.bt2: {
replaceFragment(new ItemFragment2());
break;
}
}
}
此处,数据传输到BlankFragment1中,在这个fragment中,因为传入的数据在fragment的整个生命周期中都可以进行使用,所以随便找个方法测试将数据拿出来。(此处采用onCreat()方法测试)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
Bundle bundle = this.getArguments();
String msg = bundle.getString("msg");
Log.e("leo","fragment : "+msg);
}
运行效果,下图主界面点击add pragment后,fragment展示出来了,同时控制台打印出日志。
2、Java语言中类与类自己通信常用方案:接口
首先,定义接口IFragmentCallBack用于互发消息
package com.example.fifthdemo_fragment_02;
public interface IFragmentCallBack {
//fragment给activity发送消息
void sendMsgToActivity(String msg);
//activity给fragment发送消息
String getMsgFromActivity(String msg);
}
然后,给BlankFragment1设置给activity发送消息,BlankFragment1的xml中定义一个button用于触发消息的发送。
package com.example.fifthdemo_fragment_02;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
public class BlankFragment1 extends Fragment {
private View view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = this.getArguments();
String msg = bundle.getString("msg");
Log.e("leo","fragment : "+msg);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (view == null){
view = inflater.inflate(R.layout.fragment_blank, container, false);
}
//fragment给 activity发送消息
Button button = view.findViewById(R.id.bt_3);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//1.给activity发消息
// iFragmentCallBack.sendMsgToActivity("hello,I am Fragment");
//2.接受activity消息
String msg = iFragmentCallBack.getMsgFromActivity(null);
Toast.makeText(BlankFragment1.this.getContext(),msg,Toast.LENGTH_SHORT).show();
}
});
return view;
}
private IFragmentCallBack iFragmentCallBack;
public void setiFragmentCallBack(IFragmentCallBack iFragmentCallBack){
this.iFragmentCallBack = iFragmentCallBack;
}
}
原来MainActivity.java的代码的onClick()更改成如下:
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt1: {
BlankFragment1 blankFragment1 = new BlankFragment1();
// 传入数据 给 blankFragment1
Bundle bundle = new Bundle();
bundle.putString("msg","this is a msg");
blankFragment1.setArguments(bundle);
//fragment与activity通信接口 test
blankFragment1.setiFragmentCallBack(new IFragmentCallBack() {
@Override
public void sendMsgToActivity(String msg) {
Toast.makeText(MainActivity.this,msg,Toast.LENGTH_SHORT).show();
}
@Override
public String getMsgFromActivity(String msg) {
return "hello,I am Activity !";
}
});
replaceFragment(blankFragment1);
break;
}
case R.id.bt2: {
replaceFragment(new ItemFragment2());
break;
}
}
}
写的有点奇怪…
BlankFragment1中1 、2注释可测试互发消息
3、其他方案:eventBus,LiveData…
部分基于观察者模式,发布订阅模式实现