识字粗堪供赋役,不须辛苦慕公卿。这篇文章主要讲述Android 谈谈封装那些事 --BaseActivity 和 BaseFragment相关的知识,希望能为你提供帮助。
1.前言昨天谈了BaseActivity的封装,
Android谈谈封装那些事--BaseActivity和BaseFragment(一)
有很多小伙伴提了很多建议,比如:
- 通用标题栏可以自定义View而不放在Base里面,代码更统一
- BaseEventActivity里面应该留出开关保证不需要Bus的Activity使用
- BaseStatusActivity里面就一个方法没必要新建一个
- 还有一些小的细节
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到第一次可见时执行网络请求
- 四种状态:第一次可见状态、可见状态、第一次不可见状态、不可见状态
- 销毁时处理解注册、销毁广播等问题
@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();
}
}
【Android 谈谈封装那些事 --BaseActivity 和 BaseFragment】最后提一个小问题吧:就是说如果你没有用Fragment懒加载的话而是用的viewpager的预加载,如果你没有自己定义默认预加载个数的话,那么默认肯定是会提前加载的,加入你当前fragment相邻的fragment里面有动画或者视频播放的话,切换到当前fragment时候下个fragment里面的动画或者视频就已经开始执行了,注意一下。
到此我的base就告一段落了,很多不合理的地方,我接下来私下也会去听取小伙伴们的意见进行修改,然后最后在HLibrary里面贴出来的,非常感谢大家。
推荐阅读
- Xamarin.Android之布局文件智能提示问题
- greendao 3.1.0在android studio中配置
- Android测试Handler的基本使用
- Android studio安装
- Android Duplicate files copied in APK
- android google 统计导致的文件冲突
- ionic build Android错误记录未解决
- android之Fragment基础详解
- Android package属性package name和Application ID三者的联系及区别