棒棒糖上完全透明的状态栏和导航栏

Posted

技术标签:

【中文标题】棒棒糖上完全透明的状态栏和导航栏【英文标题】:completely transparent status bar and navigation bar on lollipop 【发布时间】:2015-05-18 02:37:45 【问题描述】:

我正在尝试制作一个 android 启动器。我想实现一个完全透明的状态栏和导航栏,这里是我的主题xml文件。

<resources>
    <style name="Theme" parent="android:Theme.Material.Wallpaper.NoTitleBar">
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <item name="android:windowTranslucentStatus">false</item>
        <item name="android:windowTranslucentNavigation">false</item>
    </style>
</resources>

最后两项不行,棒棒糖上还有阴影。

这就是它的样子(注意实际上状态栏和导航栏上有一个阴影):

我想要实现的目标(新星发射器):

如何让状态栏和导航栏“透明”而不是“半透明”?

【问题讨论】:

【参考方案1】:

更新

您可以通过在 Window 中设置 FLAG_LAYOUT_NO_LIMITS 标志以编程方式在 KitKat 上和之后实现相同的效果。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
            Window w = getWindow(); // in Activity's onCreate() for instance
            w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        

如果您为布局设置背景资源(如颜色或图片),您将在状态栏“下方”看到颜色或图片。

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/primary_dark</item>

原答案

看起来android:windowTranslucentStatusandroid:windowTranslucentNavigation 应该是true 而不是false

<resources>
    <style name="Theme" parent="android:Theme.Material.Wallpaper.NoTitleBar">
        <item name="android:statusBarColor">@android:color/transparent</item>
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    </style>
</resources>

另外,你的透明活动/容器布局需要这个属性集:

android:fitsSystemWindows="true"

[来源][1] [1]:https://***.com/a/29311321/1549700

【讨论】:

当我应用这个时,导航栏和状态栏仍然是灰色的半透明颜色,如 here 所示。在 Lollipop 和 M 上测试过。知道为什么吗? 如果您为布局设置背景资源(如颜色或图片),您将在状态栏“下方”看到颜色或图片。检查编辑。 注意,我不需要主题部分,java代码就足够了。 这个答案不适合使用底部导航栏的应用,因为它失去了限制,将导航底部栏放到了手机软键上。 正确答案如何? NO_LIMITS 使内容同时绘制在状态栏和导航栏上。目标只是使导航栏完全透明。【参考方案2】:

我使用它是因为它保持状态栏和导航栏的高度

<!-- Base application theme. -->
<style name="theme" parent="android:Theme.Material.Wallpaper.NoTitleBar">
    <item name="android:navigationBarColor">#00000000</item>
    <item name="android:statusBarColor">#00000000</item>
</style>

不过,这确实需要 API 21+

【讨论】:

对我不起作用。您还对这些属性使用了哪些其他属性?【参考方案3】:

适用于 API 29 及更高版本

<style name="Your.Theme">
    <item name="android:navigationBarColor">@android:color/transparent</item>
    <item name="android:enforceNavigationBarContrast">false</item>
</style>

【讨论】:

【参考方案4】:

您可以使用这个 kotlin 扩展功能,它将状态栏设置为完全透明(在 API 23+ 上,View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 标志在 API 23+ 上可用)和导航栏(在 API 27+ 上,View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR 标志在 API 27+ 上可用)否则它将在 API 21+ 上使用 systemUiScrim 颜色

fun Activity.transparentStatusAndNavigation(
    systemUiScrim: Int = Color.parseColor("#40000000") // 25% black
) 
    var systemUiVisibility = 0
    // Use a dark scrim by default since light status is API 23+
    var statusBarColor = systemUiScrim
    //  Use a dark scrim by default since light nav bar is API 27+
    var navigationBarColor = systemUiScrim
    val winParams = window.attributes


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
        systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        statusBarColor = Color.TRANSPARENT
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
        systemUiVisibility = systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
        navigationBarColor = Color.TRANSPARENT
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        systemUiVisibility = systemUiVisibility or
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        window.decorView.systemUiVisibility = systemUiVisibility
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) 
        winParams.flags = winParams.flags or
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
        winParams.flags = winParams.flags and
                (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or
                        WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION).inv()
        window.statusBarColor = statusBarColor
        window.navigationBarColor = navigationBarColor
    

    window.attributes = winParams

API 21+ API 27+

【讨论】:

只有这个答案才能使状态栏透明。最佳答案。【参考方案5】:

100% 工作代码

完全透明的状态栏和导航栏

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    initStatusNavBar();
    transparentStatusAndNavigation();

    showSystemUI();
    // hideSystemUI();



