全栈工程师开发手册 (作者:栾鹏)
安卓教程全解

安卓中Fragment可以没有UI,不需要manifest中注册,只能嵌套在一个activity存在。

在Fragment基础上,系统派生处理另外几种fragment

1、DialogFragment:一个fragment可以在fragment的父activity上显示一个浮动的对话框,而且可以自定义对话框的UI

2、ListFragment:可以通过绑定数据源呈现一个Listview作为它主要的UI展示方式

3、WebViewFragment:封装了WebView,当Fragment被暂停或恢复时,子WebView同样会被暂停和恢复

fragment布局在activity的方式

在activity中设置fragment有2种方式。

1、在xml中设置一个FrameLayout的容器,使用java为其添加一个fragment。

2、在xml中直接引用自定义的fragment。

我们设置activity的UI如下:一个空的fragment容器:FrameLayout,一个自定义Fragment,一个自定义ListFragment。

activity_frament.xml

<?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"><!-- 作为自定义fragment的父容器,在java中去填充这个容器 --><FrameLayoutandroid:id="@+id/activity_fragment_container"android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"android:background="@color/red"  /> <!-- 直接引用java中自定义的Fagment,必须为该fragment设置id或tag --><fragment android:name="com.lp.app.Fragment1"android:id="@+id/activity_fragment_item"android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="3"android:background="@color/green"  /><!-- 直接引用java中自定义的ListFragment,必须为该fragment设置id或tag  --><fragment android:name="com.lp.app.Fragment_list"android:id="@+id/activity_fragment_list"android:layout_width="match_parent" android:layout_height="wrap_content"android:layout_weight="3"android:background="@color/blue"  />
</LinearLayout>

在activity中使用java操作Fragment、ListFragment

对于在UI 的xml文件中设置的fragment容器FrameLayout,和直接引用的自定义Fragment、ListFragment,我们分别进行操作示例。

1、在activity的java中操作Fragment

包括向容器中添加fragment(add),查找fragment(findFragmentById、findFragmentByTag),fragment的隐藏(hide),显示(show)、删除(remove),替换容器中的fragment(replace),fragment入栈(addToBackStack),事务提交动画(setTransition),事务提交(commit),事务立即执行(executePendingTransactions)。

 public void fragmentmanagerfun(){FragmentManager fragmentmanager=getFragmentManager();  //每个activity都包含一个Fragment Manager来管理它所包含的FragmentFragmentTransaction fragmentTransaction =fragmentmanager.beginTransaction();  ////添加fragmentfragmentTransaction.add(R.id.activity_fragment_container, Fragment1.newInstance("这是第1个fragment"),"tag1");  //将fragment的实例添加到容器view中(若fragment没有UI,则不需要容器),同时可以为fragment添加tag名称fragmentTransaction.add(R.id.activity_fragment_container, new Fragment1(),"tag2");  //一个FrameLayout可以添加多层fragmentfragmentTransaction.add(new Fragment1(),"tag3");  //可以添加没有ui的fragmentfragmentTransaction.commit();   //保存修改,一个fragmentTransaction只能使用一次commit,方法并不会立即执行事务fragmentmanager.executePendingTransactions();  //立即执行上面的事务。FragmentTransaction fragmentTransaction1 =fragmentmanager.beginTransaction();   //使用保存后,需要重新创建一个才能再次使用保存//查询fragment,获取引用Fragment fragment1=fragmentmanager.findFragmentById(R.id.activity_fragment_item);  //只能查找布局文件中的fragmentFragment fragment2=fragmentmanager.findFragmentByTag("tag2");  //通过tag查找java文件中添加的fragment,没保存前无法找到//判断是否被添加到了容器中if(fragment2.isAdded()){//隐藏当前的Fragment,仅仅是设为不可见,并不会销毁fragmentTransaction1.hide(fragment2);//显示之前隐藏的FragmentfragmentTransaction1.show(fragment2);//删除fragmentfragmentTransaction1.remove(fragment2);  //去除fragment,跟add是相反操作(无法移除在xml中添加的)}//替换fragmentfragmentTransaction1.replace(R.id.activity_fragment_container, Fragment1.newInstance("这是第2个fragment"),"tag3");  //替换fragment,先remove容器下层的一个fragment,再加入一个fragment,同时可以为fragment添加tag名称String tag=null;fragmentTransaction1.addToBackStack(tag);  //在提交前将当前fragment视图保存到由宿主 Activity管辖的后退栈中(通过点击back按钮更换的视图)//调用 addOnBackStackChangedListener() 方法注册监听器,用于监听后退栈的变化。fragmentTransaction1.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);  //使事务变化动起来,使用系统过渡动画fragmentTransaction1.setCustomAnimations(R.animator.anim1, R.animator.anim1);  //使用自定义动画,前者应用到添加的fragment中,后者应用到删除的fragment中fragmentTransaction1.commit();   //保存修改,只能使用一次commit}

2、在父activity的java中操作ListFragment(设置更改ListFragment的绑定数据)

 private ArrayAdapter<String> aa=null;private ArrayList<String> items = new ArrayList<String>();//在activity中设置listfragment的数据public void listfragmentfun() {FragmentManager fragmentmanager=getFragmentManager(); Fragment_list fragment_list=(Fragment_list)fragmentmanager.findFragmentById(R.id.activity_fragment_list);items.clear();for (int i = 0; i < 5; i++) {items.add("新选项" + i);}aa=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,items);fragment_list.setListAdapter(aa);
}

