fitsSystemWindows上的Fragment,Activity和DrawerLayout组合 [英] fitsSystemWindows on Fragment, Activity and DrawerLayout combination

查看:109
本文介绍了fitsSystemWindows上的Fragment,Activity和DrawerLayout组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

活动布局具有DrawerLayout,其中FrameLayout作为Fragment的内容,而LinearLayout由抽屉打开和关闭.用于内容的片段具有带有fitsSystemWindows标志的FrameLayoutToolbar.

The activity layout has a DrawerLayout with a FrameLayout as content to Fragment and a LinearLayout to be opened and closed by drawer. The fragment used on content has a FrameLayout with fitsSystemWindows flag and a Toolbar.

如果我在onCreate()处插入片段,则所有片段均按预期发生,FrameLayout从位置0开始,而Toolbar从状态栏下方开始.但是在onCreate()之外,相同的代码会失败,fitsSystemWindows不能与FrameLayout一起使用.

If I insert the fragment at onCreate() all occurs as expected, the FrameLayout starts on position 0 and the Toolbar starts below the statusbar. But outside the onCreate() the same code fails, the fitsSystemWindows not works with FrameLayout.

重要的一点是,我需要在Fragment而不是Activity上使用ToolbarfitsSystemWindows标志.

An important point, I need the Toolbar and fitsSystemWindows flag on Fragment and not on Activity.

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

How to get the same behavior seen at onCreate() moment?

主要活动

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>

片段

public class MainFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
                                                @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment, container, false);
    }

}

片段布局:

<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>

示例

要打开的LinearLayout为红色.带有fitsSystemWindows标志的FrameLayout为绿色,工具栏为蓝色,青色视图始终处于工作状态,它需要从y位置0开始.期望是第一次的绿色和蓝色,但是第二次是唯一的蓝色.

Example

The LinearLayout to be opened is in red. The FrameLayout with the fitsSystemWindows flag is in green and the toolbar is in blue, the cyan view is working all the time, it need start at y position 0. The expected is Green and blue like the first time, but in the second time the blue is the unique viewed.

推荐答案

因此,问题是,当内容更改时,系统将不再将这些插图分配给视图层次结构.

So, the problem is, that the when the content is being changed, system will no longer dispatch those insets to the view hierarchy.

可以使用 ViewCompat.requestApplyInsets(View) API.这将迫使系统再次调度WindowInsets.

要求执行View.onApplyWindowInsets(WindowInsets)的新调度.如果有的话,它会退回到View.requestFitSystemWindows().

Ask that a new dispatch of View.onApplyWindowInsets(WindowInsets) be performed. This falls back to View.requestFitSystemWindows() where available.

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

So, in your example performing this changes would result in expected behavior:



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

这篇关于fitsSystemWindows上的Fragment,Activity和DrawerLayout组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