欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中Fragment的加载方式与数据通信详解

程序员文章站 2023-01-09 14:08:37
一、加载方式 1. 静态加载 1.1 加载步骤 (1) 创建fragment:创建自定义fragment类继承自fragment类,同时将自定义fragment类与f...

一、加载方式

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();
 }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!