Android 三步简单适配齐刘海系统状态栏

个人思路:

说到齐刘海适配,最典型的就是MainActivity的几个fragment有的需要透明系统状态栏 有的不需要, 而一般需要透明系统状态栏的fragment顶部都会放个轮播图,然后在轮播图上放搜索框,所谓适配,就是指搜索框的位置根据系统状态栏高度设置,达到在齐刘海手机上搜索框不被覆盖;
在这里插入图片描述
如上图所示,下面对如动态图所示系统状态栏进行三步分析

一、获取系统状态栏高度

两行代码就能获取当前系统状态栏的高度

      int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
      int viewHeight = mContext.getResources().getDimensionPixelSize(resourceId);

二、设置颜色

根据UI的需求,我的做法是先设置系统状态栏透明,监听手势动作,开始滑动时,增加一个系统状态栏同高的view,更改背景色渐变(渐变值为0-100%,百分比同 滑动距离/轮播图高度),更改系统状态栏图标颜色为深色,再重写scrollview,监听滑动置顶时,设置透明系统状态栏,隐藏占位view

/**
 * 设置透明系统状态栏
 */
View decorView = getActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getActivity().getWindow().setStatusBarColor(Color.parseColor("#00000000"));//设置透明
/**
 * 设置系统状态栏图标颜色,用false和true 设置颜色为白色或者深色
 */
 StatusBarCompat.setLightStatusBar(getActivity().getWindow(), false);
/**
 * 滑动监听
 */
 private MyScrollView.OnMyScrollListener listener;

 listener = new MyScrollView.OnMyScrollListener() {
                @Override
                public void onScrollStateChanged(MyScrollView view, int state) {
                    String str;
                    if (state == 0) {
                        str = "IDLE";
                    } else if (state == 1) {
                        str = "DRAG";
                    } else if (state == 2) {
                        str = "FLING";
                    } else {
                        str = "ERROR";
                    }
                    Log.d("brycegao", "滑动状态:" + str);
                }

                @Override
                public void onScroll(MyScrollView view, int y) {
                    int height = banner.getHeight();
                    if (scroll_view.getScrollY() > 0) {
                        if (scroll_view.getScrollY() < height) {
                            float scale = (float) scroll_view.getScrollY() / height;
                            float alpha = (255 * scale);
                            //百分比渐变
                            view_placeholder.setBackgroundColor(Color.argb((int) alpha, 0xff, 0xff, 0xff));
                            //获取系统状态栏高度
                            int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
                            //获取屏幕宽度
                            int viewWidth = (int) (ScreenUtils.getScreenWidth(mContext));
                            if (resourceId > 0) {
                                int viewHeight = mContext.getResources().getDimensionPixelSize(resourceId);
                                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(viewWidth, viewHeight);
                                view_placeholder.setLayoutParams(params);
                            }
                            StatusBarCompat.setLightStatusBar(getActivity().getWindow(), true);//设置导航栏字体颜色
                        }
                    }

                }

                @Override
                public void onScrollToTop() {
                    Log.d("brycegao", "滑到顶部");
                    view_placeholder.setLayoutParams(new RelativeLayout.LayoutParams(0, 0));
                    StatusBarCompat.setLightStatusBar(getActivity().getWindow(), false);//设置导航栏字体颜色
                }

                @Override
                public void onScrollToBottom() {
                    Log.d("brycegao", "滑动底部");
                }
            };
/**
 * 自定义scrollview 监听滑动事件,网上找的,亲测可用,不过原文地址忘了 勿怪、见谅
 */
public class MyScrollView extends ScrollView {

    private ArrayList<OnMyScrollListener> listeners;

    private int currentState;
    private boolean isLastBottom;  //上次刷新是否底部
    private int lastDrawPos;     //上次刷新的纵向位移

    public interface OnMyScrollListener {
        int SCROLL_STATE_FLING = 2;   //手指滑动后松开,自动滑动
        int SCROLL_STATE_IDLE = 0;   //不滑动
        int SCROLL_STATE_TOUCH_SCROLL = 1;   //手指按着屏幕滑动

        void onScrollStateChanged(MyScrollView view, int state);

        void onScroll(MyScrollView view, int y); //滑动距离

        void onScrollToTop();   //滑到顶部

