Android-自定义宿主管理状态栏
本文最后更新于 677 天前

自定义状态栏View对象

/**
 * 自定义状态栏的View,用于StatusBarHostLayout中使用
 */
class StatusView extends View {

    private int mBarSize;

    public StatusView(Context context) {
        this(context, null, 0);
    }

    public StatusView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        mBarSize = StatusBarHostUtils.getStatusBarHeight(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mBarSize);
    }

    //获取到当前的状态栏高度
    public int getStatusBarHeight() {
        return mBarSize;
    }
}

核心的宿主代替类

/**
 * 宿主的布局
 */
@SuppressLint("ViewConstructor")
public class StatusBarHostLayout extends LinearLayout {

    private Activity mActivity;
    private StatusView mStatusView;
    private FrameLayout mContentLayout;

    StatusBarHostLayout(Activity activity) {
        super(activity);

        this.mActivity = activity;

        //加载自定义的宿主布局
        if (mStatusView == null && mContentLayout == null) {
            setOrientation(LinearLayout.VERTICAL);

            mStatusView = new StatusView(mActivity);
            mStatusView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            addView(mStatusView);

            mContentLayout = new FrameLayout(mActivity);
            mContentLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1.0f));
            addView(mContentLayout);
        }

        //替换宿主的contentView为外界设置的View
        replaceContentView();

        //设置原生的状态栏沉浸式,使用自定义的状态栏布局
        StatusBarHostUtils.immersiveStatusBar(mActivity);
        StatusBarHostUtils.setStatusBarColor(mActivity, Color.TRANSPARENT);
    }

    private void replaceContentView() {
        Window window = mActivity.getWindow();
        ViewGroup contentLayout = window.getDecorView().findViewById(Window.ID_ANDROID_CONTENT);
        if (contentLayout.getChildCount() > 0) {
            //先找到DecorView的容器移除掉已经设置的ContentView
            View contentView = contentLayout.getChildAt(0);
            contentLayout.removeView(contentView);
            ViewGroup.LayoutParams contentParams = contentView.getLayoutParams();

            //外部设置的ContentView添加到宿主中来
            mContentLayout.addView(contentView, contentParams.width, contentParams.height);
        }
        //再把整个宿主添加到Activity对应的DecorView中去
        contentLayout.addView(this, -1, -1);
    }


    /**
     * 设置状态栏文本颜色为黑色
     */
    public StatusBarHostLayout setStatusBarBlackText() {
        StatusBarHostUtils.setStatusBarDarkFont(mActivity, true);
        return this;
    }

    /**
     * 设置状态栏文本颜色为白色
     */
    public StatusBarHostLayout setStatusBarWhiteText() {
        StatusBarHostUtils.setStatusBarDarkFont(mActivity, false);
        return this;
    }

    /**
     * 设置自定义状态栏布局的背景颜色
     */
    public StatusBarHostLayout setStatusBarBackground(int color) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            mStatusView.setBackgroundColor(color);
        } else {
            //6.0以下不能白色状态栏
            YYLogUtils.w("当前的状态颜色1:" + color);
            if (color == Color.WHITE) {
                color = Color.parseColor("#B0B0B0");
            }

            mStatusView.setBackgroundColor(color);
        }

        return this;
    }

    /**
     * 设置自定义状态栏布局的背景图片
     */
    public StatusBarHostLayout setStatusBarBackground(Drawable drawable) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mStatusView.setBackground(drawable);
        } else {
            mStatusView.setBackgroundDrawable(drawable);
        }
        return this;
    }

    /**
     * 设置自定义状态栏布局的透明度
     */
    public StatusBarHostLayout setStatusBarBackgroundAlpha(int alpha) {
        Drawable background = mStatusView.getBackground();
        if (background != null) {
            background.mutate().setAlpha(alpha);
        }
        return this;
    }

    /**
     * 给指定的布局适配状态栏高度,设置paddingTop
     */
    public StatusBarHostLayout setViewFitsStatusBarView(View view) {

        //设置MaginTop的方式
        if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {

            //已经添加过了不要再次设置
            if (view.getTag() != null && view.getTag().equals("fitStatusBar")) {
                return this;
            }

            ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();
            int marginTop = layoutParams.topMargin;
            int setMarginTop = marginTop + mStatusView.getStatusBarHeight();
            view.setTag("fitStatusBar");
            layoutParams.topMargin = setMarginTop;
            view.requestLayout();
        }

        return this;
    }


    /**
     * 设置自定义状态栏的沉浸式
     */
    public StatusBarHostLayout setStatusBarImmersive(boolean needImmersive) {
        layoutimmersive(needImmersive);
        return this;
    }

    //具体的沉浸式逻辑
    private void layoutimmersive(boolean needImmersive) {

        if (needImmersive) {
            mStatusView.setVisibility(GONE);
        } else {
            mStatusView.setVisibility(VISIBLE);
            mStatusView.setBackgroundColor(ContextCompat.getColor(mActivity, R.color.colorPrimary));
        }

    }

}

状态栏设置入口

/**
 * 宿主替换布局的方式管理状态栏与内容的布局
 */
public class StatusBarHost {

    private StatusBarHost() {
    }

    public static StatusBarHostLayout inject(Activity activity) {
        Window window = activity.getWindow();
        ViewGroup contentLayout = window.getDecorView().findViewById(Window.ID_ANDROID_CONTENT);
        if (contentLayout.getChildCount() > 0) {
            View contentView = contentLayout.getChildAt(0);
            //如果当前是宿主的包装类,直接强转
            if (contentView instanceof StatusBarHostLayout) {
                return (StatusBarHostLayout) contentView;
            }
        }
        //如果不是我们封装一个宿主包装类
        return new StatusBarHostLayout(activity);
    }
}

使用

 val hostLayout = StatusBarHost.inject(this)
            .setStatusBarBackground(color(R.color.white))
            .setStatusBarBlackText()

 hostLayout.setStatusBarBackground(Color.RED)

 hostLayout.setStatusBarBackground(getDrawable(R.drawable.statusbar_image_1))

 hostLayout.setStatusBarImmersive(true)
iichen:https://iichen.cn/?p=354
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