一直以来,不管是Web仍是iOS、Android的应用中,为了提高应用的加载等待这段时间的用户感知体验,各类技术层出不穷。其中,尤以菊花图以及由它衍生各类加载动画最为突出。前端
对于菊花图咱们自没必要多说,如今对于加载的设计体验有了比菊花加载体验更棒的方法,即你们常看到的Skeleton Screen Loading,中文叫作骨架屏。android
所谓Skeleton Screen Loading,即表示在页面彻底渲染完成以前,用户会看到一个占位的样式,用以描绘了当前页面的大体框架,加载完成后,最终骨架屏中各个占位部分将被真实的数据替换。不少项目中都有相关的应用,如饿了么h5版本、知乎、facebook等网站中都有应用。 其效果以下图所示:webpack
iOS
iOS实现Skeleton效果的第三方库有不少,固然也能够本身建立一个,而骨架屏最核心的就是占位和属性动画。在实现方面,本文介绍几种主流的实现方式:ios
SkeletonView
实现原理
对UIView进行扩展,增长skeletonable、skeletonLayer等属性。调用showSkeleton方法,对属性skeletonable为true的视图进行遍历,找到其最上层的、skeletonable为true的子View,而后建立skeletonLayer添加到上面,构成骨架图,动效效果亦是在skeletonLayer层。须要隐藏效果时,调用hideSkeleton,一样进行遍历,移除skeletonLayer。git
简单的说,在显示占位的时候,将tableView的代理设置为经过某个对象,这个对象根据cell的Idenfier建立cell并添加占位显示。关闭显示占位的时候,将代理tableView的代理切回ViewController,正常显示。github
特色
- 不需手动写占位控件,不需处理圆角等问题,占位效果与实际控件布局一致。
- 缺点是有的控件是自适应大小,在未得到数据以前,控件位置是错误的,致使占位效果有问题。
Somo
一样是扩展UIView,添加属性somoContainer,表示占位视图的容器视图,其中每一个占位区域都是一个SomoView。对于想要显示占位效果的View,需实现协议,在协议方法中返回SomoView列表。将这些SomoView添加到somoContainer,并显示。web
特色
- 避免了上述自适应控件无数据时大小不正确的问题。
- 须要手工指定每一个占位区域,且每一个占位区域是UIView级别,不是CALayer。
TABAnimated
除此以外,TABAnimated也是一个被使用的比较多的,一样TABAnimated也是扩展的UIView。在ios中集成TABAnimated须要经历如下几步:app
1,Install
pod search TABAnimated
2,第二步(可选)
能够选择在appDelegate的didFinishLaunchingWithOptions方法全局设置动画属性,设有默认属性。例如:框架
// 设置TABAnimated相关属性 [[TABViewAnimated sharedAnimated]initWithAnimatedDuration:0.3 withColor:tab_kBackColor];
3,第三步,设置animatedStyle属性
在须要动画的view上,将属性animatedStyle设置为TABTableViewAnimationStart,不须要动画的view不用作额外的操做。less
// UIView和UICollectionView枚举 typedef NS_ENUM(NSInteger,TABViewAnimationStyle) { TABViewAnimationDefault = 0, // 默认,没有动画 TABViewAnimationStart, // 开始动画 TABViewAnimationRuning, // 动画中 TABViewAnimationEnd, // 结束动画 TABCollectionViewAnimationStart, // CollectionView 开始动画 TABCollectionViewAnimationRunning, // CollectionView 动画中 TABCollectionViewAnimationEnd // CollectionView 结束动画 }; // UITableView枚举 typedef NS_ENUM(NSInteger,TABViewAnimationStyle) { TABViewAnimationDefault = 0, // 没有动画,默认 TABViewAnimationStart, // 开始动画 TABViewAnimationEnd // 结束动画 };
// UITableView例子 - (UITableView *)mainTV { if (!_mainTV) { _mainTV = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)]; _mainTV.animatedStyle = TABTableViewAnimationStart; // 开启动画 _mainTV.delegate = self; _mainTV.dataSource = self; _mainTV.rowHeight = 100; _mainTV.backgroundColor = [UIColor whiteColor]; _mainTV.estimatedRowHeight = 0; _mainTV.estimatedSectionFooterHeight = 0; _mainTV.estimatedSectionHeaderHeight = 0; _mainTV.separatorStyle = UITableViewCellSeparatorStyleNone; } return _mainTV; } // UIView例子 - (TestHeadView *)headView { if (!_headView) { _headView = [[TestHeadView alloc]initWithFrame:CGRectMake(0, 0, tab_kScreenWidth, 90)]; _headView.animatedStyle = TABViewAnimationStart; //开启动画 } return _headView; }
4,第四步
- 将须要动的组件的属性loadStyle,设置为须要的类型,不须要动的组件不用作额外的操做;
- (可选)新增属性tabViewWidth,其为动画开启时该组件的宽度,有较为合理默认值;
typedef enum { TABViewLoadAnimationDefault = 0, //默认没有动画 TABViewLoadAnimationShort, //动画先变短再变长 TABViewLoadAnimationLong //动画先变长再变短 }TABViewLoadAnimationStyle; //view动画类型枚举
{ UILabel *lab = [[UILabel alloc]init]; [lab setFont:tab_kFont(15)]; lab.loadStyle = TABViewLoadAnimationLong; lab.tabViewWidth = 100; [lab setTextColor:[UIColor blackColor]]; [lab setText:@""]; titleLab = lab; [self.contentView addSubview:lab]; }
5,第五步
在获取到数据后,中止动画。
//中止动画,并刷新数据 _mainTV.animatedStyle = TABTableViewAnimationEnd; [_mainTV reloadData]; _headView.animatedStyle = TABViewAnimationEnd; [_headView initWithData:headGame];
示例源码连接:iOS骨架屏示例
Android
在Android中,骨架屏的实现也后不少的第三方框架,常见的有如下几个库:
ShimmerRecyclerView
ShimmerRecyclerView是一个带有闪光和指示效果的库,其运行效果以下图:
源码地址:https://github.com/sharish/ShimmerRecyclerView
Skeleton
Skeleton也是一个使用得比较普遍的库,它如今使用闪存动画的内存优化版本,所以速度更快,您也能够设置更大的布局动画。
项目源码:https://github.com/ethanhua/Skeleton
spruce-android
Spruce 是一个轻量级动画库,可帮助编排屏幕上的动画,该库同时还支持 iOS。
源码地址:https://github.com/willowtreeapps/spruce-android
前端
在前端中,经过 puppeteer 在服务端操控 headless Chrome 打开开发中的须要生成骨架屏的页面,在等待页面加载渲染完成以后,在保留页面布局样式的前提下,经过对页面中元素进行删减或增添,对已有元素经过层叠样式进行覆盖,这样达到在不改变页面布局下,隐藏图片和文字,经过样式覆盖,使得其展现为灰色块。而后将修改后的 HTML 和 CSS 样式提取出来,这样就实现了骨架屏。
前端的骨架屏实现和优化,建议读者阅读如下连接文章:
eleme骨架屏插件实现原理
page-skeleton-webpack-plugin
本文同步分享在 博客“xiangzhihong8”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。