Android,如何正确制作透明状态栏

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23859501/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:32:38  来源:igfitidea点击:

Android, How to make a transparent status bar correctly

androidandroid-layoutuser-experience

提问by Sandak

I'm trying to make transparent status bar on Android 4.4+ I know how to make it transparent by defining my own style:

我正在尝试在 Android 4.4+ 上制作透明状态栏我知道如何通过定义自己的样式来使其透明:

<style name="Theme.MyTheme" parent="Theme.MyTheme.Base">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowTranslucentNavigation">true</item> </style>

I found here: https://stackoverflow.com/a/20573595/2633630

我在这里找到:https: //stackoverflow.com/a/20573595/2633630

The problem is that when status bar is transparent, it doesn't match the color of the action bar and the activity in the background is seen: transparent status bar error

问题是当状态栏透明时,它与操作栏的颜色不匹配,并且看到了后台的活动: 透明状态栏错误

So I found that I can use android:fitsSystemWindows="true" and android:clipToPadding="false" in my layout that I found here http://mindofaandroiddev.wordpress.com/2013/12/28/making-the-status-bar-and-navigation-bar-transparent-with-a-listview-on-android-4-4-kitkat/

所以我发现我可以在我在这里找到的布局中使用 android:fitsSystemWindows="true" 和 android:clipToPadding="false" http://mindofaandroiddev.wordpress.com/2013/12/28/making-the-status -bar-and-navigation-bar-transparent-with-a-listview-on-android-4-4-kitkat/

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_darkRed"
android:fitsSystemWindows="true"
android:clipToPadding="false"    
tools:context="com.sandak.......">

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"> 
....

That solves the top problem with transparent status bar and looks ok.. Unfortunately there is problem at the bottom on the "nav bar" with the system buttons, which is red and not transparent as I wish: enter image description here

这解决了透明状态栏的首要问题,看起来不错..不幸的是,“导航栏”底部的系统按钮有问题,它是红色的,而不是我希望的透明: 在此处输入图片说明

I was trying all possible variants to achieve working result, but I cannot figure out how to solve it. My only working solution is set top padding about 60dp to the root element. But this solution is ugly and on different devices can look different and may be not working.

我正在尝试所有可能的变体来实现工作结果,但我不知道如何解决它。我唯一的工作解决方案是将顶部填充设置为根元素大约 60dp。但是这个解决方案很丑陋,在不同的设备上可能看起来不同并且可能不起作用。

I found a few applications on Google Play which working Ok with transparent background, so I'm curious how they make it work.

我在 Google Play 上发现了一些在透明背景下运行正常的应用程序,所以我很好奇它们是如何工作的。

For example: https://play.google.com/store/apps/details?id=com.trelloand few others

例如:https: //play.google.com/store/apps/details?id=com.trello和其他一些

采纳答案by Sandak

//UPDATE:
Ok, this is quite old answer. Now you can use Material theme to handle this and it is pretty easy. Just set target api to 21+, use support library if you need to and create theme with material theme where you can specify status bar color directly

//更新:
好的,这是很老的答案。现在您可以使用 Material 主题来处理这个问题,这非常容易。只需将目标 api 设置为 21+,如果需要,请使用支持库并使用材质主题创建主题,您可以直接指定状态栏颜色

<style name="AppTheme"
        parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- colorPrimary is used for the default action bar background -->
        <item name="colorPrimary">@color/color_primary</item>

        <!-- colorPrimaryDark is used for the status bar -->
        <item name="colorPrimaryDark">@color/color_primary_dark</item>

        <!-- colorAccent is used as the default value for colorControlActivated
             which is used to tint widgets -->
        <item name="colorAccent">@color/accent_orange</item>
    </style>

=======================================================================

================================================== ======================

OLD ANSWER:

旧答案:

Ok, It seems that I solve my problem. It is not the best and clearest solution, but it is working solution. If anybody in the future will find out better and more clear solution, please let me know and I will update my answer / or mark your answer as correct one. But for now, I have no better solution than this little hack:

好的,看来我解决了我的问题。这不是最好和最清晰的解决方案,但它是可行的解决方案。如果将来有人会找到更好,更清晰的解决方案,请告诉我,我会更新我的答案/或将您的答案标记为正确的答案。但就目前而言,我没有比这个小技巧更好的解决方案:

The root element of the layout has to be RelativeLayout. Than should follow your main layout like ScrollView or any kind of others layouts, it doesn't matter. At the end before closing Relative Layout tag follows empty LinearLayout which has set the same background as your Action Bar and fixed height (height of Status Bar).

布局的根元素必须是 RelativeLayout。应该遵循您的主要布局,如 ScrollView 或任何其他布局,这无关紧要。在关闭相对布局标签之前的最后,空的 LinearLayout 设置了与您的操作栏相同的背景和固定高度(状态栏的高度)。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sandak....">
<ScrollView
    android:fitsSystemWindows="true"
    android:clipToPadding="false"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
.... all your main views etc..
</ScrollView>
<LinearLayout
        android:id="@+id/statusBarBackgroundLinearLayout"
        android:layout_width="match_parent"
        android:orientation="horizontal"
        android:layout_height="30dp"
        android:background="@color/background_darkRed"
        android:clickable="false"
        android:focusable="false">
     </LinearLayout>
</RelativeLayout>

Ok then you have to set in code the same Linear Layout height as the Status bar has:

好的,那么您必须在代码中设置与状态栏相同的线性布局高度:

private void setStatusBarBackground(View rootView) {
        setStatusBarLayout(rootView);
        statusBarHeight = getStatusBarHeight();
        setStatusBarLayoutHeight(statusBarHeight);
    }

    private void setStatusBarLayout(View rootView){
        statusBarBackgroundLinearLayout = (LinearLayout) rootView.findViewById(R.id.statusBarBackgroundLinearLayout);
        if (isPreKitkatDevice()) {
            hideStatusBarLayout();
        }
    }

    private int getStatusBarHeight() {
        int statusBarHeight = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

    private boolean isPreKitkatDevice(){
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT;
    }

    private void hideStatusBarLayout(){
        statusBarBackgroundLinearLayout.setVisibility(View.INVISIBLE);
    }        

    private void setStatusBarLayoutHeight(int height){
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) statusBarBackgroundLinearLayout.getLayoutParams();
        layoutParams.height = height;
    }

And then just call setStatusBarBackground in your onCreate() method. This is working solution for all different kind of deviceas. For pre KitKat devices where transparent background is not allowed you have to hide the Linear Layout.

然后只需在您的 onCreate() 方法中调用 setStatusBarBackground 。这是适用于所有不同类型设备的工作解决方案。对于不允许透明背景的 Pre KitKat 设备,您必须隐藏线性布局。