博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android开发——Fragment知识整理(一)
阅读量:5245 次
发布时间:2019-06-14

本文共 4887 字,大约阅读时间需要 16 分钟。

0.  前言

Fragment,顾名思义是片段的意思,可以把Fragment当成Activity的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成。Fragment需要被嵌套到Activity上面才能起作用,Fragment可以充分利用屏幕面积,而且也可以更方便用户进行交互操作。Fragment是在Android3.0API level 11引入的,如果你要适配之前的系统,需要先导入Android-support-v4jar包,继承FragmentActivity并通过getSupportFragmentManager获得FragmentManager

 

1.  Fragment声明周期

Fragment的生命周期和Activity很像,只是多了几个方法如下所示。需要注意的是,因为Fragment是依附于Activity的,所以Activity的生命周期会影响到Fragment的生命周期,如下onActivityCreated()的调用时机就说明了这一点。还有比如,如果Activity是暂停状态,其中所有的Fragment都是暂停状态。如果Activity被销毁,那么它其中的所有Fragment都会被销毁。

//当Fragment被绑定到Activity时被调用onAttach()//创建该Fragment的视图,最常用,除了这个方法其余方法调用都需要superonCreateView()//当Activity的onCreate方法返回时调用onActivityCreated()//移除Fragment的布局时被调用,跟onCreateView()对应onDestroyView()//当Fragment跟Activity解除关联时被调用,跟onAttach()对应onDetach()

2.  Fragment的使用方式

2.1  静态方式

静态方式是把Fragment当成普通的控件,直接写在Activity的布局文件中。

首先写一个类继承Fragment,重写onCreateView,使用inflate决定Fragemnt的布局。

public class MyFragment extends Fragment    {          @Override        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){            View view = inflater.inflate(R.layout.myfragment, container, false);                    return view;        }    }

最后直接在Activity中布局文件中声明此Fragment,就当和普通的View一样使用即可。

2.2  动态方式

动态方式可以灵活地添加、更新、以及删除Fragment,首先将Activity的布局设置为空。

这里结合具体例子体现代码中的逻辑。有时候,我们可能有这样的需求,比如京东商城APP导航栏每个按钮对应一个fragment,当用户按下BACK键,会先判断若不是首页的fragment则回到首页的fragment,再按下BACK才会退出应用,达到了比较好的用户体验效果。这就需要用到Fragment的回退栈

 首先需要将Fragment1添加进Activity的FrameLayou中,在Activity的onCreate()中进行逻辑控制。这里我们使用add()对Fragment进行了动态的加载。具体API功能可以参考下文的总结。

FragmentTransaction ft= getFragmentManager().beginTransaction();  ft.add(R.id.id_content, new FragmentOne(),"ONE");  ft.commit();

接着将介绍从Fragment1跳转到Fragment2的按钮逻辑,假设该按钮在Fragment1上。

public class FragmentOne extends Fragment implements OnClickListener {      private Button mBtn;      @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState)  {          View view = inflater.inflate(R.layout.fragment_one, container, false);          mBtn = (Button) view.findViewById(R.id.fragment_one_btn);          mBtn.setOnClickListener(this);          return view;      }      @Override      public void onClick(View v)  {          FragmentTwo two = new FragmentTwo();          FragmentTransaction  ft = getFragmentManager().beginTransaction();          ft.replace(R.id.id_content, fTwo, "TWO");          ft.addToBackStack(null);          ft.commit();      }  }

这个逻辑跳转Fragment2中,使用了replace()方法,replaceremoveadd的合体,如果Fragment1没有被添加到回退栈,跳转时Fragment1实例会被销毁。上面源码中倒数第二行我们调用了tx.addToBackStack(null)Fragment1添加到了回退栈,所以Fragment1实例不会被销毁,但是视图层次依然会被销毁,即会调用onDestoryViewonCreateView,即当我们按下BACK键回到Fragment1时,Fragment1上诸如EditText上曾经编辑的文字会消失。那么如何保证曾经的输入还在呢?可以如下这样写点击逻辑。

