我已经创建了 androidx navigation> navigation 模式的项目。现在,我想在Fragment中关闭 drawerLayout 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
中实现这一目标?
你好,您可以通过在活动中获取片段并用kotlin代码覆盖on Backpress
来做到这一点。这是您的背压功能,在此中,您可以获取导航主机,然后您可以检查当前片段或要打开抽屉的片段。
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
}
您可以通过在抽屉活动上实现OnBackStackChangedListener
在Fragment
中执行此操作。
然后,将抽屉与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();
}
}
}
我希望这对您有帮助。
简短答案
不可能在Fragment
内拦截onBackPressed
回调,而无需在托管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()
}
}
在Kotlin中,只需在您的活动中覆盖此方法,
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START))
drawer_layout.closeDrawer(GravityCompat.START)
else
super.onBackPressed()
}
您可以用 OnBackPressedDispatcher
的片段中控制 onBackPress()
。
class SampleFragment: Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true){
override fun handleOnBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START)
} else{
isEnabled = false
requireActivity().onBackPressed() }}
}
})
}
}
我也有类似的问题。
所以,我在我的活动文件的 onbackpressed 中添加了它。
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 0) {
while (manager.getBackStackEntryCount() > 0) {
manager.popBackStackImmediate();
}