Android 在片段、活动和抽屉布局组合上安装系统窗口 问题

Android 在片段、活动和抽屉布局组合上安装系统窗口 问题,android,android-layout,android-fragments,navigation-drawer,windowinsets,Android,Android Layout,Android Fragments,Navigation Drawer,Windowinsets,活动布局有一个DrawerLayout,其中FrameLayout作为Fragment的内容,还有一个LinearLayout由抽屉打开和关闭。内容上使用的片段具有框架布局,带有fitsSystemWindows标志和工具栏 如果我在onCreate()处插入片段,则FrameLayout从位置0开始,而工具栏从状态栏下方开始。但是在onCreate()之外,相同的代码失败,fitsystemwindows不能使用FrameLayout 重要的一点是,我需要工具栏和fitsystemwindow

活动布局有一个
DrawerLayout
,其中
FrameLayout
作为
Fragment
的内容,还有一个
LinearLayout
由抽屉打开和关闭。内容上使用的片段具有
框架布局
,带有
fitsSystemWindows
标志和
工具栏

如果我在
onCreate()
处插入片段,则
FrameLayout
从位置0开始,而
工具栏从状态栏下方开始。但是在
onCreate()
之外,相同的代码失败,
fitsystemwindows
不能使用
FrameLayout

重要的一点是,我需要
工具栏
fitsystemwindows
标志,它位于
片段
上,而不是
活动

如何获得在
onCreate()时刻看到的相同行为

代码 主要活动

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            window.setStatusBarColor(Color.TRANSPARENT);
        }

        setContentView(R.layout.activity);

        findViewById(R.id.item).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Out of onCreate fails
                replaceFragment();
            }
        });

        // With onCreate all OK
        replaceFragment();
    }

    private void replaceFragment() {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.content, new MainFragment())
                .commit();
    }

}
主布局

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer"
    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">

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_width="256dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#ff0000"
        android:orientation="vertical"
        tools:layout_gravity="">

        <View
            android:layout_width="match_parent"
            android:layout_height="168dp"
            android:layout_marginBottom="16dp"
            android:background="#00ffff"/>

        <TextView
            android:id="@+id/item"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:background="#ff00ff"
            android:gravity="center"
            android:text="Click me"/>

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>
片段布局:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00ff00"
        android:fitsSystemWindows="true">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="56dp"
            android:background="#0000ff"/>

    </FrameLayout>

</RelativeLayout>


因此,问题是,当内容被更改时,系统将不再将这些插入分派到视图层次结构中

这可以通过API轻松解决。这将迫使系统再次分派
WindowInsets

要求执行新的
View.onApplyWindowInsets(WindowInsets)
分派。在可用的情况下,可返回到
View.requestFitSystemWindows()

因此,在您的示例中,执行此更改将导致预期行为:


    private void replaceFragment() {
      getSupportFragmentManager().beginTransaction()
          .replace(R.id.content, new MainFragment())
          // NOTE, we are performing `commitNow()` instead of ordinary `commit()`,
          // Because we want this commit to happen sychronously/immediately
          .commitNow();

      // Ask the framework to dispatch window insets once more to the root of your view hierarchy
      ViewCompat.requestApplyInsets(findViewById(R.id.drawer));
    }

你能解决它吗?@PaulWoitaschek不幸的是没有。我做了一项工作,获得了状态栏的高度,并将其设置为工具栏的上边距

    private void replaceFragment() {
      getSupportFragmentManager().beginTransaction()
          .replace(R.id.content, new MainFragment())
          // NOTE, we are performing `commitNow()` instead of ordinary `commit()`,
          // Because we want this commit to happen sychronously/immediately
          .commitNow();

      // Ask the framework to dispatch window insets once more to the root of your view hierarchy
      ViewCompat.requestApplyInsets(findViewById(R.id.drawer));
    }