Android App的标题栏随ScrollView的滑动改变透明度

记录一下前一段时间做项目遇到的标题栏透明度随ScrollView的滚动变化问题的解决问题

描述:前几天项目里面有一个需求,就是根据ScrollView的滚动来设置标题栏的透明度,于是我就监听scrollView的setOnScrollChangeListener方法完成了,本来做好项目后没任何问题,但是回家后用一个4.4的手机测试发现奔了,打印后发现是由于ScrollView的setOnScrollChangeListener监听在Api23以上才可以使用,所以才导致的奔溃,解决办法很简单,就是自己写一个类MyScrollView,继承自ScrollView,在MyScrollView类里面重写onScrollChanged方法 即可实现,下面附上代码:

一、先实现类MyScrollView

public class MyScrollView extends ScrollView {
    private OnScrollChangeListener scrollChangeListener = null;
    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if (scrollChangeListener != null) {
            scrollChangeListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }
    public void setScrollViewListener(OnScrollChangeListener onScrollChangeListener) {
        this.scrollChangeListener = onScrollChangeListener;
    }

    public interface OnScrollChangeListener {
        void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy);
    }
 }

二、使用

在xml引用MyScrollView,然后在Activity里面通过findViewById()找到MyScrollView 调用setScrollViewListener方法

scrollView.setScrollViewListener(new MyOnScrollChangeListener());
/**
     * ScrollVoiew滑动监听
     */
    private class MyOnScrollChangeListener implements MyScrollView.OnScrollChangeListener {


        @Override
        public void onScrollChanged(MyScrollView, int x, int y, int oldx, int oldy) {
            //根据scrollview滑动更改标题栏透明度
            changeAphlaTitle(oldy, y);
        }
    }
    /**
     * 根据内容窗体的移动改变标题栏背景透明度
     *
     * @param startY scrollview开始滑动的y坐标(相对值)
     * @param endY   scrollview结束滑动的y坐标(相对值)
     */
    private void changeAphlaTitle(int startY, int endY) {
        //获取到状态栏的高度
        int statusBarHeight = getStatusBarHeight(mActivity);
        //获取标题高度
        int titleHeight = llTop.getLayoutParams().height;
        //获取背景高度
        int backHeight = DisplayUtil.dp2px(mActivity, 250);

        //获取控件的绝对位置坐标
        int[] location = new int[2];
        rlBgUnit.getLocationInWindow(location);
        //从屏幕顶部到控件顶部的坐标位置Y
        int currentY = location[1];
        //表示回到原位(滑动到顶部)
        if (currentY >= statusBarHeight) {
            llTop.setBackgroundColor(Color.argb(0, 0, 0, 0));
        }
        //顶部条目移除或移入屏幕的过程中;颜色透明度改变
        if (currentY < statusBarHeight && currentY >= -backHeight) {
            //计算出滚动过程中改变的透明值
            double changeValue = ((double) Math.abs(currentY) / (statusBarHeight + backHeight)) * 77;
            //判断是向上还是向下
            if (endY > startY) {//向上;透明度值增加,实际透明度减小
                llTop.setBackgroundColor(Color.argb((int) changeValue, 0, 0, 0));
            } else if (endY < startY) {//向下;透明度值减小,实际透明度增加
                llTop.setBackgroundColor(Color.argb((int) changeValue, 0, 0, 0));
            }
        }
        //顶部条目移除屏幕
        if (currentY < -backHeight) {
            llTop.setBackgroundColor(Color.argb(77, 0, 0, 0));
        }
    }

    /**
     * 获取通知栏高度
     *
     * @param context 上下文
     * @return 通知栏高度
     */
    private int getStatusBarHeight(Context context) {
        Class<?> c = null;
        Object obj = null;
        Field field = null;
        int x = 0, statusBarHeight = 0;
        try {
            c = Class.forName("com.android.internal.R$dimen");
            obj = c.newInstance();
            field = c.getField("status_bar_height");
            x = Integer.parseInt(field.get(obj).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(x);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return statusBarHeight;
    }
/**
     * 将dip或dp值转换为px值,保证尺寸大小不变
     *
     * @param dipValue (DisplayMetrics类中属性density)
     * @return
     */
    public static int dp2px(Context context, float dipValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dipValue * scale + 0.5f);
    }

猜你喜欢

转载自blog.csdn.net/huahuaxiaolian/article/details/71751795