【问题标题】:Navigation Drawer is not opening when sliding from left从左侧滑动时导航抽屉未打开
【发布时间】:2015-01-31 22:37:01
【问题描述】:

正如 Android 开发者页面所说的那样

用户可以通过从屏幕左边缘滑动或触摸操作栏上的应用程序图标将导航抽屉带到屏幕上。

但奇怪的是,我的活动上的导航抽屉没有响应滑动动作。它仅在触摸操作栏上的图标时切换。下面是我实现的导航抽屉

 mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);

    // Set up the drawer.
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            drawerLayout);

对此有什么可能的解释吗?我怀疑我的活动默认情况下具有其片段之一的布局。那么是不是这个原因呢?

编辑:我的活动的布局文件

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainPage">

<!-- The main ocntent view -->
<FrameLayout android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</FrameLayout>


<!-- The navigation drawer-->
<fragment android:id="@+id/navigation_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:divider="@android:color/transparent"
    android:name="com.example.android.handsfree.NavigationDrawerFragment"
    tools:layout="@layout/fragment_navigation_drawer" />

【问题讨论】:

  • 你能提供你的布局文件吗?
  • 查看编辑@Xyaren
  • 你能用滑动手势关闭抽屉吗?
  • 没有。我可以通过触摸操作栏上的图标或触摸导航抽屉外的内容来关闭抽屉
  • 你的 MainPage Activity 扩展了什么类?你能发布你的 NavigationDrawerFragment 的代码吗(可能通过Pastebin 因为它可能很长)

标签: android android-fragments navigation-drawer


【解决方案1】:

您的“NavigationDrawerFragment”已经在其“setUp”方法中为您创建了一个抽屉切换。

您应该在您的“MainPage”活动中创建一个新活动。


注意事项: 您可以使用android.support.v7.app.ActionBarDrawerToggle 代替NavigationDrawerFragment 中的v4


更新:

现在问题似乎解决了。有 2 个问题:

  1. OP 在 MainPage - Activity 中创建了第二个抽屉切换开关,但在 NavigationDrawerFragment 的 setUp 方法中已经创建了一个,该方法由 MainPage 调用以设置抽屉。 (这基本上是将一些抽屉的东西外包给抽屉片段。)
  2. OP 通过调用将 DrawerLockMode 设置为 LOCK_MODE_LOCKED_CLOSED 的方法将抽屉锁定在 onCreateOptionsMenu 中。他从未恢复此更改。

【讨论】:

  • 您的工具栏在布局中的什么位置?在上述 cmets 之一中,您说您正在使用 Toolbar 小部件。 android.support.v7.widget.Toolbar
  • 支持库不是使用 Android ActionBar,而是使用它的自己的工具栏视图/小部件(参见我的我的布局作为 示例 Here
  • 我想导入它不是唯一要做的事情,对吧?我如何“使用”支持库?
  • 我想你已经在使用它了。 DrawerLayout 是其中的一部分。它只是一堆额外的类和资源,它们扩展或提供了普通 android 的向后兼容性。
  • 但是先试试不带工具栏部分。
【解决方案2】:

你应该使用:

drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);

【讨论】:

  • 抽屉创建后默认解锁。
【解决方案3】:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white" >

<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<ListView
    android:id="@+id/listview_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="@color/drawer"
    android:choiceMode="singleChoice" />

关于你的活动

drawlayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    listData = (ListView) findViewById(R.id.listview_drawer);

    drawlayout.setDrawerShadow(R.drawable.drawer_shadow,
            GravityCompat.START);

【讨论】:

  • 这将如何解决问题? OP 使用一个片段和一个抽屉,这非常好。
  • 是的。 Android Developers 中的文档说我们可以使用ListView,但这不是唯一的方法。
  • 所以你必须使用 ActionBarDrawableToggle 这样你就可以使用任何其他布局而不是 ListView。
  • 适用于api-21
【解决方案4】:

在您的活动类中添加这些字段:

private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;

然后,在你的活动中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ...
    // enabling action bar app icon and behaving it as toggle button
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true)

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, //nav menu toggle icon
                R.string.app_name, // nav drawer open - description for accessibility
                R.string.app_name // nav drawer close - description for accessibility
        ){
            public void onDrawerClosed(View view) {
                // calling onPrepareOptionsMenu() to show action bar icons
                invalidateOptionsMenu();
            }

            public void onDrawerOpened(View drawerView) {
                // calling onPrepareOptionsMenu() to hide action bar icons
                invalidateOptionsMenu();
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // toggle nav drawer on selecting action bar app icon/title
    if (mDrawerToggle.onOptionsItemSelected(item)) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * When using the ActionBarDrawerToggle, you must call it during
 * onPostCreate() and onConfigurationChanged()...
 */

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Pass any configuration change to the drawer toggls
    mDrawerToggle.onConfigurationChanged(newConfig);
}

ic_drawer 是一个位于可绘制资源中的.png 图像。您可以在 Google 上搜索此图片。

要使用的 API 级别为 11+。

希望对你有帮助。

【讨论】:

  • 您用于ActionBarDrawerToggle 的构造函数是用于v4.app.ActionBarDrawerToggle。我使用的是v7.app.ActionBarDrawerToggle 所以,没有可绘制的参数This 是链接
  • 有什么区别或优势?
【解决方案5】:

1- 将标签替换为:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainPage">

    <!-- The main ocntent view -->
    <FrameLayout android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </FrameLayout>


    <!-- The navigation drawer-->
    <ListView android:id="@+id/navigation_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:divider="@android:color/transparent" />
    </android.support.v4.widget.DrawerLayout>

2- 在 onCreate 函数中使用此代码,您可以使用 v4 ActionBarDrawerToggle 或 v7,我使用 v4:

private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;

mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

mDrawerToggle = new ActionBarDrawerToggle(this,    mDrawerLayout,R.drawable.ic_drawer,
R.string.app_name,R.string.app_name) {
                    public void onDrawerClosed(View view) {
                        getActionBar().setTitle(mTitle);
                        invalidateOptionsMenu();
                    }

                    public void onDrawerOpened(View drawerView) {
                        getActionBar().setTitle(mDrawerTitle);
                        invalidateOptionsMenu();
                    }
                };
                mDrawerLayout.setDrawerListener(mDrawerToggle);

【讨论】:

  • 我用的是v7版本。但除此之外,我看不出你和我的代码之间没有区别