Android 谈谈封装那些事 --BaseActivity 和 BaseFragment(二)

1.前言

昨天谈了BaseActivity的封装,
Android谈谈封装那些事--BaseActivity和BaseFragment(一)
有不少小伙伴提了不少建议,好比:javascript

  • 通用标题栏能够自定义View而不放在Base里面,代码更统一
  • BaseEventActivity里面应该留出开关保证不须要Bus的Activity使用
  • BaseStatusActivity里面就一个方法不必新建一个
  • 还有一些小的细节

在这里感谢你们的建议了啊。我修改了一部分,后面会慢慢优化,最后在HLibrary里面贴出最优代码。还有那个BaseStatusActivity(沉浸栏)的也会继续优化的。接下来谈谈BaseFragment的封装,其实主要仍是关于Fragment的懒加载问题。java

2.Fragment相关知识点

  • 生命周期
  • Fragment的使用:静态、动态
  • Fragment应注意到的问题
  • ......

在这里就不详细介绍了,想了解的能够看个人这篇文章:网络

你真的会用Fragment了么?-Fragment解析ide

1.Fragment使用场景

咱们能够看到市场的APP通常都是用底部Tab+fragment切换为总体架子的,或者经过viewpager做为容器嵌套fragment,再复杂点的就是fragment嵌套fragment,某书、某条等等都是这样;post

2.遇到的问题

这样的话咱们遇到的问题就是当fragment不少组合使用的时候,每一个fragment里面都会加载数据或者执行动画等比较复杂的业务逻辑时,致使咱们的APP进入时屏幕卡顿,性能不好,一点都不流畅。即使是咱们在使用viewpager做为容器的时候设置预加载setOffscreenPageLimit()这个方法,其实你会发现根本不会起做用。
至于viewpager这个预加载方法为何不行?咱们能够看一下viewpager源码:性能


咱们能够看到DEFAULT_OFFSCREEN_PAGES 这里就定义了默认值是1,若是你调用该方法传进来的值小于1是无效的,会被强行的拽回1。并且DEFAULT_OFFSCREEN_PAGES 这个值是private的,子类继承ViewPager也是不可见的。
网上有的说能够将viewpager的源码复制下来粘到本身的类里面将这个默认值改成0,这个目前还没试过,即便能够感受也有些别扭,更况且咱们使用场景也不必定须要viewpager呢

3.Fragment懒加载

这是靠Fragment里有一个setUserVisibleHint(boolean isVisibleToUser)的方法,咱们能够在这个方法里作判断,当其True可见时(即切换到某一个具体Fragment)时才去加载数据,这样能够省流量。
具体怎么去操做呢?优化

  • 预加载初始化数据和组件等轻量操做
  • 切换tab到第一次可见时执行网络请求
  • 四种状态:第一次可见状态、可见状态、第一次不可见状态、不可见状态
  • 销毁时处理解注册、销毁广播等问题

3.BaseFragment封装

1.初始化xml文件

@Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (getContentViewLayoutID() != 0) {
            return inflater.inflate(getContentViewLayoutID(), null);
        } else {
            return super.onCreateView(inflater, container, savedInstanceState);
        }
    }

        protected abstract int getContentViewLayoutID();复制代码

2.注解绑定以及初始化组件

@Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this,view);
        initViewsAndEvents(view);
    }

    protected abstract void initViewsAndEvents(View view);复制代码

3.四种“见”的状态拆分

@Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initPrepare();
    }

    private synchronized void initPrepare() {
        if (isPrepared) {
            onFirstUserVisible();
        } else {
            isPrepared = true;
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            if (isFirstVisible) {
                isFirstVisible = false;
                initPrepare();
            } else {
                onUserVisible();
            }
        } else {
            if (isFirstInvisible) {
                isFirstInvisible = false;
                onFirstUserInvisible();
            } else {
                onUserInvisible();
            }
        }
    }

    protected abstract void onFirstUserVisible();
    protected abstract void onUserVisible();
    private void onFirstUserInvisible() { }
    protected abstract void onUserInvisible();复制代码

4.最后解注册销毁等工做

@Override
    public void onDestroy() {
        DetoryViewAndThing();
        super.onDestroy();
    }

    protected abstract void DetoryViewAndThing();复制代码

5.跳转界面等方法

/** * 打开一个Activity 默认 不关闭当前activity */
    public void gotoActivity(Class<?> clz) {
        gotoActivity(clz, false, null);
    }

    public void gotoActivity(Class<?> clz, boolean isCloseCurrentActivity) {
        gotoActivity(clz, isCloseCurrentActivity, null);
    }

    public void gotoActivity(Class<?> clz, boolean isCloseCurrentActivity, Bundle ex) {
        Intent intent = new Intent(mActivity, clz);
        if (ex != null) intent.putExtras(ex);
        startActivity(intent);
        if (isCloseCurrentActivity) {
            mActivity.finish();
        }
    }复制代码

最后提一个小问题吧:就是说若是你没有用Fragment懒加载的话而是用的viewpager的预加载,若是你没有本身定义默认预加载个数的话,那么默认确定是会提早加载的,加入你当前fragment相邻的fragment里面有动画或者视频播放的话,切换到当前fragment时候下个fragment里面的动画或者视频就已经开始执行了,注意一下。
到此个人base就告一段落了,不少不合理的地方,我接下来私下也会去听取小伙伴们的意见进行修改,而后最后在HLibrary里面贴出来的,很是感谢你们。动画

相关文章
相关标签/搜索