使用StatusBarUtil 來實(shí)現(xiàn)沉浸式

文章參考StatusBarUtil 狀態(tài)欄工具類(實(shí)現(xiàn)沉浸式狀態(tài)欄/變色狀態(tài)欄)

StatusBaStatusBarUtil 狀態(tài)欄工具類(實(shí)現(xiàn)沉浸式狀態(tài)欄/變色狀態(tài)欄)
這是一個(gè)為Android App 設(shè)置狀態(tài)欄的工具類, 可以在4.4及其以上系統(tǒng)中實(shí)現(xiàn) 沉浸式狀態(tài)欄/狀態(tài)欄變色,支持設(shè)置狀態(tài)欄透明度
項(xiàng)目 GitHub 地址
Sample 下載
下載 StatusBarUtil-Demo(APK)

  • 設(shè)置狀態(tài)欄顏色
    StatusBarUtil.setColor(Activity activity, int color)

  • 設(shè)置狀態(tài)欄半透明
    StatusBarUtil.setTranslucent(Activity activity, int statusBarAlpha)

    ? ?

  • 設(shè)置狀態(tài)欄全透明
    StatusBarUtil.setTransparent(Activity activity)

  • 包含 DrawerLayout的界面設(shè)置狀態(tài)欄顏色(也可以設(shè)置半透明和全透明)
    StatusBarUtil.setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, int color)

  • 使用 ImageView 作為頭部的界面設(shè)置狀態(tài)欄透明
    StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View needOffsetView)

  • 在 Fragment 中使用 ImageView 作為頭部的界面的時(shí)候


當(dāng)一個(gè)Activity界面下有4個(gè)同級的Fragment的時(shí)候,首頁的Fragment頂部是圖片的時(shí)候,設(shè)置了透明狀態(tài)欄之后就會(huì)造成其他界面的標(biāo)題頂?shù)綘顟B(tài)欄中,這個(gè)時(shí)候只需要設(shè)置一下標(biāo)題布局在父控件的LayoutParams,LayoutParams 是 子控件 用來告訴 父控件 自己要如何布局時(shí)用的,也就是說設(shè)置一下頂部控件的marginTop為狀態(tài)欄的高度就可以了

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater!!.inflate(R.layout.fragment_me, container, false)
        val tvMePress = view.findViewById<TextView>(R.id.tvMePress)
        val layoutParams = tvMePress.layoutParams as LinearLayout.LayoutParams
        layoutParams.topMargin = StatusBarUtil.getStatusBarHeight(context)
        return view
    }

參考從LayoutParams說起到代碼動(dòng)態(tài)布局

通過傳入 statusBarAlpha 參數(shù),可以改變狀態(tài)欄的透明度值,默認(rèn)值是112。

使用在 build.gradle 文件中添加依賴, StatusBarUtil 已經(jīng)發(fā)布在 JCenter:
compile 'com.jaeger.statusbarutil:library:1.4.0'

在 setContentView()
之后調(diào)用你需要的方法,例如:

setContentView(R.layout.main_activity);
...
StatusBarUtil.setColor(MainActivity.this, mColor);
  • 如果你在一個(gè)包含 DrawerLayout
    的界面中使用, 你需要在布局文件中為 DrawerLayout添加
    android:fitsSystemWindows="true"
    屬性:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
        ...
    </android.support.v4.widget.DrawerLayout>
  • 當(dāng)你設(shè)置了 statusBarAlpha值時(shí),該值需要在 0 ~ 255 之間

為了更好的根據(jù)自己需求更改所以直接將工具類拷貝到自己項(xiàng)目中就可以

  • 在app的build.gradle中dependencies節(jié)點(diǎn)下加入
    compile 'com.android.support:design:26.1.0'
  • 在res中的values目錄下創(chuàng)建values.xml,內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="statusbarutil_fake_status_bar_view" type="id"/>
    <item name="statusbarutil_translucent_view" type="id"/>
