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)监听打开和关闭事件
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

NavigationViewdesign 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 科学食用 口味更佳


---- 以上就是全部内容
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容