Fragment使用小结(三)

上一篇主要总结了Activity向Fragment传递数据的方式Fragment使用小结(二),接着Fragment向Activity传递数据以及Fragment间数据传递。

一. Fragment向Activity传递数据(两种方案)

方案一:接口回调,首先在Fragment中定义一个接口,并在接口中定义传递数据的抽象方法,然后在Activity中实现这个接口,并重写这个方法,最后在fragment中创建接口对象并指向Activity,传入数据。这种方式即可以实现Fragment和Activity之间的通信,也可以实现两个Fragment之间的通信。
MainActivity.Java

public class MainActivity extends AppCompatActivity implements ThreeFragment.MyCallBack {
    private TextView mTextView;
    private FragmentManager mFm;
    private FragmentTransaction mTransaction;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.tv_data);
        mFm = getFragmentManager();
        // 2. 开启Fragment处理事务.
        mTransaction = mFm.beginTransaction();
        // 3. 进行Fragment操作
        mTransaction.add(R.id.container, new ThreeFragment());
        // 4. 进行事务的提交
        mTransaction.commit();
    }
    @Override
    public void sendData(String str) {
        mTextView.setText(str);
    }
}

ThreeFragment.java

public class ThreeFragment extends Fragment {
    private EditText mData;
    private Button mButton;
    private MyCallBack mCallBack;
    public interface MyCallBack {
        public void sendData(String str);
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_three, container, false);
        mData = (EditText) view.findViewById(R.id.et_message);
        mButton = (Button) view.findViewById(R.id.bt_sendMessage);
        mButton.setOnClickListener(new View.OnClickListener() {

            private String mString;
            @Override
            public void onClick(View view) {
                mString = mData.getText().toString().trim();
                mCallBack.sendData(mString);

            }
        });
        return view;
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mCallBack = (MyCallBack) getActivity();
    }
}

方案二:使用广播,首先在宿主Activity里面注册广播,然后当需要通信的时候在Fragment中发送广播,宿主Activity中接受到广播,就可以获取数据进行显示了。当然也可以用广播实现两个Fragment之间的通信。
MainActivity.Java

    private TextView mTextView;
    private FragmentManager mFm;
    private FragmentTransaction mTransaction;
    private IntentFilter mFilter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) findViewById(R.id.tv_data);
        mFm = getFragmentManager();
        // 2. 开启Fragment处理事务.
        mTransaction = mFm.beginTransaction();
        // 3. 进行Fragment操作
        mTransaction.add(R.id.container, new ThreeFragment());
        // 4. 进行事务的提交
        mTransaction.commit();
        //动态注册广播
        mFilter = new IntentFilter();
        mFilter.addAction("android.activity.broadReceiver");
        BroadcastReceiver mBr = new BroadReceiver();
        registerReceiver(mBr, mFilter);
    }
    public class BroadReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle mData = intent.getExtras();
            mTextView.setText(mData.getString("text"));
        }
    }
}

ThreeFragment.java

mButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("android.activity.broadReceiver");
                intent.putExtra("text", "fragment通过广播发给Activity的数据");
                getActivity().sendBroadcast(intent);
            }
        });

除了以上两种方案之外还可以使用EventBus等等,我会在下面的Fragment间数据传递中使用。
二 .Fragment间数据传递(五种方案)

方案一:首先直接通过getFragmentManager获取Fragment管理器,然后通过Fragment的tag标签找到该Fragment,最后调用该Fragment的方法即可
MainActivity.Java

public class MainActivity extends FragmentActivity {

    private LeftFragment leftFragment;
    private RightFragment rightFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFragment();
    }
    private void initFragment() {
        leftFragment = new LeftFragment();
        rightFragment = new RightFragment();
        //将这个两个Fragment放到当前Activity对应的布局文件中
        getSupportFragmentManager().beginTransaction().
        add(R.id.fl_left, leftFragment, "left").
        add(R.id.fl_right, rightFragment,"right").
        commit();

    }

}

LeftFragment.java

public class LeftFragment extends Fragment {

