Android 透明状态栏

转载:https://blog.csdn.net/fan7983377/article/details/51604657

最近公司产品提出透明状态栏的要求,将一张背景填充满屏幕,自己记录一下:

Android 透明状态栏:有两种,背景是图片还是纯色,下面分开讲:

1.当背景为图片时,布局可以这么写:

方法1,在代码onCreate()方法里书写下面代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    Window window = getWindow();
    window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
            | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
    window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    window.setStatusBarColor(Color.TRANSPARENT);
    window.setNavigationBarColor(Color.TRANSPARENT);
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    Window window = getWindow();
    window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
            WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}

然后在xml跟布局,设置属性:android:fitsSystemWindows="true",代码如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    
    android:background="@drawable/bg_scenery"
    android:fitsSystemWindows="true">
</LinearLayout>

效果图:

方法二:主要的操作都在style.xml 和 AndroidManifest.xml 中,Activity里面没有任何涉及到需要设置的代码,所以可以忽略不看。

ps:

首先需要到AndroidManifest中为指定的Activity设置Theme。但是需要注意的是,我们不能直接在values/style.xml直接去自定义 Translucet System Bar 的Theme,因为改特性仅兼容 Android 4.4 开始的平台,所以直接在values/style.xml声明引入,工程会报错。有些开发者朋友会在代码中去判断SDK的版本,然后再用代码设置Theme。虽然同样可以实现效果,但个人并不推崇这种做法。我所采取的方法则是建立多个SDK版本的values文件夹,系统会根据SDK的版本选择合适的Theme进行设置。大家可以看到上面我的工程里面有valuesvalues-v19values-v21

该方法需要做下面三步设置:

step1:在valuesvalues-v19values-v21的style.xml都设置一个 Translucent System Bar 风格的Theme

values/style.xml

<style name="ImageTranslucentTheme" parent="AppTheme">
    <!--在Android 4.4之前的版本上运行,直接跟随系统主题-->
</style>

values-v19/style.xml

<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

values-v21/style.xml

<style name="ImageTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <!--Android 5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色-->
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

上面需要注意的地方是,无论你在哪个SDK版本的values目录下,设置了主题,都应该在最基本的values下设置一个同名的主题。这样才能确保你的app能够正常运行在 Android 4.4 以下的设备。否则,肯定会报找不到Theme的错误。

step2:在AndroidManifest.xml中对指定Activity的theme进行设置

<activity android:name=".activity.ImageActivity"
    android:theme="@style/ImageTranslucentTheme"/>

step3:在Activity的布局文件中设置背景图片,同时,需要把android:fitsSystemWindows设置为true

xml布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_building"
    android:fitsSystemWindows="true">
</LinearLayout>

效果图:

上面2中方法,如果仅仅需要ImageView控件覆盖状态栏,那么将android:fitsSystemWindows设置为false即可。

xml布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_building"
    android:fitsSystemWindows="false">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="fitXY"
        android:src="@drawable/hehua"/>

</LinearLayout>

效果图:

1.当背景为纯色时,

由于它的Tab栏是纯色的,所以只要把系统通知栏的颜色设置和Tab栏的颜色一致即可,实现上相比方法一要简单很多。同样要到不同SDK版本的values下,创建一个同名的theme,在values-v21下,需要设置系统导航栏的颜色:

values/style.xml

<style name="ColorTranslucentTheme" parent="AppTheme">
</style>

values-v19/style.xml

<style name="ColorTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item>
</style>

values-v21/style.xml

<style name="ColorTranslucentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowTranslucentNavigation">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
</style>

在AndroidManifest.xml中对指定Activity的theme进行设置

<!--图片-->
<activity android:name=".activity.ColorActivity"
    android:theme="@style/ColorTranslucentTheme"/>

xml布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/bar_color"
    android:fitsSystemWindows="true">

    <!--标题布局-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:background="@color/bar_color">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="这是title栏"
            android:textColor="@android:color/white"
            android:textSize="20sp" />
    </RelativeLayout>

    <!--内容布局-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@android:color/white">
        <!--自己根据实际需求填写-->

    </LinearLayout>
</LinearLayout>

效果图:

好了,以上就是沉浸式状态栏实现的全过程,但是还有一点值得注意的就是,如果我们activity比较多,每一个页面都添加android:fitsSystemWindows="true" 比较麻烦,我们需要改动一下:

写一个基类BaseColorActivity.class,代码如下:

public abstract class BaseColorActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//这一行注意!看本文最后的说明!!!!

        setContentView(getLayoutId());

        ViewGroup contentFrameLayout = (ViewGroup) findViewById(Window.ID_ANDROID_CONTENT);
        View parentView = contentFrameLayout.getChildAt(0);
        if(parentView != null && Build.VERSION.SDK_INT >= 14){
            parentView.setFitsSystemWindows(true);
        }
    }

    protected abstract int getLayoutId();
}

然后需要沉浸状态栏的activity继承该基类:

public class ColorActivity extends BaseColorActivity {

    public static void startActivity(Context context){
        Intent intent = new Intent(context, ColorActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_color;
    }
}

然后需要沉浸状态栏的activity的布局文件中就可以把android:fitsSystemWindows="true"这行代码给省略了!,其他设置还是按照一开始操作。

 

写个工具类StatusBarCompat.class

public class StatusBarCompat {

    private static final int INVALID_VAL = -1;
    private static final int COLOR_DEFAULT = Color.parseColor("#20000000");

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static void compat(Activity activity, int statusColor)
    {

        //当前手机版本为5.0及以上 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            if (statusColor != INVALID_VAL)
            {
                activity.getWindow().setStatusBarColor(statusColor);
            }
            return;
        }

        //当前手机版本为4.4
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
        {
            int color = COLOR_DEFAULT;
            ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
            if (statusColor != INVALID_VAL)
            {
                color = statusColor;
            }
            View statusBarView = new View(activity);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    getStatusBarHeight(activity));
            statusBarView.setBackgroundColor(color);
            contentView.addView(statusBarView, lp);
        }

    }

    public static void compat(Activity activity)
    {
        compat(activity, INVALID_VAL);
    }


    public 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的onCreate中,调用方法StatusBarCompat.compat就可以了:

//第二个参数是想要设置的颜色

StatusBarCompat.compat(this, Color.RED);

如果嫌每个activity都要写有点麻烦,那就写个基类来完成这一步:

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        StatusBarCompat.compat(this, Color.RED);
    }
}

关于上面代码中提示注意的那个地方的说明:

隐藏系统title注意的两点:

  1. 继承AppCompatActivity时使用: 
    supportRequestWindowFeature(Window.FEATURENOTITLE)

  2. 继承activity时使用: 
    requestWindowFeature(Window.FEATURENOTITLE) 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值