Toolbar(或自定义布局)随滑动控件(ListView,ScrollView,RecylerView)改变透明度

1.效果如下:
这里写图片描述

2.分别实现ScrollView和ListView以及RecylerView对应时候的透明度

1.首先我们来分析ScrollView如何来实现思路:

   其实我们知道是改变Toolbar(自定义的布局)透明度,而且是更具滑动控件滑动的距离,所以问题
   来了透明度是0-1,我们猜想可以获取滑动的高度,如何将滑动高度和透明度联系在一起呢?我们
   可以设置根据屏幕高度和滑动的高度直接进行计算例如:
   这里我我将屏幕的三分之一作为基数:只要屏幕滑动大于等于屏幕的三分之一那么就透明了。
   if(scrollY<(screenHeight/3f)){ aphal=scrollY/(screenHeight/3f)}: 
   0<aphal<1

2.我们如何获取滑动的高度呢?
我们去看看ScrollView的源码发现:

protected void onScrollChanged(int l, int t, int oldl, int oldt)
然后在ScrollView重绘时候会不断调用赋值scrollY的。所以我们可以通过scrollView.getScrollY();
来获取高度

3.上代码:
1。你可以重写ScrollView也可以通过实例化后的ScrollView来通过内部类进行设置:
例如:

 mScr.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                //如何选择那种方式,你看着那个顺眼就来
            int scrollY=mScr.getScrollY();//花出去的高度
            int heightPixels=getResources().getDisplayMetrics().heightPixels;//屏幕高度
            if(scrollY<=heightPixels/3) {
               tranSlate(1-scrollY/(heightPixels/3f));//alpha=滑出去的高度/(screen_height/3f);
            }
            }
        });

或者

public class MyScrollView extends ScrollView {
    public interface TranslucentListener {
        /**
         * 透明度的回调
         *
         * @param alpha 0-1的透明度
         */
        void TranslucentTobar(float alpha);
    }
    private TranslucentListener mTranslucentLisenner;
    public void setTransluListenner(TranslucentListener mTranslucentLisenner){
        this.mTranslucentLisenner=mTranslucentLisenner;
    }
    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if(mTranslucentLisenner!=null){
            int scrollY=getScrollY();//花出去的高度
            int heightPixels=getContext().getResources().getDisplayMetrics().heightPixels;//屏幕高度
            if(scrollY<=heightPixels/3) {
                mTranslucentLisenner.TranslucentTobar(1-scrollY/(heightPixels/3f));//alpha=滑出去的高度/(screen_height/3f);
            }
        }
    }
}

4.贴出github地址如下:
https://github.com/luhenchang/Lsn11_MeterialDesign_TranslucentScrollToolbar.git

3.ListView分析如下:
1.listView同样我们是否可以拿到scrollY。如果拿到那么我们就很简单了。
当然了,你自己测试会发现这里是拿不到的,永远是0,因为在每次从新绘制时候我们
并没有发现获取scrollY的值,所以这里我们如何获取滑动的高度呢?
忽略计算假如每一个item的高度是固定的。那么我们可以获取滑动的高度
scrollY=滑动出去界面的item的个数*(乘以)每个itemHeight+最上面可视且正要滑出去
的高度。
那么我们需要获取滑出去的个数和滑动的一个的高度。
这里getChildAt(0);这里很多人都知道这个代码但是了没说清楚,当你的界面没有画出去
时候getChildAt(0).getTop();一直是增加的,当你的第一个Item滑出去那么就进入了
复用,这时候getChildAt(0).getTop();是你复用的item里面第一个item的最上边到屏幕
最上面的距离(有整负)

getFirstVisiblePosition();表示第一个可以看见的item的position这样我们就知道了
上面有几个item了。

 @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mTransliener != null) {
            int scrollY;
            //这里getChildAt(0);这里很多人都知道这个代码但是了没说清楚,当你的界面没有画出去
            //时候getChildAt(0).getTop();一直是增加的,当你的第一个Item滑出去那么就进入了
            //复用,这时候getChildAt(0).getTop();是你复用的item里面第一个item的最上边到屏幕
            //最上面的距离(有整负)
            View c =getChildAt(0);

            if (c == null)
            {
                scrollY=0;

            }
            //getFirstVisiblePosition();表示第一个可以看见的item的position这样我们就知道了
            //上面有几个item了。
            int firstVisiblePosition =getFirstVisiblePosition();
            int top = c.getTop();
            Log.e("topY",top+"");
            Log.e("firstVisibaleTop",firstVisiblePosition * c.getHeight()+"");
            Log.e("getChilder",getChildCount()+"");
            //这里scrollY=滑动的一个item的高度+滑出去的所有的高度和。
            scrollY=-top + firstVisiblePosition * c.getHeight() ;
            int screenHeight = getContext().getResources().getDisplayMetrics().heightPixels;
            if (scrollY <= screenHeight / 3f) {
                mTransliener.transListenner(1 - scrollY / (screenHeight / 3f));
            }
        }
    }

github地址:https://github.com/luhenchang/Lsn11_MeterialDesign_TranslucentScrollToolbar.git

4.RecylerView分析如下:
RecylerView我试过是没有getFirstVisiblePosition()因为我们知道RecylerView有横向的也有纵
向的,主要是有LayoutManage决定的。所以我们这里去看LayoutMananger之后发现我去,竟
然在这里findFirstVisibleItemPosition。

     recyclerView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                Log.e("scrollY",scrollY+"");
                int scrollYs=0;
                View view=recyclerView.getChildAt(0);

                if(view==null){
                    scrollYs=0;
                }

                scrollYs=-view.getTop()+((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition()*view.getHeight();
                int screenHeight=getResources().getDisplayMetrics().heightPixels;
                if(scrollYs<screenHeight/3f){

                    transListenner(1-scrollYs/(screenHeight/3f));

                }
            }
        });

gitHub地址里面的RecylerViewTranslate页面内:
https://github.com/luhenchang/Lsn11_MeterialDesign_TranslucentScrollToolbar.git

发布了47 篇原创文章 · 获赞 54 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/m0_37667770/article/details/79566735