Fragment中的通信

本文详细介绍fragment的几种通信的方式

Activty向fragment中传递数据

只需要在对应的触发事件中写如下代码即可:
    public void ck(View view) {
//        获取fragment管理器
        FragmentManager fm = getFragmentManager();
//        使用事物,为了保证数据的一致性和完整性
        FragmentTransaction ft = fm.beginTransaction();
//        将需要添加的fragment创建出来
        LeftFragment left = new LeftFragment();
//        创建一个数据包
        Bundle b=new Bundle();
//        构造需要传递的数据,并且传递出去
        b.putInt("id",R.mipmap.delaiwen);
        left.setArguments(b);
//        使用replace方式添加fragment
        ft.add(R.id.fragment_contont,left);
        ft.addToBackStack(null);
//        提交事物
        ft.commit();
    }
可以通过使用Bundle数据包,向fragment传递数据,当然对应的fragment也需要做相应的操作,我这里是将传过来的图片显示到image上面:
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left_fragme_layout, container, false);
        ImageView lv= (ImageView) view.findViewById(R.id.iamge_default);
        lv.setImageResource(getArguments().getInt("id"));
        return view;
    }
一般情况下,我们会在createview方法中取出数据,这样可以显示到UI上,不能通过有参构造的方法进行设置值,因为当屏幕旋转的时候,activity会进行销毁,对应的fragment也会进行销毁,然后重建,在重建的过程中,会调用fragment的无参构造方法(这也就是为什么fragment必须要有一个空参构造的原因)系统在创建fragment对象的时候,会看有没有被设置arguments,若有的话,会帮我们设置上,这样也可以防止数据丢失

Activity操作fragment中的数据

可以在Activity通过:
        FragmentManager fm=getFragmentManager();
        LeftFragment left= (LeftFragment) fm.findFragmentByTag("left");
来获取声明了Tag的fragment,然后进行相应的操作,若是想对fragment中的UI进行操作,则直接可以通过以下代码来实现:
        ImageView images= (ImageView) findViewById(R.id.iamge_default);
        images.setImageResource(R.mipmap.jinkesi);
这里直接在activity中通过findviewById来找到对应的组件,直接对其进行操作,( 注意:必须等fragment完成了oncreateView方法之后,也就是等fragment呈现出来之后再调用 此方法,否则会出现空指针异样的问题
下面是效果图:

Fragment向Activty中传值

fragment可以通过getActivity方法获取和它绑定的activity,不过此方法应该在onAttach之后获取,因为fragment是在onAttach方法中和activty建立关系的。若想操作activity中的UI组件或者传递值可以使用以下代码:
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.left_fragme_layout, container, false);
        ImageView lv= (ImageView) view.findViewById(R.id.iamge_default);
        lv.setImageResource(getArguments().getInt("id"));
        btn= (Button) view.findViewById(R.id.change_color);
        Log.i(TAG, "onCreateView: "+btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().findViewById(R.id.activity_main).setBackgroundColor(Color.YELLOW);
            }
        });
        return view;
    }
可以通过getActivity()获取activty对象,拿到了activty对象,就可以直接操作activity中的数据了,在这里演示的是进行改变activty的背景颜色,效果图如下:

上图中先是呈现出fragment,然后通过点击fragment中的按钮,改变activty的背景颜色
当然谷歌官方觉得这种方式会导致耦合性较高,推荐我们使用接口回调的方式来实现fragment和activity之间的数据交互
我们在fragment中定义一个内部接口:
    public interface FragmentCallbacks{
        void change(int color);
    }
并且维护一个此接口的对象,在Onattach()方法中进行获取此对象(也可以在oncreateView中获取此对象,可以起到优化内存的效果,晚绑定,早结束)。
    private FragmentCallbacks callbacks;
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        callbacks= (FragmentCallbacks) getActivity();
    }
在对应的事件中调用此接口的方法( 此原理是多态,虽然这里调用的是父类中的方法,但其实父类中的方法会被屏蔽掉,调用子类中具体实现的方法
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                callbacks.change(Color.YELLOW);
            }
        });
其实是执行子类中的方法。
好了,fragment中的工作完成了,需要让activty实现此内部接口,并重写抽象方法:
public class MainActivity extends AppCompatActivity  implements LeftFragment.FragmentCallbacks {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public void change(int color) {
        LinearLayout ll = (LinearLayout) findViewById(R.id.activity_main);
        ll.setBackgroundColor(color);
    }
这边是谷歌官方推荐的方法;
注意:这里的回调接口也是为了给activity传值,由于fragment可以获取到activity的对象,通过getActivity然后强转,我们可以直接调用activity中定义的方法来进行设置值,我们定义成接口回调是为了提高扩展性,fragment可以不依赖于宿主,若写死的话,需要每次都进行强转甚至需要判断,定义成接口,只需要子类实现此接口,然后进行强制类型转换即可;大大提高扩展性;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值