一直以來,不管是Web仍是iOS、Android的應用中,爲了提高應用的加載等待這段時間的用戶感知體驗,各類技術層出不窮。其中,尤以菊花圖以及由它衍生各類加載動畫最爲突出。前端
對於菊花圖咱們自沒必要多說,如今對於加載的設計體驗有了比菊花加載體驗更棒的方法,即你們常看到的Skeleton Screen Loading,中文叫作骨架屏。android
所謂Skeleton Screen Loading,即表示在頁面徹底渲染完成以前,用戶會看到一個佔位的樣式,用以描繪了當前頁面的大體框架,加載完成後,最終骨架屏中各個佔位部分將被真實的數據替換。不少項目中都有相關的應用,如餓了麼h5版本、知乎、facebook等網站中都有應用。 其效果以下圖所示:webpack
iOS實現Skeleton效果的第三方庫有不少,固然也能夠本身建立一個,而骨架屏最核心的就是佔位和屬性動畫。在實現方面,本文介紹幾種主流的實現方式:ios
對UIView進行擴展,增長skeletonable、skeletonLayer等屬性。調用showSkeleton方法,對屬性skeletonable爲true的視圖進行遍歷,找到其最上層的、skeletonable爲true的子View,而後建立skeletonLayer添加到上面,構成骨架圖,動效效果亦是在skeletonLayer層。須要隱藏效果時,調用hideSkeleton,一樣進行遍歷,移除skeletonLayer。git
簡單的說,在顯示佔位的時候,將tableView的代理設置爲經過某個對象,這個對象根據cell的Idenfier建立cell並添加佔位顯示。關閉顯示佔位的時候,將代理tableView的代理切回ViewController,正常顯示。github
一樣是擴展UIView,添加屬性somoContainer,表示佔位視圖的容器視圖,其中每一個佔位區域都是一個SomoView。對於想要顯示佔位效果的View,需實現協議,在協議方法中返回SomoView列表。將這些SomoView添加到somoContainer,並顯示。web
除此以外,TABAnimated也是一個被使用的比較多的,一樣TABAnimated也是擴展的UIView。在ios中集成TABAnimated須要經歷如下幾步:bash
pod search TABAnimated
複製代碼
能夠選擇在appDelegate的didFinishLaunchingWithOptions方法全局設置動畫屬性,設有默認屬性。例如:app
// 設置TABAnimated相關屬性
[[TABViewAnimated sharedAnimated]initWithAnimatedDuration:0.3 withColor:tab_kBackColor];
複製代碼
在須要動畫的view上,將屬性animatedStyle設置爲TABTableViewAnimationStart,不須要動畫的view不用作額外的操做。框架
// 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;
}
複製代碼
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];
}
複製代碼
在獲取到數據後,中止動畫。
//中止動畫,並刷新數據
_mainTV.animatedStyle = TABTableViewAnimationEnd;
[_mainTV reloadData];
_headView.animatedStyle = TABViewAnimationEnd;
[_headView initWithData:headGame];
複製代碼
示例源碼連接:iOS骨架屏示例
在Android中,骨架屏的實現也後不少的第三方框架,常見的有如下幾個庫:
ShimmerRecyclerView是一個帶有閃光和指示效果的庫,其運行效果以下圖:
Skeleton也是一個使用得比較普遍的庫,它如今使用閃存動畫的內存優化版本,所以速度更快,您也能夠設置更大的佈局動畫。
Spruce 是一個輕量級動畫庫,可幫助編排屏幕上的動畫,該庫同時還支持 iOS。
在前端中,經過 puppeteer 在服務端操控 headless Chrome 打開開發中的須要生成骨架屏的頁面,在等待頁面加載渲染完成以後,在保留頁面佈局樣式的前提下,經過對頁面中元素進行刪減或增添,對已有元素經過層疊樣式進行覆蓋,這樣達到在不改變頁面佈局下,隱藏圖片和文字,經過樣式覆蓋,使得其展現爲灰色塊。而後將修改後的 HTML 和 CSS 樣式提取出來,這樣就實現了骨架屏。
前端的骨架屏實現和優化,建議讀者閱讀如下連接文章: