Fragment之间传递数据的三种方式

来源:互联网 发布:淘宝网迪士尼保温杯 编辑:程序博客网 时间:2024/04/30 10:58

引言

Android在3.0以后由于觉得Activity占用内存等问题,推出了轻量级的碎片可以嵌套在Activity中,大大减少了开销,由于Fragment的推广普及所以fragment之间的数据传递也油然而生,下面我介绍几个我用过的Fragment之间的数据传递:

在介绍之间我们先来搭建以下这个Demo的布局和所需要了Fragment。
MainActivity布局如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent">    <FrameLayout        android:id="@+id/fm_1"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="match_parent">    </FrameLayout>    <FrameLayout        android:id="@+id/fm_2"        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="match_parent">    </FrameLayout></LinearLayout>

MainActivity类:

public class MainActivity extends AppCompatActivity {    private FragmentLeft fLeft;//左边的fragment    private FragmentRight fRight;//右边的fragment    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        getSupportActionBar().hide();//隐藏状态栏        setContentView(R.layout.activity_main);        initData();    } /**  *初始化fragment数据  *  /  private void initData() {       fLeft = new FragmentLeft();       fRight = new FragmentRight();getFragmentManager().beginTransaction().replace(R.id.fm_1,fLeft,"fLeft").commit();       getFragmentManager().beginTransaction().replace(R.id.fm_2,fRight,"fRight").commit();    }}

两个fragment类:

/** * Created by luweicheng on 2016/12/19. */public class FragmentLeft extends Fragment {    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment1,null);        return view;    }/** * Created by luweicheng on 2016/12/19. */public class FragmentRight extends Fragment {    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, @Nullable   ViewGroup container, @Nullable Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment2,null);        return view;    }

效果图:

这里写图片描述

这里写图片描述

  • 方式一
    step1 我们在创建Fragment的需要添加tag(标签),然后在发送数据的fragment中根据tag找到接收数据的fragment:
 view.findViewById(R.id.but_change) .setOnClickListener(new View.OnClickListener() {            @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)            @Override            public void onClick(View view) {                Bundle bundle = new Bundle();                        bundle.putString("data","改变图片了");                FragmentRight fragmentRight = (FragmentRight) getActivity()                        .getFragmentManager()                        .findFragmentByTag("fRight");                fragmentRight.setData(bundle);            }        });

在FragmentRight中编写setData( Bundle bundle)方法,切换图片:

  private int[] imgs = {R.drawable.sun, R.drawable.launch_icon2};    int a = 1;    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)    public void setData(Bundle bundle) {        String value = bundle.getString("data");        Toast.makeText(getActivity(), value, Toast.LENGTH_SHORT).show();        Log.e(TAG, "setData: a=="+a);        if (a % 2 == 0) {            image.setBackgroundResource(imgs[0]);            ++a;        } else {            image.setBackgroundResource(imgs[1]);            ++a;        }    }
  • 方式二

    利用接口回调,在FragmentLeft中创建一个接口,并且在点击按钮的时候如果有实现该接口的类,将产生回调:

  /**     * 自定义接口,包含imgChange()方法     */    public interface ChangeInterface{        void imgChange(Bundle data);    }    private ChangeInterface mChangeInterface;    public void setChangeInterface(ChangeInterface mChangeInterface){        this.mChangeInterface = mChangeInterface;    }

点击按钮:

 if(mChangeInterface != null){                    mChangeInterface.imgChange(bundle);                  }

在MainActivity中实现该接口,在回调方法中调用FragmentRight中的setData(Bundle bundle)方法:

fLeft.setChangeInterface(new FragmentLeft.ChangeInterface() {          @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)          @Override          public void imgChange(Bundle data) {           fRight.setData(data);          }      });
  • 方式三
    利用第三方开源库EventBus,EventBus是一种用于线程间通信的封装类,用来代替Handler、BroadCastReceiver、Intent等在Activity、Service、Fragment之间传递数据,内部基本是基于观察者模式对被观察者进行实时监听和传递数据(这里我使用最新的EventBus3.0)。
    step1:导入库
 compile 'org.greenrobot:eventbus:3.0.0'

step 2:注册事件接受者(在onCreateView中)

  EventBus.getDefault().register(this);

step 3 :发送事件(FragmentLeft)

 Bundle bundle = new Bundle();                        bundle.putString("data","改变图片了");                EventBus.getDefault().post(bundle);

step 4:接收事件(FragmentRight)

@Subscribe  //必须使用EventBus的订阅注解public void onEvent(Bundle bundle){    String value = bundle.getString("data");    Log.e(TAG, "onEvent: "+value );    Toast.makeText(getActivity(), value, Toast.LENGTH_SHORT).show();    Log.e(TAG, "setData: a=="+a);    if (a % 2 == 0) {        image.setBackgroundResource(imgs[0]);        ++a;    } else {        image.setBackgroundResource(imgs[1]);        ++a;    }}

step 5:取消注册事件(FragmentLeft)

  @Override    public void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }

好了,以上就是关于Fragment之间数据传递的方式,前两种适用于一般简单的数据传递,但是如果fragment多层嵌套而且数据传递的频繁的话,EventBus就是相当游刃有余了。

0 0
原创粉丝点击