Как закрыть навигацию DrawerLayout onBackPressed во фрагменте элементов навигации - PullRequest
16 голосов
/ 30 апреля 2019

Я создал проект Androidx с шаблоном Navigation .Теперь я хочу закрыть boxLayout onBackPressed() во фрагменте.А также я хочу установить OnClickListener для пунктов меню выдвижного ящика в моем пользовательском меню, и я никак не могу переопределить фрагмент onBackPressed() во фрагменте.

Я хочу знать, как этого добиться?

Вот мой ящик:

<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:id="@+id/drawerLayoutHome"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="350dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="@color/colorPrimaryDark"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:itemIconTint="@color/white"
        app:itemTextColor="@color/white"
        app:menu="@menu/activity_main_drawer"/>

</androidx.drawerlayout.widget.DrawerLayout>

Я хочу добиться этого:

override fun onBackPressed() {

    if (drawerLayoutHome.isDrawerOpen(GravityCompat.END)) {
        drawerLayoutHome.closeDrawer(GravityCompat.END)
    } else {
        super.onBackPressed()
    }
}

Но это для Activity, как этого добиться в Fragment?

Ответы [ 5 ]

8 голосов
/ 13 мая 2019

Здравствуйте, вы можете сделать это, включив свой фрагмент в действие и переопределив обратную обратную связь с помощью кода kotlin

Это функция обратной печати, в которой вы можете получить свой навигационный хост, а затем проверить текущий фрагмент или фрагмент, в котором хотите открыть ящик.

override fun onBackPressed() {

    val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentHomeHost)
    val completeFragmentList = navHostFragment?.childFragmentManager?.fragments

    if (completeFragmentList != null) {
        when {
            completeFragmentList[0] is HomeFragment -> {
                val home = (completeFragmentList[0] as HomeFragment)


            }
            else -> super.onBackPressed()
        }
    }

    if (drawerLayoutHome.isDrawerOpen(GravityCompat.START)) {
        drawerLayoutHome.closeDrawer(GravityCompat.START)
    } else {
        super.onBackPressed()
    }
}

А вот мотыга, вы можете получить выбор слушателя пункта

override fun onNavigationItemSelected(item: MenuItem): Boolean {
    drawerLayoutHome.closeDrawer(GravityCompat.START)

    return true
}
4 голосов
/ 10 мая 2019

Вы можете сделать это в течение Fragment, введя OnBackStackChangedListener в активность вашего ящика.
Затем свяжите ваш ящик с ActionBarDrawerToggle и переопределите onBackStackChanged() и синхронизируйте переключение вашего ящика.

Вот полный фрагмент:

public class MainActivity extends AppCompatActivity implements FragmentManager.OnBackStackChangedListener {


    private DrawerLayout drawer;
    private ActionBarDrawerToggle toggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Bind listener here
        getSupportFragmentManager().addOnBackStackChangedListener(this);
        drawer = findViewById(R.id.drawer_layout);
        toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        toggle.setToolbarNavigationClickListener(view -> onBackPressed());
        drawer.addDrawerListener(toggle);
        toggle.syncState();

    }


    //Override fragment backstack lister method 
    @Override
    public void onBackStackChanged() {
        //toggle.setDrawerIndicatorEnabled(getSupportFragmentManager().getBackStackEntryCount() == 0);
        //getSupportActionBar().setDisplayHomeAsUpEnabled(getSupportFragmentManager().getBackStackEntryCount() > 0);
        toggle.syncState();
    }

    @Override
    public void onBackPressed() {
        drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START))
            drawer.closeDrawer(GravityCompat.START);
        else {
            //super.onBackPressed();
        }
    }
}

Надеюсь, это поможет вам.

2 голосов
/ 09 мая 2019

Короткий ответ

Невозможно перехватить onBackPressed обратный вызов внутри Fragment без добавления дополнительного кода внутри хостинга Activity.Это просто не реализовано в Android SDK.Просто остановитесь.

Оригинальный ответ

В классе Fragment не существует такой вещи, как onBackPressed обратный вызов.Но вы можете реализовать это сами:

Создать интерфейс:

interface FragmentOnBackPressedListener {
  fun onBackPressed()
}

Теперь в вашей деятельности:

override fun onBackPressed() {
  // find top fragment
  val currentFragment = supportFragmentManager
    .findFragmentById(R.id.your_nav_host_fragment_id)?.let {
      it.childFragmentManager.fragments.getOrNull(0)
    }
  // check if it implements FragmentOnBackPressedListener 
  if (currentFragment is FragmentOnBackPressedListener ) {
    // if it does, transfer flow to the fragment
    return currentFragment.onBackPressed()
  }
  // if it doesn't, apply default behaviour
  super.onBackPressed()
}

Затем в вашем фрагменте:

class ExampleFragment : Fragment(), FragmentOnBackPressedListener {

  override fun onBackPressed() {
    // close your drawer layout here if visible

    // Also: to close fragment, invoke 
    // findNavController().navigateUp() or findNavController().popBackStack()
  }

}
0 голосов
/ 15 мая 2019

У меня была похожая проблема.

Итак, я добавил это в onBackPressed моего файла Activity.

FragmentManager manager = getSupportFragmentManager();
 if (manager.getBackStackEntryCount() > 0) {
                while (manager.getBackStackEntryCount() > 0) {
                    manager.popBackStackImmediate();
                }
0 голосов
/ 08 мая 2019

В Kotlin просто переопределите этот метод в своей деятельности,

override fun onBackPressed() {
    if (drawer_layout.isDrawerOpen(GravityCompat.START))
        drawer_layout.closeDrawer(GravityCompat.START)
    else
        super.onBackPressed()
}
...