实现滚动导航抽屉的最佳方式
Best way of implementing a scrolling navigation drawer
我一直在为我的一个应用程序添加导航抽屉,我开始想知道从使用 ListView
切换到多个 TextView
是否会更好导航抽屉列表项。查看 Google Design Guidelines on Navigation Drawer content (specifically the section on 'Scrolling'),我注意到多个 TextView
看起来会更好。
目前,我在导航抽屉中使用 ListView
和 ImageView
(它看起来有点像 this. However, when I scroll in my navigation drawer (I do this by turning my device landscape as there are not enough items in my list yet), only the ListView
scrolls, and the ImageView
stays as it is. I want it to be able to scoll more like this, where the ImageView
is also scrolled with the ListView
。
此外,我发现我的导航抽屉中的 ListView
没有涟漪效应 as shown in this image,尽管我的其他 Activity
中的其他 ListView
和 Fragment
是的。
我面临的问题是什么,我该如何解决这些问题?
更新:
在Google的I/O应用程序(2014)中,navigation drawer layout底部似乎有一个LinearLayout
,我认为它负责显示的项目列表。有人可以解释一下这是如何工作的吗?
only the ListView scrolls, and the ImageView stays as it is
听起来您的抽屉顶部有一个 ImageView
,然后是一个 ListView
。使用此配置,只有 ListView
会滚动(因为它是唯一可滚动的视图)。
您需要将 ImageView
添加为始终位于列表开头的 header。正如其中一条评论所建议的那样,做 listView.addHeaderView
.
there seems to be a LinearLayout at the bottom of the navigation
drawer layout which I think is responsible for the list of items
shown. Could someone explain how this would work?
他们使用 LinearLayout
作为容纳所有 TextView
的容器:
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
中,您必须创建一个单独的项目类型并在那里使用分隔线的布局,这可能会变得更加麻烦。
乍一看,然而,这段代码似乎只是re-inventing轮子,因为所有这些都可以通过ListView
.
截至 2015 年 5 月 29 日(在 Google I/O 2015 之后),您可以使用 Android 设计支持库 添加一个NavigationView
to your app(s). The Android Developer Blogspot article 说明如下:
Navigation View
The navigation drawer can be an important focal point for identity and navigation within your app and consistency in the design here can make a considerable difference in how easy your app is to navigate, particularly for first time users. NavigationView
makes this easier by providing the framework you need for the navigation drawer as well as the ability to inflate your navigation items through a menu resource.
...
You can then start using the Design library with a single new dependency:
compile 'com.android.support:design:22.2.0'
...
The Design library, AppCompat, and all of the Android Support Library are important tools in providing the building blocks needed to build a modern, great looking Android app without building everything from scratch.
使用 android.support.v4.widget.DrawerLayout 和 NavigationView 实现可滚动的导航抽屉可能比在以下位置描述的更简单:http://android-developers.blogspot.ru/2015/05/android-design-support-library.html
该文章建议将应用程序导航抽屉的每个元素添加为菜单项。这很酷,对于大多数开发人员来说绝对是一种可行的方法。
但是,如果您已经在内部实现了导航抽屉怎么办?线性布局?
看来您可以轻松地使旧的良好布局可滚动:只需将其设置为 NavigationView 的 "app:headerLayout"。无需更多更改!
因此,在最终解决方案中,您将拥有:
您的 Activity 的布局,类似于上面的博客 post,但没有 "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>
有关完整的工作示例,请参阅此 activity 布局:https://github.com/andstatus/andstatus/blob/master/app/src/main/res/layout/timeline.xml and this commit, where I migrated to a scrollable Navigation Drawer: https://github.com/andstatus/andstatus/commit/a80b299de714bdd65cacb138ffb31adc3ea23a98
我一直在为我的一个应用程序添加导航抽屉,我开始想知道从使用 ListView
切换到多个 TextView
是否会更好导航抽屉列表项。查看 Google Design Guidelines on Navigation Drawer content (specifically the section on 'Scrolling'),我注意到多个 TextView
看起来会更好。
目前,我在导航抽屉中使用 ListView
和 ImageView
(它看起来有点像 this. However, when I scroll in my navigation drawer (I do this by turning my device landscape as there are not enough items in my list yet), only the ListView
scrolls, and the ImageView
stays as it is. I want it to be able to scoll more like this, where the ImageView
is also scrolled with the ListView
。
此外,我发现我的导航抽屉中的 ListView
没有涟漪效应 as shown in this image,尽管我的其他 Activity
中的其他 ListView
和 Fragment
是的。
我面临的问题是什么,我该如何解决这些问题?
更新:
在Google的I/O应用程序(2014)中,navigation drawer layout底部似乎有一个LinearLayout
,我认为它负责显示的项目列表。有人可以解释一下这是如何工作的吗?
only the ListView scrolls, and the ImageView stays as it is
听起来您的抽屉顶部有一个 ImageView
,然后是一个 ListView
。使用此配置,只有 ListView
会滚动(因为它是唯一可滚动的视图)。
您需要将 ImageView
添加为始终位于列表开头的 header。正如其中一条评论所建议的那样,做 listView.addHeaderView
.
there seems to be a LinearLayout at the bottom of the navigation drawer layout which I think is responsible for the list of items shown. Could someone explain how this would work?
他们使用 LinearLayout
作为容纳所有 TextView
的容器:
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
中,您必须创建一个单独的项目类型并在那里使用分隔线的布局,这可能会变得更加麻烦。
乍一看,然而,这段代码似乎只是re-inventing轮子,因为所有这些都可以通过ListView
.
截至 2015 年 5 月 29 日(在 Google I/O 2015 之后),您可以使用 Android 设计支持库 添加一个NavigationView
to your app(s). The Android Developer Blogspot article 说明如下:
Navigation View
The navigation drawer can be an important focal point for identity and navigation within your app and consistency in the design here can make a considerable difference in how easy your app is to navigate, particularly for first time users.
NavigationView
makes this easier by providing the framework you need for the navigation drawer as well as the ability to inflate your navigation items through a menu resource....
You can then start using the Design library with a single new dependency:
compile 'com.android.support:design:22.2.0'
...
The Design library, AppCompat, and all of the Android Support Library are important tools in providing the building blocks needed to build a modern, great looking Android app without building everything from scratch.
使用 android.support.v4.widget.DrawerLayout 和 NavigationView 实现可滚动的导航抽屉可能比在以下位置描述的更简单:http://android-developers.blogspot.ru/2015/05/android-design-support-library.html
该文章建议将应用程序导航抽屉的每个元素添加为菜单项。这很酷,对于大多数开发人员来说绝对是一种可行的方法。 但是,如果您已经在内部实现了导航抽屉怎么办?线性布局?
看来您可以轻松地使旧的良好布局可滚动:只需将其设置为 NavigationView 的 "app:headerLayout"。无需更多更改! 因此,在最终解决方案中,您将拥有:
您的 Activity 的布局,类似于上面的博客 post,但没有 "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>
有关完整的工作示例,请参阅此 activity 布局:https://github.com/andstatus/andstatus/blob/master/app/src/main/res/layout/timeline.xml and this commit, where I migrated to a scrollable Navigation Drawer: https://github.com/andstatus/andstatus/commit/a80b299de714bdd65cacb138ffb31adc3ea23a98