美文网首页
仿简书搜索框自定义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