48

设置

我有一个活动,它的 contentView 是 a 的一个实例DrawerLayout,它有一个抽屉式导航栏,在操作栏中显示了一个抽屉式指示器。该活动包含一个Fragment,我们称之为它ListFragment,其中包含一个选项列表。单击选项时,我将 替换ListFragmentDetailFragment.

应用程序的架构

此时,我想显示一个“向上”导航选项而不是导航抽屉指示器。如果我通过调用禁用抽屉指示器,我可以显示“向上”图标mDrawerToggle.setDrawerIndicatorEnabled(false),但这只会删除抽屉图标 - 它不会删除功能 - 也就是说,当我单击插入符号时,导航抽屉是还是开了。

此外,在这些子视图中,我想通过从屏幕边缘拖动来禁用抽屉的打开。我曾尝试通过调用来做到这一点,setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)但它似乎并没有禁用此功能。

我尝试扩展ActionBarDrawerToggle类以防止在单击指示器时打开抽屉——但是,所发生的只是执行了覆盖操作(“向上”导航),但抽屉仍然打开

我还实现了在使用 Fragments 时在 Android Navigation Drawer 图像和 Up caret 之间切换的步骤。它在显示插入符号时起作用,但尽管覆盖了向上按钮功能,菜单仍然打开(应用程序确实导航回来 - 它也只是打开抽屉)。

问题

所以,长话短说:当我的布局根为DrawerLayout

  1. 用“向上”插入符号替换抽屉指示器(暂时可以通过mDrawerToggle.setDrawerIndicatorEnabled(false))
  2. 单击插入符号时防止抽屉打开,而是用我自己的“向上”功能覆盖
  3. 当我从屏幕边缘拖动时,防止抽屉打开。

编辑

好吧,看起来如果我都覆盖ActionBarDrawerToggleAND onOptionsItemSelected,当我单击插入符号时菜单不会打开。但如果我从边缘拖动它仍然会打开。帮助!

4

5 回答 5

34

短代码

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();
    }
}
于 2015-04-28T16:35:36.870 回答
22

这只是我找到的解决方案的一部分,但很难找出这个错误,所以为了后代,我把它留在这里。

这就是我为导航抽屉定义 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"问题好像解决了。

我能够在仅导航抽屉的示例应用程序中重现此问题,因此它似乎确实是一个可重现的问题,并非我的情况所独有。

于 2013-10-28T22:09:13.253 回答
12

以索尼达的回答为基础。在调用 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);

已贬值,但没有它也能正常工作。

于 2015-08-07T21:06:52.917 回答
2

您需要禁用滑动并禁用操作栏主页按钮:

使用下面的代码构建在已经给出的代码之上以禁用滑动

  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);
        }
    }
于 2015-10-25T07:34:55.893 回答
1

以@sonida 的回答为基础,并在使用@luca992 和@jai 给出的调整之后。

我尝试了上面建议的代码但是操作栏左侧的“向上”或“返回”箭头只是没有出现在我的应用程序中。但幸运的是,我能够解决这个问题。

我不得不在 setNavigationDrawerState() [Ref: android.support.v7.app.ActionBarDrawerToggle.setHomeAsUpIndicator ]中添加这行额外的代码

toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp);

我从Material.io下载了可绘制对象:ic_keyboard_backspace_white_24dp

这是完整的代码:

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's  setNavigationDrawerState() passing false
    // setNavigationDrawerState(false)

    // ...
}

MyFrag.java --> onDestroyView()

@Override
public void onDestroyView(){
    // Say, using an implemented interface Make call to MainActivitiy's setNavigationDrawerState() passing true 
    // setNavigationDrawerState(true)

    super.onDestroyView();
}
于 2017-02-12T12:06:11.080 回答