19

NavigationDrawerFragment (および layout/fragment_navigation_drawer.xml) の代わりにToolbarv7.app.ActionBarDrawerToggle、およびNavigationViewを使用する Android Studio の Navigation Drawer Activity プロジェクト テンプレートを改良しました。

ドロワーが閉じているときのイマーシブ スティッキーのナビゲーション ドロワー

それは完全に機能しています。それから、私はさらに行きます。Navigation Drawer プロジェクトをイマーシブ スティッキー(フル スクリーン) モードで使用しています。

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if (hasFocus) {
        View decorationView = getWindow().getDecorView();
        decorationView.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {

    ...

    toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayHomeAsUpEnabled(true);

    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawerToggle = new ActionBarDrawerToggle(
            this,
            drawerLayout,
            R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */
            R.string.navigation_drawer_close  /* "close drawer" description for accessibility */
    ) {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);

            invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);

            invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
        }
    };
    drawerLayout.setDrawerListener(drawerToggle);

    navigationView = (NavigationView) findViewById(R.id.navigation_view);
    navigationView.setNavigationItemSelectedListener(this);
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    drawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    drawerToggle.onConfigurationChanged(newConfig);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (drawerToggle.onOptionsItemSelected(item)) {
        return true;
    }

    ...

}

問題が発生しました。ステータス バー (上部) とナビゲーション バー (下部) から派生した、NavigationView の重なり合った影の効果のバンドは静止したままです。

ナビゲーションドロワーを開いたとき

ナビゲーション ドロワーが開いていて、スティッキー ステータスとナビゲーション バーが表示されている場合

どうすればそれらを取り除くことができますか?

v7.app.ActionBarDrawerToggle や Android の NavigationView のソースを見直してみましたがだめでした。


更新しました:

@lcw_gg のアドバイスに感謝します。ステータス バーの影を完全に取り除きました (ナビゲーション バーの影は残ります)。つまり、レイアウト xml にandroid:windowFullscreen属性を設定します。true

しかし、これを Java コードで実行したいと考えています。私は方法を見つけましたが、おそらくそれはxmlの方法と同等です:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREENこれを行うと、これら 2 つのフラグ --とView.SYSTEM_UI_FLAG_FULLSCREEN-- をに設定する必要がなくなりますdecorationView

ナビゲーションバーの影が残っているのにステータスバーの影が消えた

それでも、ナビゲーション バーの影を取り除く方法が見つかりません。解決策を待っています。

4

4 に答える 4

27

ついに、私はそれを作りました。

ソリューションは、オブジェクトFLAG_LAYOUT_NO_LIMITSと一緒に使用しています。FLAG_FULLSCREENandroid.view.Window

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

これで両方の影が完全に取り除かれました。

ここに画像の説明を入力

lcw_gg のコメントは、android.view.Window. 彼に感謝します。


Android 11 のアップデート

残念ながら、携帯電話を Android 11 (API-30) にアップデートすると、問題が再発します。上記の解決策はもはや効果的ではありません。別の解決策は、@AllanVeloso の答えを使用したものですapp:insetForeground="@null"

そして、新しい解決策も得ました。脱ぐだけSYSTEM_UI_FLAG_LAYOUT_STABLEです。これSYSTEM_UI_FLAG_LAYOUT_STABLEが影の効果の根本的な原因です。

Google Developer または StackOverflow に関する私の謙虚な調査では、フラグは常にSYSTEM_UI_FLAG_LAYOUT_FULLSCREENand/orと一緒に使用するように説明されていますがSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONそれ自体についての正確な説明SYSTEM_UI_FLAG_LAYOUT_STABLEは次のとおりです。

これは、そこに表示されるインセットが、アプリケーションが連続状態として予期できる最悪のケースを常に表すことを意味します。

だから私は他の2つでそれを自動的に使用しました。しかし、それがこの問題の根源でした。削除するSYSTEM_UI_FLAG_LAYOUT_STABLEだけでこの問題は解決しました (Android 10 以前でも)。

これらの没入型 FLAG の非推奨

ご存じのとおり、これらView.SYSTEM_UI_FLAG_*は Android 11 (API-30) から廃止されました。

以下のように使用します。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    WindowInsetsController windowInsetsController = decorView.getWindowInsetsController();
    windowInsetsController.setSystemBarsBehavior(
            WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    );
    windowInsetsController.hide(
            WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars()
    );

    window.setDecorFitsSystemWindows(false);
} else {
    (...)
}

Googleの人々(Chris Banesなど)が説明したように、Window.setDecorFitsSystemWindows(false)とほぼ同等でSYSTEM_UI_FLAG_LAYOUT_FULLSCREENあり、 とSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION結合しSYSTEM_UI_FLAG_LAYOUT_STABLEます。少なくとも影の効果については問題ありません。

于 2015-10-06T13:44:24.397 に答える
1

上記と同じ問題を抱えているが、システム ステータス バーを常に表示したい (したがって を使用しないWindowManager.LayoutParams.FLAG_FULLSCREEN) 場合は、ロリポップのステータス バーの下に奇妙なコンテンツが忍び寄るのを防ぐために、追加の作業を行う必要があります。テストしたとき、キットカットの問題に気づきませんでした。

私は 2 つのナビゲーション ドロワー (左と右) を使用していましたが、奇妙なことに左の 1 つだけが下に影を落としていました。受け入れられた回答に示されているように適用するWindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITSと、影は消えましたが、ステータスバーの下にコンテンツが忍び寄り、ステータスバーの上にナビゲーションドロワーが描画されました。デバイスのベゼルまでずっと。

これを修正するには、v21 の styles.xml でテーマを上書きして以下を含める必要があります。

<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:statusBarColor">@color/colorPrimaryDark</item>

これにより、コンテンツがステータス バーの下に戻り、ナビゲーション ドロワーがステータス バーの上に描画されなくなります。

上記の v21 スタイルのエントリに加えて、アクティビティ コードは次のようになります。

// Fixes bottom navbar shadows from appearing on side navigation drawers
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    WindowManager.LayoutParams attributes = getWindow().getAttributes();
    attributes.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
    getWindow().setAttributes(attributes);
}
于 2016-09-30T19:23:27.110 に答える