Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Fragment #51

Open
yunshuipiao opened this issue May 28, 2019 · 0 comments
Open

Android Fragment #51

yunshuipiao opened this issue May 28, 2019 · 0 comments
Labels

Comments

@yunshuipiao
Copy link
Owner

yunshuipiao commented May 28, 2019

Android Fragment

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

基础概念

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

根据官方的定义:

  • framgent 依赖于 Activity,不能独立存在
  • 一个 Activity 中可以有多个 Fragment
  • 一个 Fragment 可以被多个 Activity 重用。
  • Fragment 有自己的生命周期,并能接收输入事件
  • 可以在 Activity 运行时动态的添加和删除 Fragment。

其优势在于:

  • 模块化:逻辑放在 Fragment 中,Activity 管理和同步 Fragment 之间的信息

  • 可重用:多个 Activity 可以重用一个 Fragment 。

  • 可适配:根据硬件的屏幕尺寸,屏幕等可以实现不同的布局。

Fragment 的核心类

  • Fragment:基类,任何创建 Fragment 都需要继承该类
  • FragmentManager:管理和维护 Fragment, 也是抽象类,具体的实现类是 FragmentManagerImpl。
  • FragmentTransaction:对 Fragment 的添加,删除等操作都需要通过事务方式进行,也是抽象类,其实现类是 BackStackRecord。

如果在创建 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),且该方法调用时机:

  • onAttach()之前,调用setUserVisibleHint(false)。
  • onCreateView()之前,如果该界面为当前页,则调用setUserVisibleHint(true),否则调用setUserVisibleHint(false)。
  • 界面变为可见时,调用setUserVisibleHint(true)
  • 界面变为不可见时,调用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()来解决这个问题。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant