清除FLAG_TRANSLUCENT_STATUS标志后,为什么布局会搞乱?

App*_*rew 11 android android-layout android-fragments

我有一个Activity应用程序.它显示一个LoginFragment使状态和导航栏半透明的位置,以便它可以在其后面显示背景图像.但是,登录后,此片段将被另一个需要显示常用固态和导航栏的片段替换.因此,在LoginFragment删除之前,它会取消设置的标记,使条形不透明.

我面临的问题是,在我登录后,具有正常状态和导航栏的片段将其操作栏向下移位.如果我将屏幕旋转到横向然后再回到纵向以强制重新布局,则操作栏会快速回到正确的位置.

状态栏是半透明的.这很好. 状态栏是半透明的. 这很好.

在下一个屏幕上,操作栏向下移动.另外请注意,根据主题,状态栏是黑色的,应该是灰色的. 在下一个屏幕上,操作栏向下移动.

现在,如果我回到第一个屏幕,顶部半透明条形图很好,但整个内容向上移动,在下面留下一个空白的空白区域. 现在,如果我回到第一个屏幕,顶部半透明条形图很好,但整个内容向上移动,在下面留下一个空白的空白区域.

LoginFragment编程方式使条形半透明并恢复它们的代码: -

@Override
public void onResume() {
    super.onResume();
    if (hasTransparentStatusBar()) {
        setStatusBarTranslucent();
    }
}

@Override
public void onPause() {
    if (hasTransparentStatusBar()) {
        setStatusBarOpaque();
    }
    super.onPause();
}

protected boolean hasTransparentStatusBar() {
    return true;
}

protected void setStatusBarTranslucent() {
    if (Build.VERSION.SDK_INT >= 21) {
        Window window = getActivity().getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    }
}

protected void setStatusBarOpaque() {
    if (Build.VERSION.SDK_INT >= 21) {
        Window window = getActivity().getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    }
}
Run Code Online (Sandbox Code Playgroud)

布局xml的活动: -

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.app.MainActivity" >

    <!-- The main content view -->

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->

    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@color/divider"
        android:dividerHeight="0dp"
        android:background="@color/primary"
        />

</android.support.v4.widget.DrawerLayout>
Run Code Online (Sandbox Code Playgroud)

LoginFragment的布局xml: -

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:src="@drawable/logo"
    android:id="@+id/logo"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true" />

<Button
    android:padding="@dimen/default_margin"
    android:text="Login using Facebook"
    android:textColor="@android:color/white"
    android:background="@drawable/com_facebook_button_background"
    android:id="@+id/authButton"
    android:layout_below="@+id/logo"
    android:layout_centerHorizontal="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
Run Code Online (Sandbox Code Playgroud)

tch*_*hap 5

我之前也遇到过同样的问题,所以如果有人偶然发现此问题,则正确的解决方法是设置NO_LIMITS标志:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
Run Code Online (Sandbox Code Playgroud)

  • 我完全不知道为什么,但是我确认这是可行的(设置FLAG_LAYOUT_NO_LIMITS而不是FLAG_TRANSLUCENT_STATUS会使状态栏变为半透明,并且在底部不留空白)。 (2认同)
  • 这会导致具有UI导航栏而不是硬件按钮的设备上的导航栏出现问题(例如Nexus 5X) (2认同)

s.m*_*aks 2

我遇到了类似的问题,看来我们应该在onActivityCreated(Bundle)之前设置窗口标志。我经常使用静态方法来显示我的片段,如下所示:

public class FragmentPlayer extends MediaFragment
{

    public FragmentPlayer()
    {
        // Default public constructor required. 
    }

    public static void show(@NonNull Activity activity, boolean compact)
    {
        boolean isOrientationPortrait = UiHelper.isOrientationPortrait(activity);
        setupWindow(activity.getWindow(), isOrientationPortrait, compact);

        FragmentManager fragmentManager = activity.getFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        FragmentPlayer newFragment = FragmentPlayer.getInstance(compact);
        transaction.replace(R.id.fragment_player, newFragment);
        transaction.commit();
    }

    private static void setupWindow(@NonNull Window window, final boolean isOrientationPortrait,
                                    final boolean compact)
    {
        if (compact)
        {
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
        else
        {
            if (isOrientationPortrait)
            {
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
            else
            {
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            }
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我将所有窗口初始化从onCreateActivity(Bundle)静态方法移至静态方法setupWindow(Window, boolean, boolean),现在一切正常。

仍然不知道为什么从 调用这些方法时布局实际上会变得混乱onCreateActivity(Bundle),但这就是开始。

编辑 1:哦,别忘了设置您的Window输入Activity.onCreate(Bundle)以正确处理屏幕旋转!