我用 Navigation 模式创建了一个 Androidx 项目。现在,我要关闭片段中的 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
中实现?
答案 0 :(得分:8)
您好,您可以通过激活片段并使用Kotlin代码覆盖onbackpress来实现它
这是您的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
}
答案 1 :(得分:4)
您可以在抽屉活动中实施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 :(得分:2)
如果不在托管onBackPressed
内添加其他代码,则无法拦截Fragment
内的Activity
回调。根本没有在Android SDK
中实现它。停下来。
在onBackPressed
类中没有诸如Fragment
回调的事情。但是您可以自己实现它:
创建界面:
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()
}
}
答案 3 :(得分:0)
我遇到了类似的问题。
因此,我将其添加到我的活动文件的 onBackPressed 中。
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 0) {
while (manager.getBackStackEntryCount() > 0) {
manager.popBackStackImmediate();
}
答案 4 :(得分:0)
您可以使用onBackPress()
从片段中控制OnBackPressedDispatcher
。
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() }}
}
})
}
}
答案 5 :(得分:-1)
在Kotlin中,只需在您的活动中覆盖此方法,
override fun onBackPressed() {
if (drawer_layout.isDrawerOpen(GravityCompat.START))
drawer_layout.closeDrawer(GravityCompat.START)
else
super.onBackPressed()
}