Fragment的生命周期

可以看到Fragment比Activity多了几个额外的生命周期回调方法:

onAttach(Activity)
当Fragment与Activity发生关联时调用。

onCreateView(LayoutInflater, ViewGroup,Bundle)
创建该Fragment的视图

onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用

onDestoryView()
与onCreateView想对应,当该Fragment的视图被移除时调用

onDetach()
与onAttach相对应,当Fragment与Activity关联被取消时调用

注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,

通过自定义fragment文件Fragment1 .java来实现fragment的全部生命周期函数

import com.lp.app.R;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;public class Fragment1 extends Fragment{ Context context;   //指向父activity//activity在构造时向fragment传递参数。不使用构造函数,使用为activity重新创建,下属fragment的字段会丢失,bundle会保留private static final String ARG = "arg";public static Fragment1 newInstance(String arg){Fragment1 fragment = new Fragment1();Bundle bundle = new Bundle();bundle.putString(ARG, arg);fragment.setArguments(bundle);  //在fragment内通过getArguments读取参数return fragment;}//在fragment内部调用获取参数public String getArg(){String arg = "这是一个fragment";  //默认参数值if(getArguments()!=null)arg = getArguments().getString(ARG);return arg;}//调用该方法时Fragment会被连接到它的父activity上@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);Log.v("frament生命周期", "fragment连接到activity");}//调用该方法来进行Fragment的初始创建@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);context = getActivity();   //获得对父activity的引用//初始化fragmentLog.v("frament生命周期", "fragment初始化");}//一但Fragment已被创建,要创建它自己的用户界面时调用该方法。填充UI,获取控件引用,设置函数,创建service和timer。没有界面时不需要此函数//可以直接控制fragment中的控件,并可以调用接口函数,实现调用父activity中函数@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {//创建或者填充Fragment的UI,并返回它,如果这个Fragment没有UI,那么返回nullView view =   inflater.inflate(R.layout.mylinearlayout, container, false);final TextView myTextView = (TextView)view.findViewById(R.id.mylinearlayout_text1);myTextView.setText(getArg());  //设置控件属性,或事件函数,这里读取了存储在fragment中的参数Log.v("frament生命周期", "fragment创建UI");return view;}//一旦父activity和Fragment的UI已被创建,则调用该方法@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);//完成Fragment的初始化,尤其是那些父activity被初始化完成后或者Fragment的view被完全填充后才能做的事情Log.v("frament生命周期", "fragment的ui已创建");}// 在可见生命周期的开始时被调用@Overridepublic void onStart(){super.onStart();// 应用所有需要的UI变化,现在Fragment是可见的Log.v("frament生命周期", "fragment可见周期开始");}//在活动生命周期开始时被调用@Overridepublic void onResume(){super.onResume();//恢复所有暂停的Fragment需要的UI更新,线程或进程,但在非活动状态它是暂停的Log.v("frament生命周期", "fragment活动周期恢复");}// 在活动生命周期结束时被调用@Overridepublic void onPause(){// 当activity不是活动的前台activity时,需要暂停UI的更新、挂起线程或者暂停那些不需要更新的CPU的集中处理。由于调用这个方法后,进程可能被终止,所以要保存所有的编辑和状态改变信息super.onPause();Log.v("frament生命周期", "fragment活动周期暂停");}//在活动生命周期结束时,调用该方法保存UI的状态变化@Overridepublic void onSaveInstanceState(Bundle savedInstanceState) {// 将UI的状态改变信息保存在savedInstanceState中//这个Bundle会被传递到oncreate、oncreateview和onactivitycreate(如果它的父activity被终止并且重新启动)方法中super.onSaveInstanceState(savedInstanceState);Log.v("frament生命周期", "fragment保存ui");}//在可见生命周期结束时调用该方法@Overridepublic void onStop(){// 当fragment不可见时,暂停其余的UI更新、挂起线程或暂停不再需要的处理super.onStop();Log.v("frament生命周期", "fragment可见周期结束");}// 当fragment的view被分离时,调用该方法@Overridepublic void onDestroyView() {//清除资源相关viewsuper.onDestroyView();Log.v("frament生命周期", "fragment中view分离");}//在整个生命周期结束时调用该方法@Overridepublic void onDestroy(){// 清除所有的资源,包括结束线程和关闭数据库连接等super.onDestroy();Log.v("frament生命周期", "fragment结束");}// 当fragment从它的父activity上分离时,调用该方法@Overridepublic void onDetach() {super.onDetach();Log.v("frament生命周期", "fragment脱离activity");}
}

