Отключение навигационного ящика, включение кнопки «вверх» / «вверх-вниз» в фрагментах

Настройка

У меня есть активность, contentView – это экземпляр DrawerLayout , в котором есть ящик навигации с индикатором ящика, отображаемым в панели действий. Действие содержит Fragment , назовем его ListFragment , который содержит список параметров. Когда нажимается эта опция, я заменяю ListFragment на DetailFragment .

Архитектура приложения

На данный момент я хотел бы отобразить «вверх» навигационную опцию вместо индикатора навигационного ящика. Я могу отобразить значок «вверх», если отключить индикатор ящика, вызывая mDrawerToggle.setDrawerIndicatorEnabled(false) , но это только удаляет значок ящика – он не удаляет функциональность, то есть когда я нажимаю кнопку Каретка, навигационный ящик все еще открыт.

Кроме того, в этих подзонах я хотел бы отключить открытие ящика, перетащив его с края экрана. Я попытался сделать это, вызвав setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) но он, похоже, не отключил эту функцию.

Я попытался расширить класс ActionBarDrawerToggle чтобы предотвратить открытие ящика при щелчке индикатора – однако все, что происходит, это то, что выполняется переопределение («вверх»), но ящик все же открывается .

Я также выполнил шаги в разделе « Переход между изображениями Android Navigation Drawer и Up caret» при использовании фрагментов . Он работает, поскольку отображение каретки идет, но, несмотря на отмену функциональности кнопки вверх, меню все же открывается (приложение перемещается назад – оно просто также открывает ящик).

Вопрос

Итак, длинный рассказ: есть ли (желательно чистый и элегантный, но на данный момент я пойду с хакерским) способом достижения этих вещей, когда мой корень макета – DrawerLayout :

  1. Замените индикатор выдвижного ящика mDrawerToggle.setDrawerIndicatorEnabled(false)) «вверх» (предварительно выполним через mDrawerToggle.setDrawerIndicatorEnabled(false))
  2. Предотвратите открытие ящика при нажатии на каретку и вместо этого переопределите мои собственные функции «вверх»
  3. Не допускайте открытия ящика при перетаскивании с края экрана.

редактировать

Хорошо, похоже, если я переопределяю ActionBarDrawerToggle AND onOptionsItemSelected , меню не открывается, когда я нажимаю на каретку. Но он все равно открывается, если я перетягиваюсь с края. Помогите!

Solutions Collecting From Web of "Отключение навигационного ящика, включение кнопки «вверх» / «вверх-вниз» в фрагментах"

Короткий код

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

Это лишь часть решения, к которому я пришел, но было сложно определить эту ошибку, поэтому я оставляю это здесь ради потомства.

Это как я определял 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" эта проблема, похоже, решена.

Я смог воспроизвести эту проблему в образце, приложении только для навигационного ящика, так что это похоже на воспроизводимую проблему, не уникальную для моей ситуации.

Основываясь на ответе Сониды. После вызова 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); 

Был обесценен, но он отлично работает без него.

Вам нужно отключить салфетки и отключить кнопку дома на панели действий:

Используйте приведенный ниже код, который основывается на коде, который уже указан для отключения салфетки

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

Основываясь на ответе от @sonida и после использования настроек, приведенных @ luca992 и @jai.

Я пробовал выше предлагаемые коды. Но стрелка «вверх» или «Назад» в левой части панели действий просто не отображалась в моем приложении. Но, к счастью, я смог это исправить.

Мне пришлось добавить эту дополнительную строку кода в setNavigationDrawerState () [Ref: android.support.v7.app.ActionBarDrawerToggle.setHomeAsUpIndicator ]

toggle.setHomeAsUpIndicator (R.drawable.ic_keyboard_backspace_white_24dp);

Я загрузил drawable: ic_keyboard_backspace_white_24dp из Material.io

Вот полный код:

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