Fragment中的通信

来源:互联网 发布:python爬虫培训视频 编辑:程序博客网 时间:2024/06/05 03:25

本文详细介绍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
原创粉丝点击