4

Problem

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.

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.

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

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

Code

Main Activity

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

}

Main Layout

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

Fragment

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

}

Fragment layout:

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

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.

enter image description here

4

1 に答える 1

5

したがって、問題は、コンテンツが変更されているときに、システムがそれらのインセットをビュー階層にディスパッチしなくなることです。

ViewCompat.requestApplyInsets(View)これは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));
    }

ここに画像の説明を入力

于 2017-03-27T20:27:54.270 に答える