Подтвердить что ты не робот

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

Настройка

У меня есть действие, 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, меню не открывается, когда я нажимаю на каретку. Но он все равно открывается, если я перетаскиваю его с края. Помогите!

4b9b3361

Ответ 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();
}