从片段中禁用导航抽屉

Posted

技术标签:

【中文标题】从片段中禁用导航抽屉【英文标题】:Disabling navigation drawer from fragment 【发布时间】:2016-07-14 22:59:39 【问题描述】:

我有一个带有导航抽屉和 4 个导航项(片段)的应用。在其中一个片段中,我设置了一个带有视图寻呼机的选项卡布局(另外 3 个片段)。

从这些内部片段之一,我想动态禁用/启用导航抽屉。基本上,在按下按钮时,我想限制对导航抽屉的访问(并在再次按下时重新启用)。

我该怎么做?

我尝试从这个内部片段访问父活动的DrawerLayout。但我看不到启用/禁用导航抽屉的方法。

我将抽屉添加到主 Activity 的方式:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

DrawerLayout 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);

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);

(当然,我在 onPostCreate 方法中添加了 toggle.syncState()

【问题讨论】:

setDrawerLockMode() 用于DrawerLayout,将setDrawerIndicatorEnabled() 用于ActionBarDrawerToggle @MikeM。设置setDrawerLockMode() 停止滑动手势。但是要设置setDrawerIndicatorEnabled(),我如何从我的Fragment 中访问ActionBarDrawerToggle 理想情况下,您应该通过 Activity 实现的 interface 来执行此操作,其中 Activity 中的 interface 方法调用上述方法。 @MikeM。是的,我试着去做。但是事情变得非常复杂,因为我试图在选项卡布局的 ViewPager 中的一个片段中执行此操作,而该片段又包含在主要活动所拥有的片段中:-/ 如果您可以提供任何提示这个(像伪代码?还是基本的代码结构?),真的很棒 “但是事情变得非常复杂,因为我试图在选项卡布局的 ViewPager 中的一个片段中执行此操作,而该片段又包含在主要活动所拥有的片段中” -这并不真正相关,因为 Fragment 仍然直接附加到 Activity。将getActivity() 投射到您的interface 【参考方案1】:

一个干净的方法是创建一个interfaceActivity 实现,Fragment 可以通过它调用处理抽屉锁定和切换按钮状态的Activity 的本地方法。例如:

public interface DrawerLocker 
    public void setDrawerEnabled(boolean enabled);

Activityinterface 方法中,我们只需计算DrawerLayout#setDrawerLockMode() 调用的锁定模式常量,然后在ActionBarDrawerToggle 上调用setDrawerIndicatorEnabled()

public class MainActivity extends Activity implements DrawerLocker 

    public void setDrawerEnabled(boolean enabled) 
        int lockMode = enabled ? DrawerLayout.LOCK_MODE_UNLOCKED :
                                 DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
        drawer.setDrawerLockMode(lockMode);
        toggle.setDrawerIndicatorEnabled(enabled);
    

    ...

Fragment中,我们只需要将宿主Activity转换为interface,并相应地调用setDrawerEnabled()方法。例如,锁上抽屉:

((DrawerLocker) getActivity()).setDrawerEnabled(false);

注意:由于 v7 appcompat 支持库的版本 23.2.0,ActionBarDrawerToggle 尊重DrawerLayout 的锁定模式,如果它被锁定,将不会切换抽屉状态。这意味着使用setDrawerIndicatorEnabled() 并不是绝对必要的,尽管为了向用户提供禁用切换的视觉指示可能仍需要这样做。

【讨论】:

此解决方案有效,谢谢。如何更改图标使其不可见。我一般无法管理图标。 你在寻找ActionBar#setDisplayHomeAsUpEnabled(false)吗? getSupportActionBar().setDisplayHomeAsUpEnabled(false);为我工作。谢谢@MikeM。【参考方案2】:

对于 Kotlin 语言,这两行: first line is for closing the drawer, second line is for setting its mode to "LOCK_MODE_LOCKED_CLOSED" (to make it disabled)

drawerLayout.close()
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)

“drawerLayout”定义如下: first line: declaring an instance of a DrawerLayout object second line: assigning a value to it

private lateinit var drawerLayout:DrawerLayout
drawerLayout = findViewById(R.id.activity_main_container)

【讨论】:

以上是关于从片段中禁用导航抽屉的主要内容,如果未能解决你的问题,请参考以下文章

导航抽屉 - 禁用点击抽屉后面的项目

在 Android 中禁用导航抽屉中的项目

在导航抽屉中禁用暗淡化

导航抽屉 - 禁用滑动

如何在使用Android Jetpack导航时禁用导航图标

从片段中的按钮单击打开导航抽屉(Kotlin)