自定义fragment的布局文件使用一个简单的ViewGroup文件mylinearlayout.xml来实现。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/mylinearlayout_text1"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="一个linearlayout中的textview" />
</LinearLayout>

ListFragment的生命周期

在自定义的ListFragment中,我们主要需要注意的是onCreate启动函数、onCreateView布局UI函数、onListItemClick选项点击函数。

使用自定义ListFragment文件Fragment_list.java实现基本的函数

import com.lp.app.R; import android.app.ListFragment;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;public class Fragment_list extends ListFragment{   Context context;  //指向父activityInterface1 interface1;   //使用接口实现fragment和activity之间共享事件private ArrayAdapter<String> adapter;//可以在ListFragment内绑定数据源(也可以在activity中为ListFragment绑定数据源)@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);context = getActivity();   //获得对父activity的引用//获取对父Activity的引用,进而获取父activity中的函数(接口)和变量,interface1 = (Interface1)context;//定义一个数组List<String> data = new ArrayList<String>();for (int i = 0; i < 30; i++) {data.add("listfragment选项" + i);}//将数组加到ArrayAdapter当中adapter = new ArrayAdapter<String>(context,R.layout.mytextview, data);  //使用一个系统布局,当做list每个项的布局//绑定适配器时,必须通过ListFragment.setListAdapter()接口,而不是ListView.setAdapter()或其它方法setListAdapter(adapter);Log.v("ListFragment", "listfragment启动绑定数据源");}//创建或者填充Fragment的UI,并返回它,如果这个Fragment没有UI,那么返回null@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_list, container, false);Log.v("ListFragment", "listfragment布局整体UI");return view;}//列表每一项的点击事件@Overridepublic void onListItemClick(ListView listview, View v, int position, long id) {super.onListItemClick(listview, v, position, id);interface1.callback("点击了选项"+String.valueOf(position));   //通过接口调用activity中函数Log.v("ListFragment", "点击了选项"+String.valueOf(position));}}

自定义ListFragment的布局文件要使用一个包含listview的ViewGroup来实现。

这里使用fragment_list.xml来实现

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><ListView  android:id="@+id/android:list"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  />
</LinearLayout>

自定义ListFragment文件中的listview的每一项的布局文件,可以选用自定义的view或ViewGroup或系统自带的布局文件(android.R.layout.simple_list_item_1)。

这里使用仅有一个textview的布局文件mytextview.xml来实现

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="一个textview"android:id="@+id/mytext1"/>

构建fragment时传递参数。

一般在创建对象时,赋予参数,使用构造函数,但是在fragment创建时,我们一般使用Bundle存储数据。是因为activity重新创建,下属fragment的字段会丢失,但是bundle数据会保留。

所以在自定义fragment中使用以下代码创建构造fragment,并读取fragment绑定的参数

private static final String ARG = "arg";public static Fragment1 newInstance(String arg){Fragment1 fragment = new Fragment1();Bundle bundle = new Bundle();bundle.putString(ARG, arg);fragment.setArguments(bundle);  //在fragment内通过getArguments读取参数return fragment;}//获取fragment绑定的参数public String getArg(){String arg = "这是一个fragment";  //默认参数值if(getArguments()!=null)arg = getArguments().getString(ARG);return arg;}

在activity中可以使用下面两种方式构建自定义的fragment

Fragment1 fragmenttemp1 =Fragment1.newInstance("这是第1个fragment");   //构建一个绑定了参数的fragment
Fragment1 fragmenttemp2 =new Fragment1(); //构建一个没有绑定参数的fragment

activity与fragment的相互引用

在activity中可以使用findFragmentById、findFragmentByTag获取对子fragment的引用

Fragment fragment1=getFragmentManager().findFragmentById(R.id.activity_fragment_item);  //只能查找布局文件中的fragment
Fragment fragment2=getFragmentManager().findFragmentByTag("tag2");  //通过tag查找java文件中添加的fragment,没保存前无法找到

在fragment中可以通过getActivity获得对父activity的引用。

Context context;   //指向父activity
//调用该方法时Fragment会被连接到它的父activity上@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);context = getActivity();   //获得对父activity的引用Log.v("frament生命周期", "fragment连接到activity");}

fragment向activity传递数据

一个activity下往往包含多个fragment,多个fragment以及activity之间需要相互共享数据,一个有效的实现方法,是在fragment定义声明接口,并调用这个接口函数,而在activity中实现这个接口函数。

1、首先你要自定义一个接口文件。这里设置一个简单的接口Interface1.java


//在fragment中声明接口,调用接口函数,在activity中定义接口函数
public interface Interface1{public void callback(Object object);   //声明接口函数
}

2、在自定义fragment中定义一个接口变量

Interface1 interface1;   //使用接口实现fragment和activity之间共享事件
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);context = getActivity();   //获得对父activity的引用//获取对父Activity的引用,进而获取父activity中的函数(接口)和变量,interface1 = (Interface1)context;
}