public static void transparentStatusAndNavigation(Activity activity) 

    Window window = activity.getWindow();

    // make full transparent statusBar
    if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) 
        setWindowFlag(window, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, true);
    
    if (Build.VERSION.SDK_INT >= 19) 
        int visibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        visibility = visibility | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
        window.getDecorView().setSystemUiVisibility(visibility);
    
    if (Build.VERSION.SDK_INT >= 21) 
        int windowManager = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        windowManager = windowManager | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
        setWindowFlag(window, windowManager, false);
        window.setStatusBarColor(Color.TRANSPARENT);
        window.setNavigationBarColor(Color.TRANSPARENT);
    



private static void setWindowFlag(final int bits, boolean on) 
    Window win = getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();
    if (on) 
        winParams.flags |= bits;
     else 
        winParams.flags &= ~bits;
    
    win.setAttributes(winParams);

设置状态栏和导航栏高度和颜色:

在activity_main.xml中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainLayout"
    android:layout_
    android:layout_
    android:background="@android:color/white"
    android:orientation="vertical">

    <View
        android:id="@+id/status_bg"
        android:layout_
        android:layout_
        android:background="@color/primaryColorLightThemeDarkTrans"
        tools:layout_ />

    <LinearLayout
        android:layout_
        android:layout_
        android:layout_weight="1">

        <!--Write Code Here-->

    </LinearLayout>

    <View
        android:id="@+id/nav_bg"
        android:layout_
        android:layout_
        android:background="@color/navColorLightThemeTrans"
        tools:layout_ />
</LinearLayout>

在java代码中:

private void initStatusNavBar() 
    int statusBarHeight = getStatusBarHeight(activity);
    int navBarHeight = getNavigationBarHeight(activity, statusBarHeight);

    View statusBarBackground = findViewById(R.id.status_bg);
    statusBarBackground.getLayoutParams().height = statusBarHeight;

    View navBarBackground = findViewById(R.id.nav_bg);
    if (Build.VERSION.SDK_INT >= 21) 
        setNavigationBarHeight(activity, navBarBackground);
     else 
        navBarBackground.getLayoutParams().height = navBarHeight;
    


public static int getStatusBarHeight(Activity activity) 
    final Resources resources = activity.getResources();
    final int resId = resources.getIdentifier("status_bar_height", "dimen", "android");
    if (resId > 0) 
        return resources.getDimensionPixelSize(resId);
    
    return 0;


public static int getNavigationBarHeight(Activity activity, int statusBarHeight) 
    Point point = getNavigationBarSize(activity);
    int height = point.y;
    if (isNotchDisplay(statusBarHeight)) 
        height = height - statusBarHeight;
    
    return height;


private static Point getNavigationBarSize(Context context) 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        Point appUsableSize = getAppUsableScreenSize(context);
        Point realScreenSize = getRealScreenSize(context);

        // navigation bar on the right
        if (appUsableSize.x < realScreenSize.x) 
            return new Point(realScreenSize.x - appUsableSize.x, appUsableSize.y);
        

        // navigation bar at the bottom
        if (appUsableSize.y < realScreenSize.y) 
            return new Point(appUsableSize.x, realScreenSize.y - appUsableSize.y);
        

        // navigation bar is not present
        return new Point();
    
    return new Point();


private static Point getAppUsableScreenSize(Context context) 
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Point size = new Point();
    if (null != windowManager) 
        Display display = windowManager.getDefaultDisplay();
        display.getSize(size);
    
    return size;


private static Point getRealScreenSize(Context context) 
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Point size = new Point();
    if (null != windowManager) 
        Display display = windowManager.getDefaultDisplay();

        if (Build.VERSION.SDK_INT >= 17) 
            display.getRealSize(size);
         else 
            try 
                size.x = (Integer) Display.class.getMethod("getRawWidth").invoke(display);
                size.y = (Integer) Display.class.getMethod("getRawHeight").invoke(display);
             catch (IllegalAccessException e) 
                e.printStackTrace();
             catch (InvocationTargetException e) 
                e.printStackTrace();
             catch (NoSuchMethodException e) 
                e.printStackTrace();
            
        
    

    return size;


private static boolean isNotchDisplay(int statusBarHeight) 
    int normalStatusBarHeight = dpToPxForNav(25);
    return statusBarHeight > normalStatusBarHeight;


private static int dpToPxForNav(float dp) 
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);