    private ListView listView;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_left, container, false);

        //从Fragment的View中获取到LsitView控件
        listView = (ListView) view.findViewById(R.id.lv  );

        final String[] data = {"条目一","条目二","条目三","条目
四","条目五"};

        final int[] imageIds = {R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e};

        listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data));
        //给ListView设置条目的点击事件

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                //1. 获取用户点击的位置 对应的 title 和图片
                String title = data[position];
                int imageId = imageIds[position];
                //2. 将数据设置给RightFragment。
                //(1)找到RightFragment
                //获取Fragment管理器
                FragmentManager fragmentManager = getFragmentManager();
                //通过Fragment的tag标签找到该Fragment
                RightFragment rightFragment = (RightFragment) fragmentManager.findFragmentByTag("right");
                //(2)调用RightFragment的方法
                rightFragment.setTitleAndImage(title, imageId);

            }
        });

        return view;
    }

}

RightFragment.java

public class RightFragment extends Fragment {

    private ImageView iv;
    private TextView tv_title;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_right, container, false);

        tv_title = (TextView) view.findViewById(R.id.tv_title);
        iv = (ImageView) view.findViewById(R.id.iv);
        return view;
    }

    /*
     * 添加一个方法,用于给自己设置标题和图片
     */
    public void setTitleAndImage(String title, int imageId) {
        tv_title.setText(title);
        iv.setImageResource(imageId);
    }
}

方案二:使用接口来实现两个Fragment之间通信,需要通过宿主Activity中转一下,首先在宿主Activity中实现这个接口,这样当Fragment调用onAttach方法时就可以实例化这个接口了,Fragment通过回调接口,将值返给Activity,Activity 通过setArguments 传值给另一个Fragment。如果是Fragment和宿主Activity通信则直接调用即可。
MainActivity.Java

  public void sendData(String title, int imgId) {
        FragmentManager manager = getFragmentManager();
        //得到FragmentTransaction对象
        FragmentTransaction transaction = manager.beginTransaction();
        rightFragment = new RightFragment();
        Bundle bundle  = new Bundle();
        bundle.putString("title", title);
        bundle.putInt("img",imgId);
        rightFragment.setArguments(bundle);
        //将rightFragment替换布局
        transaction.replace(R.id.fl_right, rightFragment);
        transaction.commit();//提交事务

    }

LeftFragment.java

 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                //1. 获取用户点击的位置 对应的 title 和图片
                String title = data[position];
                int imageId = imageIds[position];
                mCallBack.sendData(title,imageId);
            }
        });
        return view;
    }
    public interface MyCallBack {
        public void sendData(String title,int imgId);
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mCallBack = (MyCallBack) getActivity();
    }

RightFragment.java

   //得到activity传过来的bundle对象
        Bundle bundle = getArguments();

        if(bundle!=null){
            tv_title.setText(bundle.getString("title"));
            iv.setImageResource(bundle.getInt("img"));
        }

方案三:EventBus,直接参考 http://blog.csdn.net/tyk0910/article/details/51073292

方案四:使用广播,我采用的是LocalBroadcastManager发送广播

LocalBroadcastManager是AndroidSupport包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。
注意,这是同一个应用,也就是其他应用就算和你共进程,也是无法互相发送广播的。
使用LocalBroadcastManager有如下好处:
1. 发送的广播只会在自己App内传播,不会泄露给其他App,确保隐私数据不会泄露
2. 其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏
3. 比系统全局广播更加高效
LeftFragment.java

   /**
   * 方案四 发送广播
    */
                Intent intent = new Intent("android.fragment.register");
                intent.putExtra("title", title);
                intent.putExtra("img", imageId);
                LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);

RightFragment.java

 LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
                .getInstance(getActivity());
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.fragment.register");
        BroadcastReceiver br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Bundle mData = intent.getExtras();
                tv_title.setText(mData.getString("title"));
                iv.setImageResource(mData.getInt("img"));
            }

        };
        localBroadcastManager.registerReceiver(br, intentFilter);

方案五:通过宿主Activity(fragment(必须在同一个Activity中)),只需要改变LeftFragment.java以下代码

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

                String title = data[position];
                int imageId = imageIds[position];
                // 在Fragment中调用其所在的Activity方法 , Fragment获取上下文的方法
                FragmentActivity activity = getActivity();
                if(activity instanceof MainActivity) {
                    // 获取Fragment管理器
                    FragmentManager fm = getFragmentManager();
                    // 找到第二个Fragment, 直接执行方法
                    RightFragment fragment = (RightFragment) fm.findFragmentByTag("right");
                    fragment.setTitleAndImage(title, imageId);

                }

            }
        });

        return view;
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值