前几天公司 App 做优化, 提出了不要菊花图, 原因是用户进入界面的时候弹出对话框压迫感太强并且在 iOS 端由于没有返回按钮要等请求完才能操作, 很坑爹. 恰巧那天又看到《玉刚说》的公众号推了一篇骨架屏的文章, 看了一下并且自己尝试了一下其他的接入总结一下坑点.
关于这方面的第三方库
https://github.com/sharish/ShimmerRecyclerView
一个封装了 Recycview 的遮罩控件, 使用起来比下面的要方便.
https://github.com/ethanhua/Skeleton
一个封装了遮罩层的库
https://github.com/team-supercharge/ShimmerLayout
一个使布局闪烁的库, 很多第三方库都依赖于它
遮罩库
https://github.com/elye/loaderviewlibrary
仅仅支持图片跟文本, 设置值时会去除遮罩. 具体实现可以看看源码,
https://github.com/rasoulmiri/Skeleton
遮罩控件, 支持多种控件, 但是需要嵌套多层会影响一点性能
实现方法
如效果图, 实现的思想有两种. 一种是写多一个遮罩布局, 请求成功后再替换. 这个也是上面第三方库的实现方法另一种是遮罩控件嵌套在原布局里, 显示成功后调用方法隐藏. 无论那种方式最好叫设计师给好一个遮罩 item 的原型尺寸, 否则遇到复杂布局时自己很难调节大小.
最简单的方法
https://github.com/sharish/ShimmerRecyclerView
只需要把 RecyclerView 换成 ShimmerRecyclerView 调用显示, 隐藏方法即可. 这种方法也需要写一个遮罩布局, 否则是默认的.
接入
- repositories {
- jcenter()
- maven { url "https://jitpack.io" }
- }
- dependencies {
- implementation 'com.github.sharish:ShimmerRecyclerView:v1.3'
- }
使用
- <com.cooltechworks.views.shimmer.ShimmerRecyclerView
- xmlns:App="http://schemas.android.com/apk/res-auto"
- Android:id="@+id/shimmer_recycler_view"
- Android:layout_width="match_parent"
- Android:layout_height="match_parent"
- App:shimmer_demo_child_count="10"
- App:shimmer_demo_grid_child_count="2"
- App:shimmer_demo_layout="@layout/layout_demo_grid"
- App:shimmer_demo_layout_manager_type="grid"
- App:shimmer_demo_angle="20"
- />
调用对应的显示隐藏方法
- shimmerRecycler.showShimmerAdapter();
- shimmerRecycler.hideShimmerAdapter();
Skeleton + 布局
https://github.com/ethanhua/Skeleton
这种方法比较自由, 除了 RecyclerView 以外还能用在其他布局上
接入
- repositories {
- jcenter()
- maven { url "https://jitpack.io" }
- }
- dependencies {
- implementation 'com.github.sharish:ShimmerRecyclerView:v1.3'
- }
使用
- RecyclerView:
- skeletonScreen = Skeleton.bind(recyclerView)
- .adapter(adapter)
- .load(R.layout.item_skeleton_news)
- .show();
其他 View:
- skeletonScreen = Skeleton.bind(rootView)
- .load(R.layout.layout_img_skeleton)
- .show();
提供的方法
- .shimmer(true) // whether show shimmer animation. default is true
- .count(10) // the recycler view item count. default is 10
- .color(color) // the shimmer color. default is #a2878787
- .angle(20) // the shimmer angle. default is 20;
- .duration(1000) // the shimmer animation duration. default is 1000;
- .frozen(false) // whether frozen recyclerView during skeleton showing default is true;
消失时调用
skeletonScreen.hide()
遮罩控件
上面的方法都要写一个布局, 如果不想写多一个布局的可以使用遮罩控件
https://github.com/elye/loaderviewlibrary
在 setText 或者给 src 设值时自动去除遮罩. 可以设置默认遮罩的百分比长度还可以设置带一点点的闪烁动画等等. 但是只有文本跟图片控件可用, 以及不能根据文本长度来设置遮罩, 因为 setText 之后会自动消失, 所以在某些比较复杂的布局里如果没有设计师提供尺寸图是做不出效果的.
接入
- dependencies {
- implementation 'com.elyeproj.libraries:loaderviewlibrary:1.5.0'
- }
使用
- <com.elyeproj.loaderviewlibrary.LoaderImageView
- Android:layout_width="100dp"
- Android:layout_height="100dp" />
- <com.elyeproj.loaderviewlibrary.LoaderTextView
- Android:layout_width="match_parent"
- Android:layout_height="wrap_content"
- App:width_weight="0.4"
- App:height_weight="0.8"
- App:use_gradient="true"
- App:corners="16"
- App:custom_color="@android:color/holo_green_dark" />
如果需要重新加载
myLoaderTextView.resetLoader();
2.
除了上图的效果外还支持其他效果, 并且支持任意布局, 因为它的使用方法是在原有布局上包裹一层. 这种方式的好处是, 可以不用设计师出遮罩图, 根据圆形图控件或者文字的大小套一层布局在外面后即可, 只是会比较耗费一点渲染性能.
接入
- allprojects {
- repositories {
- ...
- maven { url 'https://jitpack.io' }
- }
- }
- dependencies {
- compile 'com.github.rasoulmiri:Skeleton:v1.0.9'
- }
使用
- <io.rmiri.skeleton.SkeletonGroup
- Android:layout_width="match_parent"
- Android:layout_height="wrap_content">
- <io.rmiri.skeleton.SkeletonView ...>
- <View ... />
- </io.rmiri.skeleton.SkeletonView>
- <io.rmiri.skeleton.SkeletonView ...>
- <View ... />
- </io.rmiri.skeleton.SkeletonView>
- </io.rmiri.skeleton.SkeletonGroup>
支持动画监听
- skeletonGroup.setSkeletonListener(new SkeletonGroup.SkeletonListener() {
- @Override
- public void onStartAnimation() {
- ...
- }
- @Override
- public void onFinishAnimation() {
- ...
- }
- });
建议阅读
骨架屏 (Skeleton Screen) 在 Android 中的应用 https://mp.weixin.qq.com/s/7RwK3rbU9EURZ5kA0AK45A
最开始坚持的地方, 记录学习与生活的点点滴滴
来源: https://juejin.im/post/5c84c2165188257e16046cad