Android中Fragment的加载方式与数据通信详解
一、加载方式
1. 静态加载
1.1 加载步骤
(1) 创建fragment:创建自定义fragment类继承自fragment类,同时将自定义fragment类与fragment视图绑定(将layout转换成view)
view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate)
inflater用于绑定fragment的布局文件,同时将该布局转换成view对象并返回;container为fragment的ui所在的父容器。返回值为fragment显示的ui,若不显示,则返回null。
inflate(int resource, viewgroup root, boolean attachtoroot)
resource为fragment需要加载的布局文件;root为加载fragment的父viewgroup,也就是oncreateview传递进来的container;attachtoroot为是否返回父viewgroup。
(2) 使用fragment:在父视图中引入fragment,静态加载必须指定name属性以及一个唯一标识符,标识符可以为id或者tag
<!--指定在layout中实例化的fragment类,需要为“包名.类名”的完整形式--> android:name <!--唯一标识,id和tag可任选其一,不可两者都没有--> android:id android:tag
(3) 监听事件:若在父视图对应的类中设置监听事件,可以直接访问fragment中的子组件;若在fragment的类中设置,则必须通过inflate()返回的view对象访问fragment中的子组件(view.findviewbyid(id))。
1.2 简单范例
myfragment视图:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <textview android:id="@+id/fragment_text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </linearlayout>
myfragment类:
public class myfragment extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { //将layout布局转换成view对象 view view = inflater.inflate(r.layout.myfragment, container, false); //必须通过view对象对其子组件进行访问 textview textview = (textview) view.findviewbyid(r.id.fragment_text); textview.settext("这里是fragment"); //返回fragment显示ui return view; } }
引用fragment的父视图:
<?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:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.studying.staticfragmentactivity"> <fragment android:tag="fragment" android:name="com.joahyau.studying.myfragment" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </linearlayout>
父视图对应的类设置事件监听:
public class staticfragmentactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_static_fragment); //可直接通过findviewbyid访问 findviewbyid(r.id.fragment_text).setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { toast.maketext(staticfragmentactivity.this, "点击了文本", toast.length_short).show(); } }); } }
2. 动态加载
2.1 加载步骤
(1) 获取事务管理器:对fragment进行的添加、移除、替换等操作,均为事务。需通过以下代码获取事务管理器,从而对fragment进行动态操作。
fragmentmanager fm = getfragmentmanager(); fragmenttransaction ft = fm.begintransaction();
(2) 创建fragment对象:创建需要加载的fragment,而后通过add或replace等方法实现动态加载。
2.2 简单范例
布局:
<?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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="io.github.joahyau.studying.dynamicfragmentactivity"> <button android:id="@+id/load" android:text="加载" android:layout_width="match_parent" android:layout_height="80dp" /> <linearlayout android:id="@+id/container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" /> </linearlayout>
java:
public class dynamicfragmentactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_dynamic_fragment); findviewbyid(r.id.load).setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //获取事务管理器 fragmentmanager fragmentmanager = getfragmentmanager(); fragmenttransaction fragmenttransaction = fragmentmanager.begintransaction(); //创建fragment,并将其动态加载到id位container的布局中 myfragment myfragment = new myfragment(); fragmenttransaction.add(r.id.container, myfragment); //提交事务 fragmenttransaction.commit(); } }); } }
二、数据通信
3. activity向fragment传递数据
3.1 activity向动态加载的fragment传递数据
(1)在activity中获取fragment对象;
(2)创建bundle对象并传入数据;
(3)将bundle对象传递给fragment对象;
(4)在fragment中获取bundle对象并拆包得到数据。
范例:activity中只有一个id为send的button,myfragment中只有一个textview,这里就不再放布局代码了。
activity:
public class mainactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); findviewbyid(r.id.send).setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { //创建fragment对象 myfragment myfragment = new myfragment(); //创建bundle对象并传入数据 bundle bundle = new bundle(); bundle.putstring("info", "这里是向fragment传递的数据"); myfragment.setarguments(bundle); //加载fragment fragmentmanager fragmentmanager = getfragmentmanager(); fragmenttransaction begintransaction = fragmentmanager.begintransaction(); begintransaction.add(r.id.layout, myfragment, "myfragment"); begintransaction.commit(); } }); } }
fragment:
public class myfragment extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view = inflater.inflate(r.layout.my_fragment, container, false); textview tv = (textview) view.findviewbyid(r.id.text); //获取数据 string text = getarguments().get("info") + ""; tv.settext(text); return view; } }
3.2 activity向静态加载的fragment传递数据
(1)在fragment中创建作为容器的数据对象,并创建getter和setter;
(2)在activity中获取fragmentmanager;
(3)通过事务管理器的findfragmentbyid或findfragmentbytag方法,获得fragment对象;
(4)通过获得的fragment对象调用容器的setter方法进行传值。
范例:这里的布局与动态加载的布局唯一不同的就是将send按钮放在了fragment里面,其它相同。
fragment:
public class myfragment extends fragment { private button btn; private string received;//作为容器的对象 @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view = inflater.inflate(r.layout.my_fragment, container, false); textview tv = (textview) view.findviewbyid(r.id.text); tv.settext("这里是fragment"); btn = (button) view.findviewbyid(r.id.send); btn.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { toast.maketext(getactivity(), "成功接收\"" + getreceived() + "\"", toast.length_short).show(); } }); return view; } public string getreceived() { return received; } public void setreceived(string received) { this.received = received; } }
activity:
public class mainactivity extends activity { @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); fragmentmanager fragmentmanager = getfragmentmanager(); myfragment myfragment = (myfragment) fragmentmanager.findfragmentbyid(r.id.my_fragment); myfragment.setreceived("this is a test."); } }
4. fragment向activity传递数据
(1)在fragment中写一个回调接口;
(2)在activity中实现这个回调接口,实现的函数用于传值;
(3)重写fragment中onattach,在其中创建一个接口对象,得到传递过来的activity(我的理解是这个接口其实相当于传递过来的activity的一个父类,这一步是用到了多态的特性);
(4)用得到的接口对象进行传值。
fragment:
public class myfragment extends fragment { private senddata senddata; @override public void onattach(activity activity) { super.onattach(activity); //获取实现的接口对象 senddata = (senddata) activity; } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view view = inflater.inflate(r.layout.my_fragment, container, false); textview tv = (textview) view.findviewbyid(r.id.text); tv.settext("这里是fragment"); //通过接口对象传递数据 senddata.sendmsg("this is a test."); return view; } //定义一个回调接口 public interface senddata{ void sendmsg(string str); } }
activity:
public class mainactivity extends activity implements myfragment.senddata{ private button btn; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); btn = (button) findviewbyid(r.id.send); btn.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { myfragment myfragment = new myfragment(); fragmentmanager fragmentmanager = getfragmentmanager(); fragmenttransaction begintransaction = fragmentmanager.begintransaction(); begintransaction.add(r.id.layout, myfragment); begintransaction.commit(); } }); } //实现senddata接口,接收数据 @override public void sendmsg(string str) { toast.maketext(this, "成功接收\"" + str + "\"", toast.length_short).show(); } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!
推荐阅读
-
详解Android 在 ViewPager 中使用 Fragment 的懒加载
-
android中ProgressDialog与ProgressBar的使用详解
-
Android Manifest中meta-data扩展元素数据的配置与获取方式
-
Android中Fragment的加载方式与数据通信详解
-
Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题
-
Vue中定义全局变量与常量的各种方式详解
-
详解Android Activity中的几种监听器和实现方式
-
android开发AIDL跨进程通信:AIDL中RemoteCallbackList的使用及权限验证方式详解
-
Laravel中Facade的加载过程与原理详解
-
Android在fragment中编写toobar的步骤详解