Отключение навигационного ящика, включение кнопки "вверх" / "вверх-вниз" в фрагментах
Настройка
У меня есть действие, contentView которого является экземпляром DrawerLayout
, в котором есть ящик навигации с индикатором ящика, отображаемым на панели действий. Действие содержит Fragment
, назовите его ListFragment
, который содержит список опций. Когда нажимается эта опция, я заменяю ListFragment
на DetailFragment
.
![Architecture of the application]()
В этот момент я бы хотел отобразить "вверх" навигационную опцию вместо индикатора навигационного ящика. Я могу отобразить значок "вверх" , если я отключу индикатор ящика, вызвав mDrawerToggle.setDrawerIndicatorEnabled(false)
, но это только удаляет значок ящика - он не удаляет функциональность, то есть когда я нажимаю на каретку, навигационный ящик все еще открыт.
Кроме того, в этих subviews я хотел бы отключить открытие ящика, перетащив его с края экрана. Я попытался сделать это, вызвав setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
, но он, похоже, не отключил эту функцию.
Я попытался расширить класс ActionBarDrawerToggle
, чтобы предотвратить открытие ящика при щелчке индикатора - однако все, что происходит, это то, что выполняется переопределение ( "вверх" ), но ящик все еще открывается.
Я также выполнил шаги в Переключение между изображениями Android Navigation Drawer и Up caret при использовании фрагментов. Он работает, поскольку отображение каретки идет, но, несмотря на отмену функциональности кнопки вверх, меню по-прежнему открывается (приложение перемещается назад - оно просто также открывает ящик).
Вопрос
Итак, длинный рассказ: есть ли (желательно чистый и элегантный, но на данный момент я пойду с хакерским) способом достижения этих вещей, когда мой корень макета DrawerLayout
:
- Замените индикатор выдвижного ящика каретой "вверх" (предварительно выполнив
mDrawerToggle.setDrawerIndicatorEnabled(false))
- Предотвратить открытие ящика при нажатии на каретку и вместо этого переопределить мою собственную функциональность "вверх"
- Предотвратите открытие ящика при перетаскивании с края экрана.
Изменить
Все в порядке, похоже, если я переопределяю ActionBarDrawerToggle
AND onOptionsItemSelected
, меню не открывается, когда я нажимаю на каретку. Но он все равно открывается, если я перетаскиваю его с края. Помогите!
Ответы
Ответ 1
Это только часть решения, к которому я пришел, но было довольно сложно понять эту ошибку, поэтому я оставляю это здесь ради потомства.
Это как я определял 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"
эта проблема, по-видимому, решена.
Я смог воспроизвести эту проблему в образце, приложении только для навигационного ящика, так что это похоже на воспроизводимую проблему, не уникальную для моей ситуации.
Ответ 2
Короткий код
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();
}
}
Ответ 3
Основываясь на ответе сониды. После вызова 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);
был обесценен, но он отлично работает без него.
Ответ 4
Вам нужно отключить салфетки и отключить домашнюю кнопку панели действий:
Используйте приведенный ниже код, который основывается на коде, уже указанном для отключения прокрутки
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);
}
}
Ответ 5
Основываясь на ответе @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 setNavigationDrawerState() passing false
// setNavigationDrawerState(false)
// ...
}
MyFrag.java → onDestroyView()
@Override
public void onDestroyView(){
// Say, using an implemented interface Make call to MainActivitiy setNavigationDrawerState() passing true
// setNavigationDrawerState(true)
super.onDestroyView();
}