[奇技淫巧] Android 4.4 5.0 6.0 另一种思路的沉浸式状态栏

[奇技淫巧] Android 4.4 5.0 6.0 另一种思路的沉浸式状态栏

最近在写公司项目
想统一写一下沉浸式状态栏,看到网上的例子,感觉还是好复杂啊,,Ծ‸Ծ,,
要配置xml,一会又要写代码 有些地方也不一定会用到,又要去配置一遍,有没有什么简单点,在一处配置,简便使用的方法呢?
所以想到了一个简单的奇技淫巧来达到目的

思路

我们只需要考虑用不同版本的方法把默认的状态栏全部隐藏掉,在基类中创建一个空白View填满原本是状态栏的位置,我们只需要控制好自己创建的statusBar就可以了,这样就不会有各种各样麻烦的东西出现,简化很多很多。

创建基类BaseActivity

/**
 * Created by HuangQS on 2017/6/22 04:33
 * Email:515215310@qq.com
 */
public abstract class BaseActivity extends AppCompatActivity{
    protected boolean isShowStatusBar = true;    //设置是否显示伪造的状态栏
    protected int statusColor = -1;              //状态栏颜色

    protected abstract int setLayoutResId();    //资源文件位置 回传R.layout.activity_main
    protected abstract void initView();         //初始化控件
    protected abstract void initListener();     //初始化监听器

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int resId = setLayoutResId();
        mContext = this;
          try {
            if (resId > 0) {
                setContentView(R.layout.activity_base);
                View statusBar = findViewById(R.id.view_base_status_bar);
                FrameLayout frameLayout = (FrameLayout) findViewById(R.id.fl_base_content);
                LayoutInflater.from(mContext).inflate(resId, frameLayout, true);

                initView();
                initListener();

                //设置状态栏
                //注意状态栏的位置一定要在initView的后面
                //我们会在继承BaseActivity的activity里initView()中设置颜色和显示状态栏
                NewStatusBarUtils.setStatusBarUtils(this, isShowStatusBar, statusBar, statusColor);
            }
        } catch (Exception e) {
            //如果错误应该没有错误
            e.printStackTrace();
        }
  }
}

基类里面具体放什么,就随便你啦,反正基本的就这些
然后是上面出现的activity_base的代码 很简单 就只是一个控件(伪状态栏)和一个存放子类Activity的ViewGroup

基类的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--伪造的状态栏-->
    <View
        android:id="@+id/view_base_status_bar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:visibility="gone"/>
    <!--内容布局 子类activity中的内容都会在这里-->
    <FrameLayout
        android:id="@+id/fl_base_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

写完这些,接下来就是工具类NewStatusBarUtils 为了方便,就把包名也写进来吧。这样复制的时候,就不会出问题了(一般也不会出问题的= = )

状态栏工具类NewStatusBarUtils

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

/**
 * 状态栏工具类
 * Created by HuangQS on 2017/6/22 09:20
 * Email:515215310@qq.com
 */

public class NewStatusBarUtils {
    private static final int INVALID_VAL = -1;
    private static final int COLOR_DEFAULT = Color.GREEN;


    public static void setStatusBarUtils(Activity activity, boolean isShow, View statusBar) {
        setStatusBarUtils(activity, isShow, statusBar, INVALID_VAL);
    }


    public static void setStatusBarUtils(Activity activity, boolean isShow, View statusBar, int statusColor) {
        //设置状态栏默认颜色
        if (isShow) {
            if (statusColor == INVALID_VAL) {
                statusColor = ActivityCompat.getColor(activity, R.color.status_bar_color);
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //version_code > 5.0
            setHideStatusBar21(activity);
            if (isShow) {
                ViewGroup.LayoutParams layoutParams = statusBar.getLayoutParams();
                layoutParams.height = getStatusBarHeight(activity);
                statusBar.setVisibility(View.VISIBLE);
                statusBar.setBackgroundColor(statusColor);
            } else {
                statusBar.setVisibility(View.GONE);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { //4.4 <= version_code<5.0
            setHideStatusBar19(activity);
            if (isShow) {
                ViewGroup.LayoutParams layoutParams = statusBar.getLayoutParams();
                layoutParams.height = getStatusBarHeight(activity);
                statusBar.setVisibility(View.VISIBLE);
                statusBar.setBackgroundColor(statusColor);
            } else {
                statusBar.setVisibility(View.GONE);
            }
        } else {
            LogUtils.d(NewStatusBarUtils.class.getSimpleName(), ":setStatusBarUtils 4.4以下");
        }
    }
    //4.4~~5.0隐藏状态栏
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static void setHideStatusBar19(Activity activity) {
        Window window = activity.getWindow();
        window.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
//        StatusBarHelper.from(activity).setTransparentStatusbar(true).process();

        WindowManager.LayoutParams winParams = window.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        winParams.flags |= bits;
        window.setAttributes(winParams);
    }

     //5.0++隐藏状态栏
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private static void setHideStatusBar21(Activity activity) {  //隐藏5.0++状态栏
        Window window = activity.getWindow();

        window.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
        activity.getWindow().setNavigationBarColor(Color.TRANSPARENT);

        if (AndroidWorkaround.checkDeviceHasNavigationBar(activity)) {
            AndroidWorkaround.assistActivity(activity.findViewById(android.R.id.content));
        }
    }

    //获取状态栏高度,网上的教程很多都是这个方法一模一样= = 果然天下代码一大抄 哈哈哈
    private static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
}

Activity子类中的控制

public class LoginFragment extends BaseActivity{

    @Override
    public void initView() {
        isShowStatusBar = true; //显示状态栏,基类中是true,此处为了演示方便临时写一下意思意思而已,别介意
        statusColor = ActivityCompat.getColor(activity, R.color.status_bar_color);

        //这些都是不重要的东东了 可以不用理 关键的都在上面↑↑↑
        scrollView = $findViewById(R.id.sv_fragment_login_scroll);
        etUserName = $findViewById(R.id.login_et_username);
        etPassword = $findViewById(R.id.login_et_password);
        tvForgetPwd = $findViewById(R.id.login_tv_forget_pwd);
        btnLogin = $findViewById(R.id.login_btn_login);
        btnRegister = $findViewById(R.id.login_btn_register);
    }

    @Override
    protected void initListener() {
        //实现监听器
    }

    @Override
    public int setLayoutResId() {
        return R.layout.fragment_login; //在这里设置布局,在基类中自动处理。
    }
}

所有的代码已经简化到非常简单,代码也比较清晰(我自己这么认为的, (。˘•ε•˘。)别打我)大概就是这些关键点。
不过有一个需要说明的这种方法很快捷的管理实现状态栏,可以对状态栏颜色,状态栏显示隐藏做控制,但是有一点需要知道,那就是:

在基类中多出一层layout界面,如果代码追求极度简洁,强迫癌终极患者,可能会影响到性能(。・`ω´・)

其他快捷介绍 Level > 5.0++

透明隐藏顶部状态栏(也就是顶部电池,时间,信号的条条)Translucent status bar

window.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

透明隐藏底部导航栏 (也就是底部的虚拟按键) Translucent navigation bar

window.setFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

设置状态栏背景颜色

activity.getWindow().setStatusBarColor(Color.TRANSPARENT);

设置底部虚拟按键背景颜色

activity.getWindow().setNavigationBarColor(Color.BLUE);

相关资料

华为虚拟按键导致导航栏顶上去的解决方法[链接]

实现4.4以上的状态栏变色,参考这里的StatusBarUtils 对顶部状态栏处理 测试发现该方法在华为Nova 7.0貌似没有效果,所以只作为参考[链接]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值