public static void setNavigationBarHeight(Activity activity, View navBarBackground) 
    ViewCompat.setOnApplyWindowInsetsListener(navBarBackground, (v, insets) -> 
        int navBarHeight = insets.getSystemWindowInsetBottom();
        navBarBackground.getLayoutParams().height = navBarHeight;
        return insets.consumeSystemWindowInsets();
    );



@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void showSystemUI() 
    statusBarBackground.setVisibility(View.VISIBLE);
    navBarBackground.setVisibility(View.VISIBLE);
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);


@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void hideSystemUI() 
    statusBarBackground.setVisibility(View.GONE);
    navBarBackground.setVisibility(View.GONE);
    mDecorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                    | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

styles.xml 中的主题:

<style name="MyAppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">

    <!--For Notch Issues-->
    <item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">shortEdges</item>

    <item name="windowActionBarOverlay">true</item>

    <item name="colorPrimary">@color/primaryColor</item>
    <item name="colorPrimaryDark">@color/primaryColorDark</item>
    <item name="colorAccent">@color/accentColor</item>
    <item name="colorControlHighlight">@color/colorHighlight</item>
    <item name="android:windowBackground">@android:color/white</item>
    <item name="android:textColorPrimary">#fff6d7</item>

    <item name="android:colorPrimary" tools:targetApi="lollipop">@color/primaryColor</item>
    <item name="android:colorPrimaryDark" tools:targetApi="lollipop">@color/primaryColorDark</item>
    <item name="android:statusBarColor" tools:targetApi="lollipop">@color/primaryColorDark</item>
    <item name="android:colorAccent" tools:targetApi="lollipop">@color/accentColorLight</item>
    <item name="android:colorControlHighlight" tools:targetApi="lollipop">@color/colorHighlight</item>

    <item name="android:navigationBarColor" tools:targetApi="lollipop">@color/navColor</item>

    <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">true</item>

</style>

在 AndroidManifest.xml 中:

    <activity
        android:name="com.MyActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:screenOrientation="fullSensor"
        android:theme="@style/MyAppTheme" />

【讨论】:

不适用于搭载 Android 9 的 Pixel 2 XL。还将底部软件按钮栏更改为没有可见按钮的白条。 @Potass 你必须为Api 23+ 添加标志View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR。请求状态栏以与浅色状态栏背景兼容的模式进行绘制。要使其生效,窗口必须请求 FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS 而不是 FLAG_TRANSLUCENT_STATUS。 developer.android.com/reference/android/view/… 玩设置以获得所需的效果。 也许你还需要添加 window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) 否则你的条会变黑【参考方案6】:

以下代码是我在项目中使用的示例:

styles.xml

<style name="FadingActionBarTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/FadingActionBarWidget</item>
</style>

<style name="FadingActionBarWidget.Transparent">
    <item name="android:background">@android:color/transparent</item>
</style>

<style name="FadingActionBarTheme.TranslucentActionBar">
    <item name="android:icon">@drawable/ic_ab_icon</item>
    <item name="android:actionBarStyle">@style/FadingActionBarWidget.Transparent</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

AndroidManifest.xml

<activity
    android:name=".MyActivity"
    android:label="@string/app_name"
    android:theme="@style/FadingActionBarTheme.TranslucentActionBar">
</activity>

【讨论】:

【参考方案7】:

您需要在主题中添加android:windowDrawsSystemBarBackgrounds 标志

<item name="android:windowDrawsSystemBarBackgrounds">true</item>

或者在 onCreate() 中调用它

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

【讨论】:

这不会使导航栏透明。 @nhaarman 您还需要添加它。窗口 w = getWindow(); w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); 它通过 FLAG_LAYOUT_NO_LIMITS 使状态栏变得透明,但是我的操作栏隐藏了?你能帮忙吗?【参考方案8】:

在状态栏下绘制布局:

值/样式.xml

<item name="android:windowTranslucentStatus">true</item>

values-v21/styles.xml

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>

使用已经处理过 fitSystemWindows 参数的 CoordinatorLayout/DrawerLayout 或创建自己的布局,如下所示:

