web-dev-qa-db-ja.com

ナビゲーションドロワーの無効化、フラグメント内のホームボタン/アップインジケーターの切り替え

セットアップ

ContentViewがDrawerLayoutのインスタンスであるアクティビティがあり、アクションバーに引き出しインジケータが表示されたナビゲーション引き出しがあります。アクティビティにはFragmentが含まれています。これをListFragmentと呼びましょう。これにはオプションのリストが含まれています。オプションをクリックすると、ListFragmentDetailFragmentに置き換えます。

Architecture of the application

この時点で、ナビゲーションドロワーインジケーターの代わりに「アップ」ナビゲーションオプションを表示したいと思います。 mDrawerToggle.setDrawerIndicatorEnabled(false)を呼び出して引き出しインジケータを無効にすると、「アップ」アイコンを表示できますが、これは引き出しアイコンを削除するだけです。機能は削除されません。つまり、クリックするとキャレット、ナビゲーションドロワーはまだ開いています。

さらに、これらのサブビューでは、画面の端からドラッグしてドロワーを開くことを無効にします。 setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)を呼び出してこれを試しましたが、この機能を無効にしていないようです。

インジケーターがクリックされたときにドロワーが開かないようにActionBarDrawerToggleクラスを拡張しようとしましたが、オーバーライドアクション(「アップ」ナビゲーション)が実行されるだけで、ドロワーそれでも開きます

また、 Android Navigation Drawer imageとフラグメントを使用する場合のUpキャレット)の切り替え の手順も実装しました。ボタンの機能、メニューはまだ開きます(アプリは戻ってナビゲートします-それは単に引き出しも開きます)。

質問

要するに、レイアウトルートがDrawerLayoutである場合にこれらのことを実現する方法はありますか(できればクリーンでエレガントですが、この時点ではハッキーに取り組みます)。

  1. 引き出しインジケータを「上」のキャレットに置き換えます(mDrawerToggle.setDrawerIndicatorEnabled(false))で一時的に実行可能)
  2. キャレットがクリックされたときにドロワーが開かないようにし、代わりに自分の「アップ」機能でオーバーライドします
  3. 画面の端からドラッグしたときに引き出しが開かないようにします。

編集

ActionBarDrawerToggle AND onOptionsItemSelectedをオーバーライドすると、キャレットをクリックしてもメニューが開かないようです。ただし、Edgeからドラッグすると開きます。助けて!

46
Catherine

これは私がたどり着いた解決策の一部にすぎませんが、このバグを把握するのは非常に困難であったため、後世のためにここに残しています。

これは、ナビゲーションドロワーのListViewの定義方法です。

_<ListView
    Android:id="@+id/listview_drawer"
    Android:layout_width="240dp"
    Android:layout_height="match_parent"
    Android:layout_gravity="start|bottom"
    Android:background="#111"
    Android:choiceMode="singleChoice"
    Android:divider="@Android:color/transparent"
    Android:dividerHeight="0dp" />
_

setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)を呼び出した後でも、引き出しをスライドして開くことができました。

ただし、_layout_gravity_を_"start"_に変更すると、この問題は解決されたようです。

ナビゲーションドロワー専用のサンプルアプリでこの問題を再現することができたので、私の状況に固有ではない再現可能な問題のように見えます。

22
Catherine

ショートコード

public void setDrawerState(boolean isEnabled) {
    if ( isEnabled ) {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
        drawerToggle.setDrawerIndicatorEnabled(true);
        drawerToggle.syncState();

    }
    else {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        drawerToggle.setDrawerIndicatorEnabled(false);
        drawerToggle.syncState();
    }
}
34
sonida

ソニダの答えに基づいています。 setDrawerIndicatorEnabled(false)を呼び出した後、onNavigateUpはまだ呼び出されていませんでした。そのため、私はそれを呼び出す新しいonClickListenerを作成しました。

public void setDrawerState(boolean isEnabled) {
    if ( isEnabled ) {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        drawerToggle.setDrawerIndicatorEnabled(true);
        drawerToggle.syncState();

    }
    else {
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
        drawerToggle.setDrawerIndicatorEnabled(false);
        drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onSupportNavigateUp();
            }
        });
        drawerToggle.syncState();
    }
}

また、私は思う

drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);

減価償却されましたが、それがなくても正常に機能します。

11
luca992

スワイプを無効にし、アクションバーのホームボタンを無効にする必要があります。

スワイプを無効にするには、すでに指定されたコードに基づいた以下のコードを使用します

  public void setDrawerState(boolean isEnabled) {
        if ( isEnabled ) {
            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
            mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
            mDrawerToggle.setDrawerIndicatorEnabled(true);
            mDrawerToggle.syncState();
            getActivity().getActionBar().setHomeButtonEnabled(true);

        }
        else {
            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
            mDrawerToggle.setDrawerIndicatorEnabled(false);
            mDrawerToggle.syncState();
            getActivity().getActionBar().setHomeButtonEnabled(false);
        }
    }
2
jai

@sonidaによる回答の構築そして、@ luca992と@jaiによって与えられた調整を使用した後。

上記の推奨コードを試しましたが、アクションバーの左側にある「上」または「戻る」矢印がアプリに表示されませんでした。しかし、幸運にも私はそれを修正することができました。

SetNavigationDrawerState()にこの余分なコード行を追加する必要がありました[参照: Android.support.v7.app.ActionBarDrawerToggle.setHomeAsUpIndicator ]

toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp);

ドローアブルをダウンロードしました: Material.io からic_keyboard_backspace_white_24dp

完全なコードは次のとおりです。

MainActivity.Java-> onCreate()

DrawerLayout drawer;
ActionBarDrawerToggle toggle;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // Start: Code automatically generated by Android Studio
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();
    // End: Code automatically generated by Android Studio

    // I had to add this listener as the "back" arrow was totally unresponsive
    // Thanks to @luca992
    toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onBackPressed();
        }
    });

    // Start: Code automatically generated by Android Studio
    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    // End: Code automatically generated by Android Studio

    // More custom code for other stuff
    // ...
}

MainActivity.Java-> setNavigationDrawerState()

public void setNavigationDrawerState(boolean isEnabled) {
if ( isEnabled ) {
    drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    toggle.setDrawerIndicatorEnabled(true);
    toggle.syncState();
}
else {
    drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    toggle.setDrawerIndicatorEnabled(false);
    // the extra line of code goes here
    toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp);    

    toggle.syncState();
}

MainActivity.Java-> onBackPressed()

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else if(getSupportFragmentManager().getBackStackEntryCount() > 0){
        getSupportFragmentManager().popBackStack();
    }else {
        super.onBackPressed();
    }
}

MainActivity.Java-> startFragment()[例えばダミー関数]

public void startFragment(){
    MyFrag myFrag = new MyFrag();

    getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.frag_container ,myFrag)
        .addToBackStack(null)
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .commit();
}

MyFrag.Java-> onViewCreated()

@Override
public void onViewCreated (View view, Bundle savedInstanceState){
    super.onViewCreated(view, savedInstanceState);

    // Say, using an implemented interface Make call to MainActivitiy's  setNavigationDrawerState() passing false
    // setNavigationDrawerState(false)

    // ...
}

MyFrag.Java-> onDestroyView()

@Override
public void onDestroyView(){
    // Say, using an implemented interface Make call to MainActivitiy's setNavigationDrawerState() passing true 
    // setNavigationDrawerState(true)

    super.onDestroyView();
}
1
Vinay Vissh