        void onScrollToBottom(); //滑到底部
    }

    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        listeners = new ArrayList<>();
    }

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

    @Override public boolean onTouchEvent(MotionEvent ev) {
        boolean lastDragState = getDragState();

        boolean ret = super.onTouchEvent(ev);
        if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
            for (OnMyScrollListener listener:listeners) {
                listener.onScroll(this, getScrollY());
            }
        }

        if ((ev.getActionMasked() == MotionEvent.ACTION_UP
                || ev.getActionMasked() == MotionEvent.ACTION_CANCEL)
                && currentState == OnMyScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
            //取消滑动
            currentState = OnMyScrollListener.SCROLL_STATE_IDLE;
            for (OnMyScrollListener listener:listeners) {
                listener.onScrollStateChanged(this, OnMyScrollListener.SCROLL_STATE_IDLE);
            }

        }
        boolean curDragState = getDragState();

        //拖动
        if (!lastDragState && curDragState) {
            currentState = OnMyScrollListener.SCROLL_STATE_TOUCH_SCROLL;
            for (OnMyScrollListener listener:listeners) {
                listener.onScrollStateChanged(this, OnMyScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            }
        }
        return ret;
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (lastDrawPos == getScrollY()
                && getScrollY() > 0
                && currentState == OnMyScrollListener.SCROLL_STATE_FLING ) {
            currentState = OnMyScrollListener.SCROLL_STATE_IDLE;  //设置状态为空闲
            for (OnMyScrollListener listener:listeners) {
                listener.onScrollStateChanged(this, OnMyScrollListener.SCROLL_STATE_IDLE);
            }
        }

        if (getScrollY() == 0 && lastDrawPos == 0
                && currentState != OnMyScrollListener.SCROLL_STATE_IDLE) {
            currentState = OnMyScrollListener.SCROLL_STATE_IDLE;  //设置状态为空闲
            for (OnMyScrollListener listener:listeners) {
                listener.onScrollStateChanged(this, OnMyScrollListener.SCROLL_STATE_IDLE);
                listener.onScrollToTop();
            }
        }

        lastDrawPos = getScrollY();

        if (isCurrentBottom()
                && !isLastBottom) {
            for (OnMyScrollListener listener:listeners) {
                listener.onScrollToBottom();
            }
        }
        isLastBottom = isCurrentBottom();
    }

    @Override public void fling(int velocityY) {
        super.fling(velocityY);

        if (getChildCount() > 0) {
            currentState = OnMyScrollListener.SCROLL_STATE_FLING;
            for (OnMyScrollListener listener:listeners) {
                listener.onScrollStateChanged(this, OnMyScrollListener.SCROLL_STATE_FLING);
            }
        }
    }

    //判断是否滑到底部
    private boolean isCurrentBottom() {
        boolean ret = false;

        int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
        int heightPadding;  //scrollview上下padding之和
        View child = getChildAt(0);
        final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
        if (targetSdkVersion >= Build.VERSION_CODES.M) {
            heightPadding = getPaddingTop() + getPaddingBottom() + lp.topMargin + lp.bottomMargin;
        } else {
            heightPadding = getPaddingTop() + getPaddingBottom();
        }

        if (getMeasuredHeight() - heightPadding + getScrollY() == child.getMeasuredHeight()) {
            ret = true;
        }
        return ret;
    }

    //反射查询mIsBeingDragged
    private boolean getDragState() {
        boolean state = false;
        try {
            Class clz = ScrollView.class;
            Field field = clz.getDeclaredField("mIsBeingDragged");
            field.setAccessible(true);
            state = field.getBoolean(this);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return state;
    }

    //滑动加速器是否停止
    private boolean isfinishScroll() {
        boolean isfinish=false;
        Class scrollview=ScrollView.class;
        try {
            Field scrollField=scrollview.getDeclaredField("mScroller");
            scrollField.setAccessible(true);
            Object scroller=scrollField.get(this);
            Class overscroller= scrollField.getType();
            Method finishField=overscroller.getMethod("isFinished");
            finishField.setAccessible(true);
            isfinish= (boolean) finishField.invoke(scroller);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {

        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return isfinish;
    }

    /**
     * 添加滑动监听
     * @param listener
     */
    public void addOnScrollListner(OnMyScrollListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("invalid listener");
        }

        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }

    public void removeOnScrollListener(OnMyScrollListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("invalid listener");
        }

        listeners.remove(listener);
    }
}

三、UI适配

其实这个UI适配也很简单的,就是设置搜索框的paddingTop为系统状态栏的高度+xdp,这里就不写代码了

以上就是本人对齐刘海适配的思路,欢迎指正,共同学习,共勉

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值