public class FitsSystemWindowConstraintLayout extends ConstraintLayout 

    private Drawable mStatusBarBackground;
    private boolean mDrawStatusBarBackground;

    private WindowInsetsCompat mLastInsets;

    private Map<View, int[]> childsMargins = new HashMap<>();

    public FitsSystemWindowConstraintLayout(Context context) 
        this(context, null);
    

    public FitsSystemWindowConstraintLayout(Context context, AttributeSet attrs) 
        this(context, attrs, 0);
    

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

        if (ViewCompat.getFitsSystemWindows(this)) 
            ViewCompat.setOnApplyWindowInsetsListener(this, new android.support.v4.view.OnApplyWindowInsetsListener() 
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) 
                    FitsSystemWindowConstraintLayout layout = (FitsSystemWindowConstraintLayout) view;
                    layout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
                    return insets.consumeSystemWindowInsets();
                
            );
            setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            TypedArray typedArray = context.obtainStyledAttributes(new int[]android.R.attr.colorPrimaryDark);
            try 
                mStatusBarBackground = typedArray.getDrawable(0);
             finally 
                typedArray.recycle();
            
         else 
            mStatusBarBackground = null;
        
    

    public void setChildInsets(WindowInsetsCompat insets, boolean draw) 
        mLastInsets = insets;
        mDrawStatusBarBackground = draw;
        setWillNotDraw(!draw && getBackground() == null);

        for (int i = 0; i < getChildCount(); i++) 
            View child = getChildAt(i);
            if (child.getVisibility() != GONE) 
                if (ViewCompat.getFitsSystemWindows(this)) 
                    ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) child.getLayoutParams();

                    if (ViewCompat.getFitsSystemWindows(child)) 
                        ViewCompat.dispatchApplyWindowInsets(child, insets);
                     else 
                        int[] childMargins = childsMargins.get(child);
                        if (childMargins == null) 
                            childMargins = new int[]layoutParams.leftMargin, layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin;
                            childsMargins.put(child, childMargins);
                        
                        if (layoutParams.leftToLeft == LayoutParams.PARENT_ID) 
                            layoutParams.leftMargin = childMargins[0] + insets.getSystemWindowInsetLeft();
                        
                        if (layoutParams.topToTop == LayoutParams.PARENT_ID) 
                            layoutParams.topMargin = childMargins[1] + insets.getSystemWindowInsetTop();
                        
                        if (layoutParams.rightToRight == LayoutParams.PARENT_ID) 
                            layoutParams.rightMargin = childMargins[2] + insets.getSystemWindowInsetRight();
                        
                        if (layoutParams.bottomToBottom == LayoutParams.PARENT_ID) 
                            layoutParams.bottomMargin = childMargins[3] + insets.getSystemWindowInsetBottom();
                        
                    
                
            
        

        requestLayout();
    

    public void setStatusBarBackground(Drawable bg) 
        mStatusBarBackground = bg;
        invalidate();
    

    public Drawable getStatusBarBackgroundDrawable() 
        return mStatusBarBackground;
    

    public void setStatusBarBackground(int resId) 
        mStatusBarBackground = resId != 0 ? ContextCompat.getDrawable(getContext(), resId) : null;
        invalidate();
    

    public void setStatusBarBackgroundColor(@ColorInt int color) 
        mStatusBarBackground = new ColorDrawable(color);
        invalidate();
    

    @Override
    public void onDraw(Canvas canvas) 
        super.onDraw(canvas);
        if (mDrawStatusBarBackground && mStatusBarBackground != null) 
            int inset = mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
            if (inset > 0) 
                mStatusBarBackground.setBounds(0, 0, getWidth(), inset);
                mStatusBarBackground.draw(canvas);
            
        
    

main_activity.xml

<FitsSystemWindowConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:fitsSystemWindows="true">

    <ImageView
        android:layout_
        android:layout_
        android:fitsSystemWindows="true"
        android:scaleType="centerCrop"
        android:src="@drawable/toolbar_background"
        app:layout_constraintBottom_toBottomOf="@id/toolbar"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_
        android:layout_
        android:background="@android:color/transparent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_
        android:layout_
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar">

        <TextView
            android:layout_
            android:layout_
            android:gravity="center"
            android:text="Content"
            android:textSize="48sp" />
    </LinearLayout>
</FitsSystemWindowConstraintLayout>

结果:

【讨论】:

【参考方案9】:

对于那些想要在 KitKat 及更高版本上完全透明的状态栏和导航栏的人来说,使用 windowTranslucentNavigation 和 @Machado 的 Lollipop 答案存在一些小冲突,并防止这种冲突将样式分开

styles.xml

<style name="LockScreenStyle" parent="@android:style/Theme.Wallpaper.NoTitleBar">
    <item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
    <item name="android:windowTranslucentNavigation" tools:targetApi="kitkat">true</item>
</style>

styles.xml (v21)

<style name="LockScreenStyle" parent="@android:style/Theme.Wallpaper.NoTitleBar">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
</style>

MyClass.java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        Window w = getWindow(); // in Activity's onCreate() for instance
        w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 
            w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        
    

【讨论】:

【参考方案10】:

您还可以将 colorPrimary 和 colorPrimaryDark 的 alpha 更改为 00,然后将其添加到您的 onCreateMethod:

    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

