Material Design - DrawerLayout
关键字:DrawerLayout、材料设计
项目地址:AboutMaterialDesign
注意:代码基于 android.support.design 26.0.0
在材料设计出现之前,想要实现下面的布局,必须自定义实现,多亏了开源社区,那时候我们可以用 SlidingMenu 等优秀的第三方模块来实现相关功能。今天我们要介绍 google 推出的抽屉布局
效果图一、从搬运官网代码开始
链接:官网链接,科学食用
抽屉式导航栏是一个面板,它将应用的主要导航选项显示在屏幕边缘。大多数情况下,它处于隐藏状态,但是如果用户从屏幕左边缘滑动手指,它就会显示出来。
抽屉式导航栏设计
决定在应用中使用抽屉式导航栏之前, 应该了解抽屉式导航栏设计 指南中定义的用例和设计原则。材料设计的原则如果想详细了解,还可以戳这里
1)创建简单抽屉布局
现在来创建一个简单的抽屉布局,要添加抽屉式导航栏,需要将包含 DrawerLayout 对象的用户界面声明为布局的根视图。在 DrawerLayout 内,添加一个包含屏幕主内容(当抽屉式导航栏处于隐藏状态时为主要布局)的视图和另一个包含抽屉式导航栏内容的视图。
<!--例如,以下布局使用包含两个子视图的 DrawerLayout:-->
<!--包含主内容的 FrameLayout(在运行时由 Fragment 填充)-->
<!--和抽屉式导航栏的 ListView-->
<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">
<!-- The main content view -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
- 此布局演示了一些重要的布局特性:
- 1.主内容视图(上面的 FrameLayout)必须是第一个子视图,因为 XML 顺序意味着按 z 序(层叠顺序)排序,并且抽屉式导航栏必须位于内容顶部。主内容视图设置为匹配父视图的宽度和高度, 因为在抽屉式导航栏处于隐藏状态时, 它代表整个 UI。
- 2.抽屉式导航栏视图 (ListView) 必须使用 android:layout_gravity 属性指定其水平重力。要支持“从右到左”(RTL) 语言,请使用 "start"(而非 "left")指定该值(这样当布局为 RTL 时,抽屉式导航栏会显示在右侧)。
- 3.抽屉式导航栏视图以 dp 为单位指定其宽度, 且高度与父视图相匹配。抽屉式导航栏的宽度不应超过 320dp,从而用户始终可以看到部分主内容。
2)初始化抽屉式导航栏列表
直接贴代码了,listview 的数据填充应该都没有大的问题
public class MainActivity extends Activity {
private String[] mPlanetTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlanetTitles = getResources().getStringArray(R.array.planets_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
...
}
}
3)监听打开和关闭事件
-
DrawerLayout.DrawerListener
监听的方法名也很人性,一看就懂
Type | Interface Discription |
---|---|
abstract void | onDrawerClosed(View drawerView) |
abstract void | onDrawerOpened(View drawerView) |
abstract void | onDrawerSlide(View drawerView,float slideOffset) |
abstract void | onDrawerStateChanged(int newState) |
onDrawerStateChanged 的对应值
Type | Name | Constant Discription |
---|---|---|
int | STATE_DRAGGING | Indicates that a drawer is currently being dragged by the user. |
int | STATE_IDLE | Indicates that any drawers are in an idle, settled state. No animation is in progress. |
int | STATE_SETTLING | Indicates that a drawer is in the process of settling to a final position. |
---- 以上就是官网文档的全部内容,当然还有一点点关于 ActionBarDrawerToggle 的介绍,有兴趣可以自行了解。
二、简单的使用
其实最简单的使用官网已经列出了,按照上面的代码就可以写出一个最简单的抽屉布局。
三、更进一步,NavigationView
NavigationView 是 design 22.2.0 加入的一个新的类,如果支持包版本过低,是没有的。它的出现弥补了上面简单布局中实现 ListView 布局的繁琐,可以让我们快速实现抽屉栏的布局。(就像文章开头的效果一样)
贴上仓库的部分代码,如果全部代码,可以到仓库链接克隆。
链接:仓库传送门
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_drawer_drawerlayoutId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
tools:context="com.arno.aboutmaterialdesign.drawerlayout.DrawerLayoutActivity">
<!--主布局-->
<include layout="@layout/content_drawerlayout_drawer"/>
<!--抽屉布局-->
<!--Attention:-->
<!--android:layout_gravity="start" 属性一定要设置,这是作为抽屉的标志-->
<!--这里的代码很可能没有联想,需要手动输入-->
<android.support.design.widget.NavigationView
android:id="@+id/activity_drawer_nav"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/header_drawerlayout"
app:menu="@menu/menu_drawer"
android:background="@color/colorPrimaryDark"
></android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
使用 NavigationView 会有这样的问题:
- 1.item 设置的图片没有色彩
- 2.取消滚动条的有效方法找不到
- 3.item 文字样式怎么设置
//去除滚动条
mNavigationView.getChildAt(0).setVerticalScrollBarEnabled(false);
//设置图片有色彩
mNavigationView.setItemIconTintList(null);
//设置文字颜色
mNavigationView.setItemTextColor(getResources().getColorStateList(R.color.selector_nav_menu_item));
//设置文字其他样式
mNavigationView.setItemTextAppearance(R.style.main_nav_menu_item_text_appearance);
NavigationView 有一个内部的监听方法:
NavigationView.OnNavigationItemSelectedListener
另,menu 和 header 除了像上面那样在 xml 中设置,也可以在代码里设置:
//Header 相关
addHeaderView(View v)
inflateHeaderView(int res)
getHeaderCount()
getHeaderView(int index)
removeHeaderView(View v)
//Menu 相关
getMenu()
inflateMenu()
也许你会觉得,好像哪里还有点不如意,不如看看 Menu 这个文件的属性,是不是能帮到你
链接:Menu 科学食用 口味更佳
---- 以上就是全部内容