透明状态栏 - Android 4.4(奇巧巧克力)之前

27

我知道在Android 4.4 KitKat (API 19)中,可以使状态栏透明。

但例如Go Launcher Ex等应用程序也有选项来使其透明,并且它也适用于预先的KitKat版本,对于我(Android 4.3 (Jelly Bean))和我的Android 4.0 (Ice Cream Sandwich)设备也有效。

我不需要root或任何特殊权限来使用它。

下载Go Launcher Ex并自行尝试。如果需要root,我也可以接受。

但是他们是如何做到的呢? 如何在pre-KitKat设备上使Android的状态栏半透明?

---为了澄清事情---

我不是在谈论操作栏;我指的是状态栏(通知栏)!

看这些示例图片:

(注意,这是我使用的Stock Galaxy Note 3Android 4.3Go Launcher Ex拍摄的。)

(同样的方法也适用于我的Galaxy S2Android 4.0。)

没有透明状态栏:

Without transparent bar (default)

启用透明状态栏:

(我希望在4.4之前(API 19)的设备上实现此功能)

With transparent status bar (what I want to achieve on pre 4.4 devices in any way


你能提供一张你想要实现的图片吗? - Austyn Mahoney
@AustynMahoney 当然,我现在会添加一个。 - bricklore
@AustynMahoney添加了图片,希望它们能够帮助识别我的问题 :) - bricklore
1
@AbdEl-RahmanEl-Tamawy,我认为我的问题并不那么混乱或模糊,请重新阅读它 - (我想让它透明 - 请参见我帖子中的第二张图片) - bricklore
1
@AustynMahoney他们不这样做。要做到那几乎是不可能的,尽管如此,您可以使用一些系统工具(在开发者设置中)验证它们是否处于全屏模式。 - bricklore
显示剩余6条评论
2个回答

21
我发现如何在运行至少Android 4.0的三星和索尼设备上获得透明状态栏。
首先,让我解释一下为什么这在大多数设备上不可能: 从 Android 的官方角度来看,在 KitKat(4.4)之前是没有解决方案的。 但是,像三星和索尼这样的设备制造商已经在其专有软件中添加了此选项。
三星使用他们自己的 Android 版本,称为 TouchWiz,而索尼也在使用自己的系统。 他们拥有一个关于 View 类的自己的实现,其中包含额外的 SYSTEM_UI_ 标志,可以在 4.4 之前的设备上启用透明状态栏!
但是,证明这些标志存在并访问它们的唯一方法是使用反射。 以下是我的解决方案:
解析视图标志:
int ResolveTransparentStatusBarFlag()
{
    String[] libs = getPackageManager().getSystemSharedLibraryNames();
    String reflect = null;

    if (libs == null)
        return 0;

    for (String lib : libs)
    {
        if (lib.equals("touchwiz"))
            reflect = "SYSTEM_UI_FLAG_TRANSPARENT_BACKGROUND";
        else if (lib.startsWith("com.sonyericsson.navigationbar"))
            reflect = "SYSTEM_UI_FLAG_TRANSPARENT";
    }

    if (reflect == null)
        return 0;

    try
    {
        Field field = View.class.getField(reflect);
        if (field.getType() == Integer.TYPE)
            return field.getInt(null);
    }
    catch (Exception e)
    {
    }

    return 0;
}

将其应用于您的Window(任何Activity内部的decorView):

void ApplyTransparentStatusBar()
{
    Window window = getWindow();
    if (window != null)
    {
        View decor = window.getDecorView();
        if (decor != null)
            decor.setSystemUiVisibility(ResolveTransparentStatusBarFlag());
    }
}

我认为可能有其他设备制造商实现了这样的标志,但我只能找到这两个(因为我拥有三星和索尼设备)


不错的发现。你是怎么想到的? - Juan Andrés Diana
4
我反编译了拥有该功能的三星和索尼的启动器,然后发现那些标记是存在的。 - bricklore
1
我猜你已经反编译了Nova Launcher,除此之外(或者是代替)还有Samsung和Sony的Launcher……你不需要搜索系统库,只需要使用反射测试两个标志会更直接,而且可能更快,因为通过PackageManager调用 tend to be slow (getSystemSharedLibraryNames)。 - Kevin TeslaCoil
然而,Google Play版设备将具有View SYSTEM UI标志,但它们不会起作用。这些设备将没有共享库。Nova检查库以在不支持的设备上禁用该选项。 - Kevin TeslaCoil
谢谢,我会看看 Nova 并尝试改进答案。 - bricklore
显示剩余2条评论

2

请使用这个。 :)

在super()之后、set content之前使用。

if (Build.VERSION.SDK_INT >= 19)
{
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21)
{
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
}

if (Build.VERSION.SDK_INT >= 21)
{
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
    getWindow().setStatusBarColor(Color.TRANSPARENT);
}


public static void setWindowFlag(Activity activity, final int bits, boolean state)
{
    Window win = activity.getWindow();
    WindowManager.LayoutParams winParams = win.getAttributes();

    if (state)
     {
        winParams.flags |= bits;
    }
     else
     {
        winParams.flags &= ~bits;
    }
}

工作正常 - Maravilho Singa

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