</resources>
  • 在項(xiàng)目下創(chuàng)建util文件夾,并拷貝StatusBarUtil.class
package 包名.util;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.widget.DrawerLayout;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;


/**
 * @author GitHub: https://github.com/laobie
 */
public class StatusBarUtil {
    public static final String TAG = "StatusBarUtil";
    private static final int DEFAULT_STATUS_BAR_ALPHA = 112;
    private static final int FAKE_STATUS_BAR_VIEW_ID = com.lqx.fragmentdemo.R.id.statusbarutil_fake_status_bar_view;
    private static final int FAKE_TRANSLUCENT_VIEW_ID = com.lqx.fragmentdemo.R.id.statusbarutil_translucent_view;
    private static final int TAG_KEY_HAVE_SET_OFFSET = -123;

    /**
     * 設(shè)置狀態(tài)欄顏色
     *
     * @param activity 需要設(shè)置的 activity
     * @param color    狀態(tài)欄顏色值
     */
    public static void setColor(Activity activity, @ColorInt int color) {
        setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA);
    }

    /**
     * 設(shè)置狀態(tài)欄顏色
     * API等級19:Android 4.4 KitKat   API等級20:Android 4.4W   API等級21:Android 5.0 Lollipop
     * API等級22:Android 5.1 Lollipop  API等級23:Android 6.0 Marshmallow   API等級24:Android 7.0 Nougat
     *
     * @param activity       需要設(shè)置的activity
     * @param color          狀態(tài)欄顏色值
     * @param statusBarAlpha 狀態(tài)欄透明度
     */
    public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {
        //21以上
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));
            //19到21
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //DecorView是頂級View,內(nèi)部有titlebar和contentParent兩個(gè)子元素,
            // contentParent的id是content,而我們設(shè)置的main.xml布局則是contentParent里面的一個(gè)子元素
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
            if (fakeStatusBarView != null) {
                if (fakeStatusBarView.getVisibility() == View.GONE) {
                    fakeStatusBarView.setVisibility(View.VISIBLE);
                }
                fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
            } else {
                //第一次加載會(huì)先創(chuàng)建并添加
                decorView.addView(createStatusBarView(activity, color, statusBarAlpha));
            }
            setRootView(activity);
        }
    }

    /**
     * 為滑動(dòng)返回界面設(shè)置狀態(tài)欄顏色
     *
     * @param activity 需要設(shè)置的activity
     * @param color    狀態(tài)欄顏色值
     */
    public static void setColorForSwipeBack(Activity activity, int color) {
        setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA);
    }

    /**
     * 為滑動(dòng)返回界面設(shè)置狀態(tài)欄顏色
     *
     * @param activity       需要設(shè)置的activity
     * @param color          狀態(tài)欄顏色值
     * @param statusBarAlpha 狀態(tài)欄透明度
     */
    public static void setColorForSwipeBack(Activity activity, @ColorInt int color,
                                            @IntRange(from = 0, to = 255) int statusBarAlpha) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
            View rootView = contentView.getChildAt(0);
            int statusBarHeight = getStatusBarHeight(activity);
            if (rootView != null && rootView instanceof CoordinatorLayout) {
                final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                    coordinatorLayout.setFitsSystemWindows(false);
                    contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
                    boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
                    if (isNeedRequestLayout) {
                        contentView.setPadding(0, statusBarHeight, 0, 0);
                        coordinatorLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                coordinatorLayout.requestLayout();
                            }
                        });
                    }
                } else {
                    coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
                }
            } else {
                contentView.setPadding(0, statusBarHeight, 0, 0);
                contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
            }
            setTransparentForWindow(activity);
        }
    }

    /**
     * 設(shè)置狀態(tài)欄純色 不加半透明效果
     *
     * @param activity 需要設(shè)置的 activity
     * @param color    狀態(tài)欄顏色值
     */
    public static void setColorNoTranslucent(Activity activity, @ColorInt int color) {
        setColor(activity, color, 0);
    }

    /**
     * 設(shè)置狀態(tài)欄顏色(5.0以下無半透明效果,不建議使用)
     *
     * @param activity 需要設(shè)置的 activity
     * @param color    狀態(tài)欄顏色值
     */
    @Deprecated
    public static void setColorDiff(Activity activity, @ColorInt int color) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        transparentStatusBar(activity);
        ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
        // 移除半透明矩形,以免疊加
        View fakeStatusBarView = contentView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            if (fakeStatusBarView.getVisibility() == View.GONE) {
                fakeStatusBarView.setVisibility(View.VISIBLE);
            }
            fakeStatusBarView.setBackgroundColor(color);
        } else {
            contentView.addView(createStatusBarView(activity, color));
        }
        setRootView(activity);
    }

    /**
     * 使?fàn)顟B(tài)欄半透明
     * <p>
     * 適用于圖片作為背景的界面,此時(shí)需要圖片填充到狀態(tài)欄
     *
     * @param activity 需要設(shè)置的activity
     */
    public static void setTranslucent(Activity activity) {
        setTranslucent(activity, DEFAULT_STATUS_BAR_ALPHA);
    }

    /**
     * 使?fàn)顟B(tài)欄半透明
     * <p>
     * 適用于圖片作為背景的界面,此時(shí)需要圖片填充到狀態(tài)欄
     *
     * @param activity       需要設(shè)置的activity
     * @param statusBarAlpha 狀態(tài)欄透明度
     */
    public static void setTranslucent(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        setTransparent(activity);
        addTranslucentView(activity, statusBarAlpha);
    }

    /**
     * 針對根布局是 CoordinatorLayout, 使?fàn)顟B(tài)欄半透明
     * <p>
     * 適用于圖片作為背景的界面,此時(shí)需要圖片填充到狀態(tài)欄
     *
     * @param activity       需要設(shè)置的activity
     * @param statusBarAlpha 狀態(tài)欄透明度
     */
    public static void setTranslucentForCoordinatorLayout(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        transparentStatusBar(activity);
        addTranslucentView(activity, statusBarAlpha);
    }

    /**
     * 設(shè)置狀態(tài)欄全透明
     *
     * @param activity 需要設(shè)置的activity
     */
    public static void setTransparent(Activity activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        transparentStatusBar(activity);
        setRootView(activity);
    }

    /**
     * 使?fàn)顟B(tài)欄透明(5.0以上半透明效果,不建議使用)
     * <p>
     * 適用于圖片作為背景的界面,此時(shí)需要圖片填充到狀態(tài)欄
     *
     * @param activity 需要設(shè)置的activity
     */
    @Deprecated
    public static void setTranslucentDiff(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // 設(shè)置狀態(tài)欄透明
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            setRootView(activity);
        }
    }

    /**
     * 為DrawerLayout 布局設(shè)置狀態(tài)欄變色
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     * @param color        狀態(tài)欄顏色值
     */
    public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
        setColorForDrawerLayout(activity, drawerLayout, color, DEFAULT_STATUS_BAR_ALPHA);
    }

    /**
     * 為DrawerLayout 布局設(shè)置狀態(tài)欄顏色,純色
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     * @param color        狀態(tài)欄顏色值
     */
    public static void setColorNoTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
        setColorForDrawerLayout(activity, drawerLayout, color, 0);
    }

    /**
     * 為DrawerLayout 布局設(shè)置狀態(tài)欄變色
     *
     * @param activity       需要設(shè)置的activity
     * @param drawerLayout   DrawerLayout
     * @param color          狀態(tài)欄顏色值
     * @param statusBarAlpha 狀態(tài)欄透明度
     */
    public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,
                                               @IntRange(from = 0, to = 255) int statusBarAlpha) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        } else {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        // 生成一個(gè)狀態(tài)欄大小的矩形
        // 添加 statusBarView 到布局中
        ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
        View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            if (fakeStatusBarView.getVisibility() == View.GONE) {
                fakeStatusBarView.setVisibility(View.VISIBLE);
            }
            fakeStatusBarView.setBackgroundColor(color);
        } else {
            contentLayout.addView(createStatusBarView(activity, color), 0);
        }
        // 內(nèi)容布局不是 LinearLayout 時(shí),設(shè)置padding top
        if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
            contentLayout.getChildAt(1)
                    .setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),
                            contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());
        }
        // 設(shè)置屬性
        setDrawerLayoutProperty(drawerLayout, contentLayout);
        addTranslucentView(activity, statusBarAlpha);
    }

    /**
     * 設(shè)置 DrawerLayout 屬性
     *
     * @param drawerLayout              DrawerLayout
     * @param drawerLayoutContentLayout DrawerLayout 的內(nèi)容布局
     */
    private static void setDrawerLayoutProperty(DrawerLayout drawerLayout, ViewGroup drawerLayoutContentLayout) {
        ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);
        drawerLayout.setFitsSystemWindows(false);
        drawerLayoutContentLayout.setFitsSystemWindows(false);
        drawerLayoutContentLayout.setClipToPadding(true);
        drawer.setFitsSystemWindows(false);
    }

    /**
     * 為DrawerLayout 布局設(shè)置狀態(tài)欄變色(5.0以下無半透明效果,不建議使用)
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     * @param color        狀態(tài)欄顏色值
     */
    @Deprecated
    public static void setColorForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            // 生成一個(gè)狀態(tài)欄大小的矩形
            ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
            View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);
            if (fakeStatusBarView != null) {
                if (fakeStatusBarView.getVisibility() == View.GONE) {
                    fakeStatusBarView.setVisibility(View.VISIBLE);
                }
                fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, DEFAULT_STATUS_BAR_ALPHA));
            } else {
                // 添加 statusBarView 到布局中
                contentLayout.addView(createStatusBarView(activity, color), 0);
            }
            // 內(nèi)容布局不是 LinearLayout 時(shí),設(shè)置padding top
            if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
                contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);
            }
            // 設(shè)置屬性
            setDrawerLayoutProperty(drawerLayout, contentLayout);
        }
    }

    /**
     * 為 DrawerLayout 布局設(shè)置狀態(tài)欄透明
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     */
    public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {
        setTranslucentForDrawerLayout(activity, drawerLayout, DEFAULT_STATUS_BAR_ALPHA);
    }

    /**
     * 為 DrawerLayout 布局設(shè)置狀態(tài)欄透明
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     */
    public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout,
                                                     @IntRange(from = 0, to = 255) int statusBarAlpha) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        setTransparentForDrawerLayout(activity, drawerLayout);
        addTranslucentView(activity, statusBarAlpha);
    }

    /**
     * 為 DrawerLayout 布局設(shè)置狀態(tài)欄透明
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     */
    public static void setTransparentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        } else {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }

        ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
        // 內(nèi)容布局不是 LinearLayout 時(shí),設(shè)置padding top
        if (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {
            contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);
        }

        // 設(shè)置屬性
        setDrawerLayoutProperty(drawerLayout, contentLayout);
    }

    /**
     * 為 DrawerLayout 布局設(shè)置狀態(tài)欄透明(5.0以上半透明效果,不建議使用)
     *
     * @param activity     需要設(shè)置的activity
     * @param drawerLayout DrawerLayout
     */
    @Deprecated
    public static void setTranslucentForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // 設(shè)置狀態(tài)欄透明
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            // 設(shè)置內(nèi)容布局屬性
            ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);
            contentLayout.setFitsSystemWindows(true);
            contentLayout.setClipToPadding(true);
            // 設(shè)置抽屜布局屬性
            ViewGroup vg = (ViewGroup) drawerLayout.getChildAt(1);
            vg.setFitsSystemWindows(false);
            // 設(shè)置 DrawerLayout 屬性
            drawerLayout.setFitsSystemWindows(false);
        }
    }

    /**
     * 為頭部是 ImageView 的界面設(shè)置狀態(tài)欄全透明
     *
     * @param activity       需要設(shè)置的activity
     * @param needOffsetView 需要向下偏移的 View
     */
    public static void setTransparentForImageView(Activity activity, View needOffsetView) {
        setTranslucentForImageView(activity, 0, needOffsetView);
    }

    /**
     * 為頭部是 ImageView 的界面設(shè)置狀態(tài)欄透明(使用默認(rèn)透明度)
     *
     * @param activity       需要設(shè)置的activity
     * @param needOffsetView 需要向下偏移的 View
     */
    public static void setTranslucentForImageView(Activity activity, View needOffsetView) {
        setTranslucentForImageView(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);
    }

    /**
     * 為頭部是 ImageView 的界面設(shè)置狀態(tài)欄透明
     *
     * @param activity       需要設(shè)置的activity
     * @param statusBarAlpha 狀態(tài)欄透明度
     * @param needOffsetView 需要向下偏移的 View
     */
    public static void setTranslucentForImageView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,
                                                  View needOffsetView) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            return;
        }
        setTransparentForWindow(activity);
        addTranslucentView(activity, statusBarAlpha);
        if (needOffsetView != null) {
            Object haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_OFFSET);
            if (haveSetOffset != null && (Boolean) haveSetOffset) {
                return;
            }
            ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) needOffsetView.getLayoutParams();
            layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + getStatusBarHeight(activity),
                    layoutParams.rightMargin, layoutParams.bottomMargin);
            needOffsetView.setTag(TAG_KEY_HAVE_SET_OFFSET, true);
        }
    }

    /**
     * 為 fragment 頭部是 ImageView 的設(shè)置狀態(tài)欄透明
     *
     * @param activity       fragment 對應(yīng)的 activity
     * @param needOffsetView 需要向下偏移的 View
     */
    public static void setTranslucentForImageViewInFragment(Activity activity, View needOffsetView) {
        setTranslucentForImageViewInFragment(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);
    }

    /**
     * 為 fragment 頭部是 ImageView 的設(shè)置狀態(tài)欄透明
     *
     * @param activity       fragment 對應(yīng)的 activity
     * @param needOffsetView 需要向下偏移的 View
     */
    public static void setTransparentForImageViewInFragment(Activity activity, View needOffsetView) {
        setTranslucentForImageViewInFragment(activity, 0, needOffsetView);
    }

    /**
     * 為 fragment 頭部是 ImageView 的設(shè)置狀態(tài)欄透明
     *
     * @param activity       fragment 對應(yīng)的 activity
     * @param statusBarAlpha 狀態(tài)欄透明度
     * @param needOffsetView 需要向下偏移的 View
     */
    public static void setTranslucentForImageViewInFragment(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,
                                                            View needOffsetView) {
        setTranslucentForImageView(activity, statusBarAlpha, needOffsetView);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            clearPreviousSetting(activity);
        }
    }

    /**
     * 隱藏偽狀態(tài)欄 View
     *
     * @param activity 調(diào)用的 Activity
     */
    public static void hideFakeStatusBarView(Activity activity) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            fakeStatusBarView.setVisibility(View.GONE);
        }
        View fakeTranslucentView = decorView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
        if (fakeTranslucentView != null) {
            fakeTranslucentView.setVisibility(View.GONE);
        }
    }

    ///////////////////////////////////////////////////////////////////////////////////

    @TargetApi(Build.VERSION_CODES.KITKAT)
    private static void clearPreviousSetting(Activity activity) {
        ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
        View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);
        if (fakeStatusBarView != null) {
            decorView.removeView(fakeStatusBarView);
            ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
            rootView.setPadding(0, 0, 0, 0);
        }
    }

    /**
     * 添加半透明矩形條
     *
     * @param activity       需要設(shè)置的 activity
     * @param statusBarAlpha 透明值
     */
    private static void addTranslucentView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {
        ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
        View fakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);
        if (fakeTranslucentView != null) {
            if (fakeTranslucentView.getVisibility() == View.GONE) {
                fakeTranslucentView.setVisibility(View.VISIBLE);
            }
            fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));
        } else {
            contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));
        }
    }

    /**
     * 生成一個(gè)和狀態(tài)欄大小相同的彩色矩形條
     *
     * @param activity 需要設(shè)置的 activity
     * @param color    狀態(tài)欄顏色值
     * @return 狀態(tài)欄矩形條
     */
    private static View createStatusBarView(Activity activity, @ColorInt int color) {
        return createStatusBarView(activity, color, 0);
    }

    /**
     * 生成一個(gè)和狀態(tài)欄大小相同的半透明矩形條
     *
     * @param activity 需要設(shè)置的activity
     * @param color    狀態(tài)欄顏色值
     * @param alpha    透明值
     * @return 狀態(tài)欄矩形條
     */
    private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {
        // 繪制一個(gè)和狀態(tài)欄一樣高的矩形
        View statusBarView = new View(activity);
        LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));
        statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);
        return statusBarView;
    }

    /**
     * 設(shè)置根布局參數(shù)
     */
    private static void setRootView(Activity activity) {
        ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);
        for (int i = 0, count = parent.getChildCount(); i < count; i++) {
            View childView = parent.getChildAt(i);
            if (childView instanceof ViewGroup) {
                childView.setFitsSystemWindows(true);
                ((ViewGroup) childView).setClipToPadding(true);
            }
        }
    }

    /**
     * 設(shè)置透明
     */
    private static void setTransparentForWindow(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
            activity.getWindow()
                    .getDecorView()
                    .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            activity.getWindow()
                    .setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 使?fàn)顟B(tài)欄透明
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private static void transparentStatusBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        } else {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 創(chuàng)建半透明矩形 View
     *
     * @param alpha 透明值
     * @return 半透明 View
     */
    private static View createTranslucentStatusBarView(Activity activity, int alpha) {
        // 繪制一個(gè)和狀態(tài)欄一樣高的矩形
        View statusBarView = new View(activity);
        LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));
        statusBarView.setLayoutParams(params);
        statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));
        statusBarView.setId(FAKE_TRANSLUCENT_VIEW_ID);
        return statusBarView;
    }

    /**
     * 獲取狀態(tài)欄高度
     *
     * @param context context
     * @return 狀態(tài)欄高度
     */
    public static int getStatusBarHeight(Context context) {
        // 獲得狀態(tài)欄高度
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        return context.getResources().getDimensionPixelSize(resourceId);
    }

    /**
     * 計(jì)算狀態(tài)欄顏色
     *
     * @param color color值
     * @param alpha alpha值
     * @return 最終的狀態(tài)欄顏色
     */
    private static int calculateStatusColor(@ColorInt int color, int alpha) {
        if (alpha == 0) {
            return color;
        }
        float a = 1 - alpha / 255f;
        int red = color >> 16 & 0xff;
        int green = color >> 8 & 0xff;
        int blue = color & 0xff;
        red = (int) (red * a + 0.5);
        green = (int) (green * a + 0.5);
        blue = (int) (blue * a + 0.5);
        return 0xff << 24 | red << 16 | green << 8 | blue;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,384評論 0 17
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 47,183評論 22 665
  • 當(dāng)你真的去愛一個(gè)人的時(shí)候,你會(huì)發(fā)現(xiàn)你在乎的是她的一切,盡管在別人眼里看來是幼稚的事情。
    軟軟大人閱讀 220評論 0 0

友情鏈接更多精彩內(nèi)容