【问题标题】:Best way of implementing a scrolling navigation drawer实现滚动导航抽屉的最佳方式
【发布时间】:2015-05-06 18:14:03
【问题描述】:

我一直在向我的一个应用程序添加一个抽屉式导航,我开始怀疑是否最好从使用ListView 切换到多个TextViews 作为导航抽屉列表项。查看Google Design Guidelines on Navigation Drawer content (specifically the section on 'Scrolling'),我注意到多个TextViews 可能看起来更好。

目前,我在导航抽屉中使用ListViewImageView(它看起来有点像this。但是,当我在导航抽屉中滚动时(我通过转动设备横向来做到这一点)因为我的列表中还没有足够的项目),只有ListView 滚动,ImageView 保持原样。我希望它能够更像this, where the ImageView is also scrolled with the ListView

此外,我发现我的导航抽屉中的ListView 没有涟漪效应as shown in this image,尽管我的其他Activitys 和Fragments 中的其他ListViews 有。

我面临哪些问题,我该如何解决这些问题?

更新:

在 Google 的 I/O 应用程序 (2014) 中,navigation drawer layout 的底部似乎有一个 LinearLayout,我认为它负责显示的项目列表。有人可以解释一下这是如何工作的吗?

【问题讨论】:

  • 请发布任何代码以获得更好的帮助。
  • @SiloéBezerraBispo 我真的认为不需要为这种情况发布代码,但如果你坚持,我应该在我的问题中添加什么代码?
  • 如果导航项是预先知道的并且不是动态确定的,我看不到使用 TextViews(大概在 ScrollView 内)而不是 ListView 的问题。或者,您可以将图像添加为 ListView 上的标题视图。
  • ListView.addHeaderView

标签: android android-listview scroll navigation-drawer


【解决方案1】:

只有 ListView 滚动,ImageView 保持原样

听起来您的抽屉顶部包含一个ImageView,然后是一个ListView。使用此配置,只有 ListView 会滚动(因为它是唯一可滚动的视图)。

您需要将ImageView 添加为始终位于列表开头的标题。正如其中一位 cmets 所建议的,请执行listView.addHeaderView

导航底部似乎有一个LinearLayout 我认为负责项目列表的抽屉布局 显示。有人可以解释一下这是如何工作的吗?

他们使用LinearLayout 作为容器来保存所有TextViews:

private void createNavDrawerItems() {
    mDrawerItemsListContainer = (ViewGroup) findViewById(R.id.navdrawer_items_list);
    ...
    int i = 0;
    for (int itemId : mNavDrawerItems) {
        mNavDrawerItemViews[i] = makeNavDrawerItem(itemId, mDrawerItemsListContainer);
        mDrawerItemsListContainer.addView(mNavDrawerItemViews[i]);
        ++i;
    }
}

我相信他们使用LinearLayout 并以编程方式膨胀所有项目的原因是能够轻松使用分隔项:

private View makeNavDrawerItem(final int itemId, ViewGroup container) {
    ...
    if (itemId == NAVDRAWER_ITEM_SEPARATOR) {
        layoutToInflate = R.layout.navdrawer_separator;
    } else if (itemId == NAVDRAWER_ITEM_SEPARATOR_SPECIAL) {
        layoutToInflate = R.layout.navdrawer_separator;
    } else {
        layoutToInflate = R.layout.navdrawer_item;
    }
    ...
    return view;
}

ListView 中,您必须创建一个单独的项目类型并在那里使用分隔符的布局,这可能会变得更加麻烦。

乍一看,不过,这段代码似乎是在重新发明轮子,因为所有这一切都可以通过 ListView 实现。

【讨论】:

  • 我喜欢在您的答案中显示TextViews 的想法,主要是因为我可以添加分隔符并更好地控制我的布局。
  • 您不需要添加单独的分隔符视图。 LinearLayout 可以在其子元素之间绘制分隔线,只需给它一个可绘制对象并调用 'setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);`
  • 感谢您的回答。我会看看是否可以在我的应用中以这种方式实现抽屉式导航。
  • @Simas 我在哪里可以找到您发布的代码(它来自 Google 在 GitHub 上的 I/O 应用程序)?
  • @FarbodSalamat-Zadeh 是的,它来自您提供的链接的存储库。 BaseActivity 包含 createNavDrawerItems 方法。
【解决方案2】:

自 2015 年 5 月 29 日起(在 Google I/O 2015 之后),您可以使用 Android 设计支持库向您的应用添加 NavigationView )。 Android Developer Blogspot article 声明如下:

导航视图

navigation drawer 可以成为应用内标识和导航的重要焦点,此处设计的一致性可以显着提高应用导航的难易程度,尤其是对于初次使用的用户而言。 NavigationView 通过为抽屉式导航提供所需的框架以及通过菜单资源扩展导航项的能力,使这变得更容易。

...

然后,您可以开始使用带有一个新依赖项的设计库:
compile 'com.android.support:design:22.2.0'

...

设计库、AppCompat 和所有 Android 支持库都是重要的工具,它们提供了构建现代、美观的 Android 应用所需的构建块,而无需从头开始构建所有内容。

【讨论】:

  • 但是 NavigationView 是否可以像问题中所要求的那样滚动?
  • 如有必要,我想它可以放在ScrollView 中。
  • 当我在菜单项的 onClick 中调用 DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); 时,将其放在滚动视图中会导致问题。错误是找不到抽屉。
【解决方案3】:

使用 android.support.v4.widget.DrawerLayout 和 NavigationView 实现可滚动的 Navigation Drawer 可能比http://android-developers.blogspot.ru/2015/05/android-design-support-library.html 中描述的更简单

那篇文章建议将应用程序导航抽屉的每个元素添加为菜单项。这很酷,对于大多数开发人员来说绝对是一种方式。 但是,如果您已经在内部实现了导航抽屉怎么办?线性布局?

看来您可以轻松地使旧的良好布局可滚动:只需将其设置为 NavigationView 的“app:headerLayout”即可。无需更多更改! 因此,在最终解决方案中,您将拥有:

您的 Activity 布局,类似于上面的博客文章,但没有“app:menu="@menu/drawer" 属性,例如:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- your content layout -->

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        />
</android.support.v4.widget.DrawerLayout>

“drawer_header.xml”文件中所有旧抽屉内容的布局,迁移后没有对此可滚动抽屉进行任何更改,例如这个:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:choiceMode="singleChoice"
    android:orientation="vertical">

    <TextView
        android:id="@+id/myFirstButton"
        android:onClick="onMyFirstButtonClick"
        android:text="@string/my_first_button_title"/>

    <TextView
        android:id="@+id/goToTheTopButton"
        android:onClick="onGoToTheTopButtonClick"
        android:text="@string/go_to_the_top_title"/>

    <View style="@style/Divider"/>

    <!-- Some other "menu items" -->
</LinearLayout>

有关完整的工作示例,请参阅此活动布局:https://github.com/andstatus/andstatus/blob/master/app/src/main/res/layout/timeline.xml 和此提交,我迁移到可滚动的导航抽屉:https://github.com/andstatus/andstatus/commit/a80b299de714bdd65cacb138ffb31adc3ea23a98

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    相关资源
    最近更新 更多