ezgif-2-4d820a47d1.gif
效果
這里可以拆出兩個獨立的效果
1.recycleview從頂端滑到頭部圖片底部時宛蚓,標題欄顏色逐漸從透明轉(zhuǎn)向白色勾拉。
recycleview從頭部圖片底部滑到頂端時,標題欄顏色逐漸從白色轉(zhuǎn)向透明猎醇。
2.recycleview滑到頂端時顺饮,搜索框做縮進動畫。
recycleview滑到頭部圖片底部時劲装,搜索框做收縮動畫胧沫。
改變標題欄透明度分為三個步驟
1.在這里監(jiān)聽recycleview的滑動。
2.透明度變化百分比=recycleview滑動的高度/(頭部圖片的高度-標題欄的高度)
3.再把透明度設(shè)置給頭部背景圖片
監(jiān)聽recycleview的滑動
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
計算百分比
float fraction = calcFraction(dy);
設(shè)置透明度
setBackgoundAlpha(fraction);
}
});
private float calcFraction(int dy){
float imgHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, getResources().getDisplayMetrics());
float toolbarHeight = rlHead.getHeight();
float maxHeight = imgHeight - toolbarHeight;
scrollY += dy;
if(scrollY>maxHeight){
mSearchView.startAnimation(SearchView.SCROLL_HEAD_BOTTOM);
}
if(scrollY==0){
mSearchView.startAnimation(SearchView.SCROLL_HEAD_TOP);
}
if (scrollY >= maxHeight) {
return 1.0f;
} else if (scrollY <= 0) {
return 0f;
} else {
return scrollY/maxHeight;
}
}
private void setBackgoundAlpha(float fraction){
//背景只需要設(shè)置透明度酱畅,255是全不透明
headBg.setAlpha((int) (fraction*255));
}
搜索框縮進彈出動畫
當recycleview滑動的垂直方向上的距離大于頭部圖片高度減去標題欄琳袄,searchview做彈出動畫江场。當recycleview滑動到頂部時纺酸,searchview做收縮動畫
if(scrollY>maxHeight){
mSearchView.startAnimation(SearchView.SCROLL_HEAD_BOTTOM);
}
if(scrollY==0){
mSearchView.startAnimation(SearchView.SCROLL_HEAD_TOP);
}
public void startAnimation(int state){
if(state==SCROLL_HEAD_TOP){
if(searchViewState==SearchViewState.OUT){
searchViewState=SearchViewState.IN;
startAnimationIn();
}
}else{
if(state==SCROLL_HEAD_BOTTOM){
if(searchViewState==SearchViewState.INIT||searchViewState==SearchViewState.IN){
searchViewState=SearchViewState.OUT;
startAnimationOut();
}
}
}
}
在每個ValueAnimator中調(diào)用了invalidate()去觸發(fā)onDraw(Canvas canvas)讓View發(fā)生重繪。
mCircleIn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
currentInCircleWidth= (float) valueAnimator.getAnimatedValue();
invalidate();
}
});
這里用枚舉定義了searchview的三種狀態(tài)址否,并在onDraw()方法中根據(jù)當前狀態(tài)來繪制出對應(yīng)的seachview
private enum SearchViewState
{
INIT,OUT,IN;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
switch (searchViewState)
{
case INIT:
drawInit(canvas);
break;
case OUT:
drawOutAnimation(canvas);
break;
case IN:
drawInAnimation(canvas);
break;
}
}