public void onClick(View v)  {         FragmentTwo two = new FragmentTwo();          FragmentTransaction  ft = getFragmentManager().beginTransaction();          ft.hide(this);          ft.add(R.id.id_content, fTwo, "TWO");          ft.addToBackStack(null);          ft.commit();      }

这里没有使用replace,而是先hide当前Fragment,再添加Fragment2实例,最后Fragment1添加到回退栈,这样即可实现文字的保留。

接下来实现,无论接下来Fragment2在进入Fragment3、4、5,用户点击Back键,直接回到Fragment1,如果直接在主界面Fragment1则直接退出的逻辑:

public boolean onKeyDown(int keyCode, KeyEvent event) {     if (keyCode == KeyEvent.KEYCODE_BACK) {     // 获取当前回退栈中的Fragment个数     int backStackEntryCount = fragmentManager.getBackStackEntryCount();        if (backStackEntryCount > 1) {        // 如果回退栈中Fragment个数大于1则一直退出         while (fragmentManager.getBackStackEntryCount() > 1) {             fragmentManager.popBackStackImmediate();            }         } else {                finish();          }      }        return true;}

3  API介绍

这一小节介绍Fragment相关的API。这些常用API的作用还是要熟悉的。

//获取FragmentManage的方式,v4包中为getSupportFragmentManagergetFragmentManager()//开启一个事务,并添加/删除一个Fragment//从Activity中remove一个Fragment时,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁,而后面的detach则不会销毁实例,只是销毁其视图结构FragmentTransaction transaction = fm.benginTransatcion();transaction.add() transaction.remove() transatcion.commit()//提交一个事务,一定要在Activity.onSaveInstance()之前调用//使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体transaction.replace()//隐藏/显示当前的Fragment,隐藏仅仅是设为不可见,并不会销毁transaction.hide()transaction.show()//会将view从UI中移除, fragment的状态依然由FragmentManager维护detach()//重建view视图,附加到UI上并显示attach()

下面的API是关于回退栈的,均为fm所调用。

//将Fragment添加到回退栈中addToBackStack(tag) //如果i=0则回退到该tag所对应的Fragment层//如果i=FragmentManager.POP_BACK_STACK_INCLUSIVE则回退到该tag所对应的Fragment的上一层popBackStack(String tag, int i)//立即清除回退栈中栈顶FragmentpopBackStackImmediate()//获取回退栈中Fragment的个数getBackStackEntryCount()//获取回退栈中该索引值下的Fragment//若为fragmentManager.getBackStackEntryCount() – 1即获取当前Fragment节点,继续getName()即可获得该节点tag标记getBackStackEntryAt(int index)

下一篇将着重于介绍Fragment和Activity之间的通信以及使用Fragment保存Activity销毁时数据的一些知识。

转载于:https://www.cnblogs.com/qitian1/p/6461456.html

你可能感兴趣的文章
SIGPIPE并产生一个信号处理
查看>>
CentOS
查看>>
Linux pipe函数
查看>>
java equals 小记
查看>>
爬虫-通用代码框架
查看>>
2019春 软件工程实践 助教总结
查看>>
YUV 格式的视频呈现
查看>>
Android弹出框的学习
查看>>
现代程序设计 作业1
查看>>
在android开发中添加外挂字体
查看>>
Zerver是一个C#开发的Nginx+PHP+Mysql+memcached+redis绿色集成开发环境
查看>>
多线程实现资源共享的问题学习与总结
查看>>
Learning-Python【26】:反射及内置方法
查看>>
torch教程[1]用numpy实现三层全连接神经网络
查看>>
java实现哈弗曼树
查看>>
转:Web 测试的创作与调试技术
查看>>
python学习笔记3-列表
查看>>
程序的静态链接,动态链接和装载 (补充)
查看>>
关于本博客说明
查看>>
线程androidAndroid ConditionVariable的用法
查看>>