美文网首页
仿简书搜索框自定义view

仿简书搜索框自定义view

作者: __hgb | 来源:发表于2018-03-11 13:59 被阅读0次
ezgif-2-4d820a47d1.gif

效果

这里可以拆出两个独立的效果
1.recycleview从顶端滑到头部图片底部时,标题栏颜色逐渐从透明转向白色。
recycleview从头部图片底部滑到顶端时,标题栏颜色逐渐从白色转向透明。

2.recycleview滑到顶端时,搜索框做缩进动画。
recycleview滑到头部图片底部时,搜索框做收缩动画。

改变标题栏透明度分为三个步骤

1.在这里监听recycleview的滑动。
2.透明度变化百分比=recycleview滑动的高度/(头部图片的高度-标题栏的高度)
3.再把透明度设置给头部背景图片

监听recycleview的滑动
rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                计算百分比
                float fraction = calcFraction(dy);
                设置透明度
                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){
        //背景只需要设置透明度,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中调用了invalidate()去触发onDraw(Canvas canvas)让View发生重绘。

 mCircleIn.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentInCircleWidth= (float) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });

这里用枚举定义了searchview的三种状态,并在onDraw()方法中根据当前状态来绘制出对应的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;
        }
    }

具体源码链接

相关文章

网友评论

      本文标题:仿简书搜索框自定义view

      本文链接:https://www.haomeiwen.com/subject/xiiifftx.html