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

16

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

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

我在这里找到了解决方法:https://dev59.com/UmIj5IYBdhLWcg3whFe4#20573595

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

transparent status bar error

所以我发现我可以在我的布局中使用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"> 
....

这解决了透明状态栏的顶部问题并且看起来还不错。不幸的是,在系统按钮处(“导航栏”底部)存在问题,它是红色的,而不是我希望的透明: enter image description here

我尝试了所有可能的变体,但无法解决它。我的唯一有效解决方案是在根元素中设置大约60dp的顶部填充。但是这个解决方案很丑陋,在不同的设备上可能看起来不同,也可能不起作用。

我在Google Play上找到了一些可透明背景运行良好的应用程序,因此我很好奇它们是如何实现的。

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


当我像你一样将android:windowTranslucentStatus/Navigation设置为true时,背景只是半透明的。你有没有做什么不同的事情来获得你在截图中拥有的漂亮的深色渐变效果? - JMRboosties
1个回答

12

//更新:
好的,这个回答相当古老了。现在你可以使用Material主题来处理这个问题,而且非常容易。只需将目标API设置为21+,如有需要可以使用支持库,并创建具有Material主题的主题,您可以直接指定状态栏颜色。

<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>

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

原回答:

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

布局的根元素必须是RelativeLayout。接下来应该是您的主要布局,如ScrollView或任何其他类型的布局,都无关紧要。在关闭RelativeLayout标记之前,在其后添加一个空的LinearLayout,该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>

那么你需要在代码中设置与状态栏相同高度的线性布局:

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;
    }

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


2
getStatusBarLayout(View v) 没有返回类型?你可以更改该名称。 :) - Rajkiran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接