前言:公司的一個(gè)產(chǎn)品需求,需要將列表的最后可見(jiàn)的一項(xiàng)做透明度以及縮放處理漱牵,并且在滑動(dòng)時(shí)夺蛇,最后可見(jiàn)的一項(xiàng)可以淡入淡出的顯示在列表中。效果如圖~
實(shí)現(xiàn):
調(diào)研:起初的設(shè)計(jì)方案是使用開源項(xiàng)目:RecyclerView Animators https://github.com/wasabeef/recyclerview-animators
但是過(guò)不了UI那關(guān)酣胀,于是便只能想辦法實(shí)現(xiàn)滑動(dòng)監(jiān)聽時(shí)刁赦,做一系列的效果了~
設(shè)計(jì)分析:
已經(jīng)確定了要實(shí)現(xiàn)RecyclerView滑動(dòng)監(jiān)聽,必然就得了解RecyclerView滑動(dòng)監(jiān)聽實(shí)現(xiàn)的方法:
1.onScrollStateChanged //滑動(dòng)狀態(tài)的改變
2.onScrolled //滑動(dòng)時(shí)回調(diào)該方法
這里不需要第一個(gè)方法灵临,因此我們就重寫onScrolled方法:
1.找到列表中最后一項(xiàng)可見(jiàn)的view
2.根據(jù)可見(jiàn)部分占view總部分的占比,計(jì)算出透明度以及縮放比例截型。
代碼實(shí)現(xiàn):
private void calculateAlphaAndScale(RecyclerView recyclerView, LinearLayoutManager layoutManager) {
//找出列表中可見(jiàn)的最后一項(xiàng)索引趴荸。
int firstItemPosition = layoutManager.findFirstVisibleItemPosition();
int lastItemPosition = layoutManager.findLastVisibleItemPosition();
//根據(jù)索引找到view
View lastView = layoutManager.getChildAt(lastItemPosition - firstItemPosition);
if (lastView != null) {
//當(dāng)找到最后一項(xiàng)的view時(shí),根據(jù)可見(jiàn)部分占view總部分的占比,計(jì)算出透明度以及縮放比例儒溉。
int itemHeight = lastView.getHeight();
int visibleHeight = recyclerView.getHeight() - lastView.getTop();
if (visibleHeight < 0) {
return;
}
float ratio = visibleHeight * 1.0f / itemHeight;
if (ratio > 1.0) {
return;
}
lastView.setAlpha(ratio);
float scale = 0.8f;//默認(rèn)最小的縮放比例
float scaleFactor = scale + (1 - scale) * ratio;
lastView.setScaleX(scaleFactor);
lastView.setScaleY(scaleFactor);
}
}
最重要的動(dòng)畫部分已經(jīng)實(shí)現(xiàn),但是還存在一些問(wèn)題发钝,實(shí)際項(xiàng)目中的還有tab切換顿涣,導(dǎo)致的列表刷新(由于時(shí)間緊迫,并沒(méi)有采取ViewPager+Indicator的方式)時(shí)酝豪,已經(jīng)做縮放和透明度的View沒(méi)有還原涛碑。因此:
在每次做動(dòng)效前,先遍歷列表view孵淘,初始化一下狀態(tài)蒲障。
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
int childCount = layoutManager.getChildCount();
//對(duì)每個(gè)item進(jìn)行初始化
for (int i = 0; i < childCount; i++) {
layoutManager.getChildAt(i).setAlpha(1);
layoutManager.getChildAt(i).setScaleY(1);
layoutManager.getChildAt(i).setScaleX(1);
}
calculateAlphaAndScale(recyclerView, layoutManager);
}
這樣,全部的動(dòng)效就已經(jīng)完畢了瘫证,跑在手機(jī)上的效果就如前面的gif圖~