3、在这个fragment中边可以调用接口函数。也就是向activity传递数据

 public void returndata(Object object) {interface1.callback(object);   //通过接口}

4、在activity中实现这个接口,并接受fragment传递的数据

public class Activity_fragment extends Activity implements Interface1{  //activity和fragment之间的事件共享,通过接口,activity接收fragment传来的数据,以便在自身或其他fragment中应用@Overridepublic void callback(Object object) {Log.v("fragment的主窗口", object.toString());//控制UI或调用其他fragment中的函数}
}

安卓中fragment的使用全解相关推荐

  1. 安卓调用系统语音识别功能全解(谷歌语音服务):获取识别结果,使用语音识别进行搜索。

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓调用系统语音识别功能全解(谷歌语音服务):获取识别结果,使用语音识别进行搜索. 首先要添加权限 <uses-permission andro ...

  2. 安卓电话和网络开发全解:电话硬件检测、电话服务信息、sim信息、网络服务信息、数据连接和数据传输信息、电话状态监听

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓电话和网络开发全解,包括电话硬件检测.电话服务信息.sim信息.网络服务信息.数据连接和数据传输信息.通过phone state listener ...

  3. 语义分割中的深度学习方法全解:从FCN、SegNet到各版本DeepLab

    语义分割中的深度学习方法全解:从FCN.SegNet到各版本DeepLab 原文:https://www.sohu.com/a/155907339_610300 图像语义分割就是机器自动从图像中分割出 ...

  4. python中的format什么意思中文-Python中format()格式输出全解

    格式化输出:format() format():把传统的%替换为{}来实现格式化输出 1.使用位置参数:就是在字符串中把需要输出的变量值用{}来代替,然后用format()来修改使之成为想要的字符串, ...

  5. 安卓Dialog弹出对话框全解:包含了AlertDialog,DialogFragment

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 Dialog基类中并没有定义界面,所以如果使用dialog类设置弹出框,需要使用xml自定义UI. 当然系统也自带了几个dialog派生的弹出框,例如 ...

  6. 安卓自定义相机拍照功能全解(不调用系统相机)

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓实现一个相机的基本功能. 启动和释放相机 由于拍照功能一般需要实时预览,所以比较耗电,因此在窗口的恢复和暂停函数中需要启动和释放相机 privat ...

  7. python网络爬虫系列教程——python中pyquery库应用全解

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python网络爬虫lxml库的应用全解. 在线安装方法:cmd中输入"pip install pyquery" 离线安装 ...

  8. python网络爬虫系列教程——python中lxml库应用全解(xpath表达式)

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python网络爬虫lxml库的应用全解. 在线安装方法:cmd中输入"pip install lxml" 离线安装,下载 ...

  9. python网络爬虫系列教程——python中requests库应用全解

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python中requests库的基础应用,网页数据挖掘的常用库之一.也就是说最主要的功能是从网页抓取数据. 使用前需要先联网安装reques ...

最新文章

  1. 一本关于 女仆小说的构思,有能力写的看下
  2. [codevs1022]覆盖
  3. Druid 内置Filter配置
  4. 基于matlab的信号与系统实例,华南理工大学信号与系统实验基于Matlab的信号处理实例...
  5. 互联网产品哪个不火哪个就在红利期
  6. sqoop导入数据(保持一致性)--staging-table
  7. 第八章第二层交换和生成树协议(STP)
  8. jquery name选择器_jQuery学习(1)
  9. Android电视远程桌面,180元让电视变电脑 远程桌面终端评测
  10. linux usb转串口驱动报错,USB转串口驱动编译出错
  11. 如何填写台式计算机参数,教你如何看懂电脑各配置参数
  12. 密码爆破 hashcat+rar2john破解rar5压缩包密码
  13. git push出现 remote: Support for password authentication was removed on August 13, 2021.
  14. 边沿触发是什么意思_epoll 水平触发 边沿触发
  15. tcl/tk参考——tcl内建命令
  16. 网站 图标 背景 素材 网址 js效果网址 导航效果网址 网址大全 素材集
  17. Ukulele 那些花儿
  18. 使用ADB和Python实现手机自动刷视频(快手极速版、抖音极速版)
  19. 一个神奇指标公式,能找到立刻单边行情的品种,准确率惊人,堪称交易法宝!
  20. 2020年11月28日

热门文章

  1. Vue-Cli3配置多页面应用(详)
  2. dfs时间复杂度_Python实现图的经典DFS、BFS、Dijkstra、Floyd、Prim、Kruskal算法
  3. Axure的一些入门小案例
  4. JavaScript创建页面节点
  5. h5比html新增加的标签,H5新增的标签以及改良的标签
  6. oracle procedure可以执行非常复杂的语句吗,oracle-存储过程(procedure)
  7. PowerDesigner name与code同步问题
  8. ExtJs 4.x MVC 架构
  9. web前后台数据交互的四种方式
  10. 【CCCC】L2-018 多项式A除以B (25分),多项式除法