我可以仅为状态栏设置FLAG_LAYOUT_NO_LIMITS标志吗?

70

我需要使状态栏透明。我正在使用getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)实现我想要的状态栏效果。但它也会影响导航栏:导航栏也变成了透明的,getWindow().setNavigationBarColor(Color.BLACK)无效。

有没有办法只使状态栏透明而不影响导航栏?


23
你找到解决方法了吗? - Ivan Fork
1
我也对解决方案很感兴趣,但是到目前为止我还没有找到任何有用的信息... - bazinac
请问您能否发布您当前和期望的行为的图片? - Ferdous Ahamed
13个回答

38

这对我起作用

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
)

样式.xml

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

v21\styles.xml

<style name="TranslucentStatusBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowDrawsSystemBarBackgrounds">false</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

状态栏会是透明或半透明的,导航栏则不会

希望这可以帮到你!


完美而简洁的答案。赞! - Shashank Degloorkar
终于!一个准确而原创的答案。 - BST Kaal
1
防止滚动视图滚动。 - Karsh Soni
4
在三星SM-T295 (Android 10, One UI 2.1) 上无法使用该方法。导航栏会出现在内容的顶部。 - Alexey Timokhin
这没有效果!我无法在导航栏上设置浅色主题。只有带有黑色半透明背景的白色按钮。 - AndreasReiff

21

使用mikepenz的评论,我精确地编写了以下代码(已转换为Kotlin)。

// at AppCompatActivity, min SDK is 16, I tested api 25
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
    }
    if (Build.VERSION.SDK_INT >= 19) {
        window.decorView.systemUiVisibility =
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    }
    if (Build.VERSION.SDK_INT >= 21) {
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.statusBarColor = Color.TRANSPARENT
    }

    setContentView(R.layout.activity_main)
}

1
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 更好(我需要这样做来保持状态栏图标为黑色而不是白色) - hmac

16

首先,将styles.xml定义为以下内容 -

styles.xml

向下滚动以查看最终结果的外观。

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
</style>

请勿添加以下行

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

在具有EditText的对话框上显示软键盘时,添加此行不会将布局向上移动

然后像这样在v21 v23样式中覆盖此样式-

v21/styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>

v23/styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>

活动代码 - Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    window.setFlags(
            LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            LayoutParams.FLAG_LAYOUT_NO_LIMITS
    )
    setContentView(R.layout.YOUR_LAYOUT_RESOURCE_ID)
    .
    .
.
}

活动代码 - Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(
            LayoutParams.FLAG_LAYOUT_NO_LIMITS,
            LayoutParams.FLAG_LAYOUT_NO_LIMITS
    )
    setContentView(R.layout.YOUR_LAYOUT_RESOURCE_ID)
    .
    .
    .
}

最终结果最终结果


1
它对我起作用了。此外,我所要做的就是根据状态栏调整我的布局顶部。非常感谢 :) - Aanal Shah
@NikunjPatel 它对我(和其他4个人)有效。你能把你的代码发布为一个问题,说明它在哪里不能工作,并将链接发送到这里吗?也许我可以帮忙。 - Rajkiran
5
几乎所有的设备都能正常工作,但它在运行Android 10和One UI 2.0的三星Note 10+上无法正常工作。导航栏仍然透明并覆盖应用程序内容。 - phamxuanlu
FLAG_LAYOUT_NO_LIMITS 隐藏 actionbar - famfamfam

11
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

这会隐藏我的工具栏吗? - famfamfam

5
fun showTransparentStatusbar() {
        activity!!.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN)
    }


    fun removeStatusbarFlags() {
        activity!!.window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
    }

谢谢,只有这个方法对我有效。简明扼要,不需要额外的信息。 - smoothumut
它使状态栏消失。 - Alexey Timokhin

4

试试这个,你不会后悔的。

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

1
你是对的。我尝试了它,没有后悔过。 - Shunan
这会隐藏我的工具栏吗? - famfamfam

3
您可以使用以下方式来隐藏状态栏和导航栏。
WindowManager.LayoutParams attributes = getWindow().getAttributes();
    attributes.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
    getWindow().setAttributes(attributes);

如果需要再次显示navigationBar,请使用以下方法:

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

    }

对我来说,颜色是灰色的,也许你可以将它强制设置为你的主要颜色。


3
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

对我来说,上面的标志起作用了。导航按钮可见,状态栏和操作栏被隐藏。

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

无法工作。测试设备为Nexus 5。


你解决了吗? - famfamfam
那是3年前的事了。是的,WindowManager.LayoutParams.FLAG_FULLSCREEN适用于Nexus 5。 - Eugene P.

1
我找到了解决方案,兄弟。
<style name="transparent" parent="Theme.AppCompat.Light.NoActionBar">//AppCompat is the key; You can choose any other theme than the light-theme, but stick to AppCompat
    <item name="android:windowTranslucentStatus">false</item>
    <item name="android:windowDrawsSystemBarBackgrounds">false</item>
    //Other styling(optional)
</style>

然后将这个透明的主题应用到你的活动清单中,像这样:
 <activity
      ...
      android:theme="@style/transparent"/>

该解决方案按照描述完成了工作。导航栏是不透明的,并且其下面没有任何内容。 - samurdhilbk
你用的是哪个版本的Android?因为这个程序是为旧的Android 6或7设计的。 - Robokishan

1

对于所有对解决方案/黑客感兴趣的人,因为Android API在这方面非常糟糕。不要使用任何系统窗口标志,将负边距设置为您布局的根,并使用setStatusBarColor使您的StatusBar透明。

statusBarHeight = getResources().getDimensionPixelSize(R.dimen.margin_24dp);
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId != 0) {
    statusBarHeight = getResources().getDimensionPixelSize(resourceId);
}

FrameLayout.LayoutParams rootParams = (FrameLayout.LayoutParams) binding.getRoot().getLayoutParams();
rootParams.topMargin = -statusBarHeight;
binding.getRoot().setLayoutParams(rootParams);

getWindow().setStatusBarColor(getResources().getColor(R.color.transparent));

其中binding.getRoot()当然是您布局的根

结果为

enter image description here


你只需要调整视图的边距,那么如果我有工具栏该怎么办? - famfamfam
你的意思是什么?我设置了布局的根组件的边距。在该布局中,我还有一个工具栏。 - TheJudge

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