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

1.前言

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

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

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

2.Fragment相关知识点

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

在这里就不详细介绍了,想了解的可以看我的这篇文章:

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

1.Fragment使用场景

我们可以看到市场的APP一般都是用底部Tab+fragment切换为整体架子的,或者通过viewpager作为容器嵌套fragment,再复杂点的就是fragment嵌套fragment,某书、某条等等都是这样;

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里面贴出来的,非常感谢大家。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容