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

时间:2015-09-10 20:11:57

标签: android android-layout android-fragments

我有一个Activity应用程序。它显示 bool mainPivotLoaded = false; private ObservableCollection<MyItem> myItemCollection = new ObservableCollection<MyItem>(); public MainPage() { InitializeComponent(); DataContext = App.ViewModel; LLS_MyItems.ItemsSource = myItemCollection; for (int x = 0; x < 20; x++) { MyItem i = new MyItem(); i.Title = "Hello" + x.ToString(); myItemCollection.Add(i); } DispatcherTimer dt = new System.Windows.Threading.DispatcherTimer(); dt.Tick += new EventHandler(Dt_Tick); dt.Interval = new TimeSpan(0, 0, 0, 1, 0); dt.Start(); } private void Dt_Tick(object sender, EventArgs e) { if (myItemCollection.Count > 0 && mainPivotLoaded) myItemCollection.RemoveAt(0); } private void MainPivot_Loaded(object sender, RoutedEventArgs e) { mainPivotLoaded = true; } class MyItem : INotifyPropertyChanged { public string Title { get; set; } public PointCollection PC { get; set; } public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(String propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public MyItem() { PC = new PointCollection(); PC.Add(new Point(1, 1)); PC.Add(new Point(10, 10)); } } ,使状态和导航条变为半透明,以便它可以显示背后的背景图像。但是,登录后,此片段将被另一个需要显示常用固态和导航栏的片段替换。因此,在删除LoginFragment之前,它会取消设置的标记,以使条形不透明。

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

状态栏为半透明时。这非常好。 When Status bar is translucent. This is perfectly fine.

在下一个屏幕上,操作栏向下移动。另请注意,根据主题,状态栏是黑色的,应该是灰色的。 On next screen Action bar is displaced downwards.

现在,如果我回到第一个屏幕,顶部半透明条形图很好,但整个内容向上移动,在下面留下一个空白空白。 Now if I go back to first screen, the top translucent bar is fine, but the whole content is shifted upwards, leaving a blank white space below.

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

LoginFragment

布局xml活动: -

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

<?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> 的布局xml: -

LoginFragment

4 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分: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);
            }
        }
    }   
}

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

仍然不知道为什么布局实际上从onCreateActivity(Bundle)调用这些方法时搞砸了,但这是开始。

编辑1:哦,不要忘记在Window设置Activity.onCreate(Bundle)以正确处理屏幕旋转!

答案 2 :(得分:1)

在窗口上为透明状态栏设置所有这些标志之后。 调用w.getDecorView().requestApplyInsets()可解决此问题。 在评论中感谢@Froyo

答案 3 :(得分:-1)

我尝试了解决这个问题的所有可能性并找到了明确的解决方案。 首先做youtube video中显示的内容 并将android:fitsSystemWindows="true"添加到xml中的android.support.v7.widget.Toolbar