并将其添加到您的活动中:

android:fitsSystemWindows="true"

【讨论】:

【参考方案11】:

这是为像我这样使用 Nativescript + Angular 的新手准备的。我从NTS marketplace 上的空白模板之一开始。然后对于我的特定用途,我需要顶部的状态栏始终透明(类似于 ios 样式),导航栏(底部)在某些组件/模块上完全透明(不是半透明!),而在其他组件/模块中不透明。如果一切都按照 NTS 设置的协议完成,你应该有一个类似于这个的 main.ts(我的解决方案的先决条件)

我把我的作品分成两部分,先上,后下。对于顶部,我发现 this answer 有效。所以你应该有一个如下所示的 main.ts 文件。

import  platformNativeScriptDynamic  from "@nativescript/angular";

import  AppModule  from "./app/app.module";

import * as application from "tns-core-modules/application";
import  Color  from "@nativescript/core";

platformNativeScriptDynamic().bootstrapModule(AppModule);

declare var android;

application.android.on(application.AndroidApplication.activityCreatedEvent, (event) => 

    const activity = event.activity;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) 
    activity.getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
    activity.getWindow().clearFlags(android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    activity.getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    activity.getWindow().setStatusBarColor(android.graphics.Color.TRANSPARENT);
    activity.getWindow().setNavigationBarColor(android.graphics.Color.TRANSPARENT);

 else 
    activity.getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    activity.getWindow().setNavigationBarColor(android.graphics.Color.TRANSPARENT);


const parent = activity.findViewById(android.R.id.content);
for (let i = 0; i < parent.getChildCount(); i++) 
    const childView = parent.getChildAt(i);
    if (childView instanceof android.view.ViewGroup) 
        childView.setFitsSystemWindows(true);
        childView.setClipToPadding(true);
    


);

然后为了增加导航栏的透明度,我遵循this 并将其添加到上面 main.ts 文件的第 24 行。 activity.getWindow().addFlags(android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

现在请注意,还有我们必须尊重的 styles.xml 文件,所以我的 styles.xml 文件 (App_Resources\Android\src\main\res\values\styles.xml) 如下所示:

    <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

<!-- theme to use FOR launch screen-->
<style name="LaunchScreenThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="toolbarStyle">@style/NativeScriptToolbarStyle</item>
    <item name="colorPrimary">@color/ns_primary</item>
    <item name="colorPrimaryDark">@color/ns_primaryDark</item>
    <item name="colorAccent">@color/ns_accent</item>
    <item name="android:windowBackground">@drawable/splash_screen</item>
    <item name="android:statusBarColor">@color/transparent</item>
</style>

<style name="LaunchScreenTheme" parent="LaunchScreenThemeBase"></style>

<!-- theme to use AFTER launch screen is loaded-->
<style name="AppThemeBase" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="toolbarStyle">@style/NativeScriptToolbarStyle</item>
    <item name="colorPrimary">@color/ns_primary</item>
    <item name="colorPrimaryDark">@color/ns_primaryDark</item>
    <item name="colorAccent">@color/ns_accent</item>
    <item name="android:statusBarColor">@color/transparent</item>
    <item name="android:navigationBarColor">@color/transparent</item>

    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:windowTranslucentNavigation">false</item>
</style>

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

<!-- theme for action-bar -->
<style name="NativeScriptToolbarStyleBase" parent="Widget.AppCompat.Toolbar">
    <item name="android:background">@color/transparent</item>
    <item name="theme">@color/transparent</item>
    <item name="popupTheme">@color/transparent</item>
</style>

<style name="NativeScriptToolbarStyle" parent="NativeScriptToolbarStyleBase"></style>

花了我大约 2-3 天的时间才弄明白,希望这会有所帮助

【讨论】:

【参考方案12】:

来自 Android R

fun Activity.setTransparentStatusBar() 
    WindowCompat.setDecorFitsSystemWindows(window, false)
    window.statusBarColor = Color.TRANSPARENT
    window.navigationBarColor = Color.TRANSPARENT

就是这样

【讨论】:

以上是关于棒棒糖上完全透明的状态栏和导航栏的主要内容,如果未能解决你的问题,请参考以下文章

Android 沉浸式/透明式状态栏、导航栏

如何让 Flutter 应用在​​ android 导航栏后面绘制并使导航栏完全透明?

状态栏、导航栏、PopupWindow的使用

Android透明状态栏和沉浸式的实现

如何添加覆盖所有其他视图(包括导航栏和状态栏)的暗屏?

在状态栏和导航栏之间添加图片