yunshuipiao / Potato

Read the fucking source code for the Android interview
Apache License 2.0
80 stars 12 forks source link

Android Fragment #51

Open yunshuipiao opened 5 years ago

yunshuipiao commented 5 years ago

Android Fragment

这篇文章讲解 Fragment 的基本概念使用。

基础概念

因为support库是不断更新的,因此建议使用support库中的android.support.v4.app.Fragment,而不要用系统自带的android.app.Fragment。而如果要使用support库的Fragment,Activity必须要继承FragmentActivity(AppCompatActivity是FragmentActivity的子类)

根据官方的定义:

其优势在于:

Fragment 的核心类

如果在创建 Fragment时要传入参数,必须通过 setArguments() 方式添加,而不建议通过 Fragment 添加带参数的构造函数。因为 通过前者方式添加,在由于内存紧张导致 Fragment 被系统杀死并恢复时可以保留这些数据。在Fragment的 onAttach() 中通过 getArguments() 获得传进来的参数,并在之后使用这些参数。

onSaveInstanceState()是当activity可能被系统回收的情况下,而且是在onStop()之前。注意是有可能,如果是已经确定会被销毁,比如用户按下了返回键,或者调用了finish()方法销毁activity,则onSaveInstanceState不会被调用。或者也可以说,此方法只有在activity被异常终止的情况下会被调用

onRestoreInstanceState(Bundle savedInstanceState)只有在activity确实是被系统回收,重新创建activity情况下才会被调用,并且是在onStart()之后,onResume()之前的。

懒加载

懒加载主要用于ViewPager且每页是Fragment的情况,场景为微信主界面,底部有4个tab,当滑到另一个tab时,先显示”正在加载”,过一会才会显示正常界面。

默认情况,ViewPager会缓存当前页和左右相邻的界面。实现懒加载的主要原因是:用户没进入的界面需要有一系列的网络、数据库等耗资源、耗时的操作,预先做这些数据加载是不必要的。

这里懒加载的实现思路是:用户不可见的界面,只初始化UI,但是不会做任何数据加载。等滑到该页,才会异步做数据加载并更新UI。

懒加载主要依赖Fragment的setUserVisibleHint(boolean isVisible)方法,当Fragment变为可见时,会调用setUserVisibleHint(true);当Fragment变为不可见时,会调用setUserVisibleHint(false),且该方法调用时机:

commitAllowingStateLoss

使用Fragment的时候偶尔会有这么一个报错,Can not perform this action after onSaveInstanceState,意思为无法再onSaveInstanceState之后执行该操作,这个操作就是指commit()。

为什么我们会有这种报错呢?

因为我们在使用add(),remove(),replace()等方法将Fragment的变化添加进去,然后在通过commit去提交这些变化(另外,在commit之前可以去调用addToBackState()方法,将这些变化加入到activity管理的back stack中去,这样用户调用返回键就可以回退这些变化了),提交完成之后这些变化就会应用到我们的Fragment中去。但是,这个commit()方法,你只能在avtivity存储他的状态之前调用,也就是onSaveInstanceState()。

activity有一个保存状态的方法和恢复状态的方法。

在onSaveInstanceState()方法之后去调用commit(),就会抛出我们遇到的这个异常,这是因为在onSaveInstanceState()之后调用commit()方法,这些变化就不会被activity存储,即这些状态会被丢失,但我们可以去用commitAllowingStateLoss()这个方法去代替commit()来解决这个问题。