博客:https://juejin.im/post/5d35cbaf6fb9a07eaf2bcfec
StatusLayout
StatusLayout : 一个超高自定义度又简单的页面状态管理库
https://github.com/Colaman0/StatusLayout
业务场景需求:
在日常开发App的过程中,我们少不了对Activity/Fragment 等做一些不同状态不同UI的状态管理逻辑,比如空页面 错误重试页面 等等,网上也有很多作者写了开源库来处理这些问题
但是我看了一下这些库,个人认为有以下几个小问题
以上几个小问题相信有些开发者也有发现,在用的时候也会觉得还有改进的空间
我在公司的项目中也发现了这些问题,所以在空闲时间写了一个管理库用来管理页面,接下来就给大家介绍一下,相信能给大家在日常开发中带来更多便利,更少的代码,更多的可操作性
StatusLayout有以下几个优点
效果图
效果图来看比起普通的库多了一个淡入淡出的动画效果,这部分可以自定义,这里只给大家展现一个最基本的效果(图片太大了)
(https://user-gold-cdn.xitu.io/2019/7/22/16c1a2e363765211?imageslim)
依赖 :
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
具体使用步骤如下:
dependencies {
implementation 'com.github.Colaman0:StatusLayout:1.0.8'
}
1.第一步先把StatusLayout作为根布局,这里有以下两种写法
把StatusLayout作为根布局在activity/fragment/view 中使用
在xml内直接把StatusLayout
作为根布局,注意StatusLayout
内部子view数量不能超过1个, 所以如果UI上需求需要排列多个View的时候,需要多套一层布局,比如:
<StatusLayout>
<LinearLayout>
<View/>
<View/>
<View/>
</LinearLayout>
</StatusLayout>
通过 StatusLayout.init()方法传入Context以及你要显示到的layout资源文件,这个方法会返回一个StatusLayout对象,所以大家可以在封装BaseActivity的时候这样写:
// 后续可以通过mStatusLayout添加不同状态对应的UI
StatusLayout mStatusLayout = StatusLayout.init(this, R.layout.activity_main);
setContentView(mStatusLayout);
2. 添加不同状态对应的UI以及响应点击事件
通过add(statusconfig : StatusConfig)方法来添加一种状态布局,传入StatusConfig参数类,给大家讲一下每个参数的作用
data class StatusConfig(
var status: String?,
@field:LayoutRes
var layoutRes: Int = -1,
var view: View? = null,
@field:IdRes
var clickRes: Int = -1)
3. 切换布局
通过switchLayout()/showDefaultContent()两种方法来切换布局
4. 不同布局点击的回调
上面在add方法中讲到了StatusConfig中一个clickRes变量,相当于告诉StatusLayout我要监听这个id的view的点击事件,当它被点击的时候告诉我,可以通过setLayoutClickListener()方法来设置监听
setLayoutClickListener(new StatusLayout.OnLayoutClickListener() {
@Override
public void OnLayoutClick(View view, String status) {
// View: 对应status的rootView
// status:当前status,可以判断当前页面处于哪个status
switch (status) {
case LOADING:
Toast.makeText(MainActivity.this, LOADING, Toast.LENGTH_SHORT).show();
break;
case EMPTY:
Toast.makeText(MainActivity.this, EMPTY, Toast.LENGTH_SHORT).show();
break;
case ERROR:
// 这里通过showDefaultContent()方法展示默认的布局
mStatusLayout.showDefaultContent();
break;
}
}
});
讲解一下上面的代码,设置一个layout点击的回调监听,当layout/clickRes 对应的view被点击的时候,会回调当前是哪一个status的页面,以及对应的布局view,当我们的clickRes不传的时候,默认是整个页面响应点击事件,所以在add的时候比较灵活的处理了关于点击事件的处理,比较复杂的页面建议就在add的时候传入一个view然后在内部做处理比较合适了,避免拓展出一大堆方法。
5. 设置显示/隐藏的动画
通过setAnimation() 来设置页面显示/隐藏的的动画, 也可以通过setGlobalAnim()来设置一个全局的动画效果,setAnimation()的优先级比setGlobalAnim()更高
6.设置全局属性
考虑到APP里常见的空页面 loading 之类的页面都是比较统一的,这个时候可以通过StatusLayout.setGlobalData()方法来设置全局的属性,这个时候可以设置全局属性来避免重复添加的代码,后续可以通过add()方法来覆盖全局属性。
setGlobalData方法传入的参数和通过add()方法传入的参数值是一样的,可以参考一下代码,并且这里考虑到有些地方没有机会用到这些布局或者说不需要这些布局,所以StatusLayout只有在切换布局的时候才会去加载这些全局属性布局。
StatusLayout.setGlobalData(
StatusConfig(status = StatusLayout.STATUS_EMPTY, layoutRes = R.layout.include_empty),
StatusConfig(status = StatusLayout.STATUS_ERROR, layoutRes = R.layout.include_error, clickRes = R.id.btn_retry))
总结
以上六点就讲解完了StatusLayout的一个使用,在我一开始写的时候,是想着能尽量适应多种场景以及尽可能少的代码逻辑
整个库的核心想法就是通过status来管理页面,StatusLayout只负责管理你添加进来的布局,以及对应切换某个status的布局。并不会限制得很死要调用某个方法,所以你可以尽情得自定义你的页面,添加各种各样的布局进去,然后通过switchLayout()来切换布局就可以了。