安卓學習記錄-7-UI fragment与fragment管理器
作者:互联网
#仅个人学习记录,如有疏漏,请多见谅
1:引入与分析
fragment的引入可以实现灵活的UI设计。fragment与activity类似,也有不同的地方。
它们都有布局文件xml和java类,拥有类似的生命周期。它们都属于控制器对象。
不同的是activity是由操作系统控制,而fragment由指定的activity托管,需要在activity视图中给fragment指定位置,理解为放置一个容器组件容纳fragment。这样fragment视图才能显示在屏幕上。
怎么实现新建一个fragment并且显示在activity视图特定位置呢?
一般步骤为:
①首先建立fragment的布局文件xml和Java类(继承自Fragment类,一般选用支持库版),然后将它们两个绑定在一起。(在Java类的onCreateView方法中实现)
②在activity视图中添加需要的位置添加fragment容器(FragmeLayout),为实现对fragment实例的托管,需要获取Activity.FragmentManager来绑定容器和对应获取的fragment(涉及到fragment队列,事务,资源ID等概念)。(注意:此为通过代码方式添加fragment给activity,比视图方式更加灵活,可以实现动态效果。视图方式是通过在activity视图文件中直接添加指定的fragment)
2:例子步骤
建立fragment布局文件:
右键单击res/layout文件夹,选择New->Layout resource file,命名fragment.xml
按需要设计自己的布局文件。
建立fragment类文件:
在自己工程对应包下新建Java Class,命名fragment.java。继承自Fragment
public class CrimeFragment extends Fragment {}
绑定两者:
在fragment类生命周期onCreateView方法中实现。
通过直接调用LayoutInflater.inflate(...)传入布局资源ID “R.layout.fragment”实现。该方法把布局视图转化成View类并且返回。
注意:fragment生命周期方法都是public,因为activity要托管。
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment,container,false);
return v;
}
此外还可以在onCreateView中实例化fragment视图中的组件,可以调用v.findViewById(Int id)实现。
fragment配置完后,此时还不能显示在屏幕上,接下来需要配置activity,涉及添加容器,绑定fragment等操作。
activity视图中添加容器组件:
<FrameLayout
xmlns:android = "http://schemas.android.com/apk/res/android"
android:id="@+id/framgment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
FragmeLayout是服务于fragment的容器视图,是个通用性视图,也可以托管其他fragment,后续学到再补充。
使用FragmentManager管理器:
已经定义好容器了,怎么把fragment往里面装呢?用到FragmentManager类,是在Activity类中的一个管理器,负责管理fragment并将它们的视图添加到activity的视图层级结构中。
FragmentManager具体管理:
1:fragment队列
2:fragment事务回退栈(后面学习)
获取一个FragmentManager管理器:
FragmentManager fm =getSupportFragmentManager();
获取一个fragment实例:
获取FragmentManager后,需要获取一个fragment给它管理。
通过一般方法fragment = new fragment()获取显然很简单,但这里还要介绍另一种获取方法,通过已经与对应fragment实例绑定过的fragment容器视图资源ID获取。代码如下:
Fragment fragment = fm.findFragmentById(R.id.framgment_container);
为什么容器视图资源ID可以唯一识别一个fragment呢?这其实是FragmentManager的一种内部实现机制。通过这种方法,如果要获取的fragment在队列中,FragmentManager就会直接返回他。如果不在,返回null。
那什么时候要获取的fragment在队列中呢?为什么会在队列中呢?这涉及FragmentManager另外一个机制,如果activity被销毁,它的FragmentManager会将fragment队列保存下来,这样,当activity重建时,新的FragmentManager会首先获取保存的队列,然后重建队列,恢复到原来的状态。(不需要重新添加fragment到队列,并且数据可以恢复回来,例如在旋转设备时)
因此,程序中可以首先用这种方法获取fragment,再去判断是否为null,为null时再用fragment = new fragment()来创建。
创建fragment事务来操作队列:
FragmentManager fm =getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.framgment_container);
if(fragment == null){
fragment = new Fragment();
fm.beginTransaction()
.add(R.id.framgment_container,fragment)
.commit();
}
关键代码在第5行。
beginTransaction():创建一个事务
add(R.id.framgment_container,fragment):说明这个事务要执行添加一个fragment到队列的操作,一个参数时容器资源ID,一个参数时fragment实例。其他操作还包括移除,附加,分离,替换等等。
commit():提交该事务
总结:创建一个新的fragment事务,执行一个fragment添加操作,然后提交改事务。
添加并提交事务后,我们成功绑定好容器与实例。接下来FragmentManager会马上调用fragment的onAttach,onCreate和onCreateView生命周期方法,然后fragment视图就显示在屏幕上。
3:生命周期
标签:容器,管理器,fragment,视图,队列,UI,activity,FragmentManager 来源: https://blog.csdn.net/qq_27696545/article/details/122670669