前言
我刚来这个公司的时候,每个周三都会有分享会,主题自定,分享对象尽量是面向大众,一开始觉得不错,但是到后面发现分享的内容不是那么有营养,而且积极性不是很高,都是当做任务进行分享。 程序员因为较为腼腆,分享的人较少,大部分都是客户部、分析部或者推广部的分享,久而久之,氛围就比较消极。
为了提高咱们程序员发言的积极性,增添技术部的沟通氛围,决定之前的分享形式不变,但是改为月末一次,技术部的分享每周一次。主题可以是当前部门的相关技术,当然最好是能够让大众听懂。分享时能够积极讨论,最终目的提高自身的软实力,咱们程序员不能只知道敲代码,是吧?
那么,轮到我分享了,其实一个月之前就已经通知我让我准备分享,因为公司有个交易项目要上线,比较繁忙,就没太抽出时间准备,直到上个星期五才抽出周末的时间准备。
准备
说完那么多废话,开始进入正题。最终决定分享主题为『Material Design In Android』。因为之前毕设项目趣闻中有用到「Support Design」库中的控件,所以写起来会顺手一点。我分三部分准备:
-
APP
准备 - 文档准备
-
Keynote
准备
一、APP准备
项目已经上传到GitHub
上:AndroidMD
运行效果
花了两个多小时做了这个APP
,功能简单,主题明确。
先说说完成这个APP
的事前准备:
1. 主题
主题是最近非常火的「终结者2:审判日」
2. 数据
数据是自己在本地写的json
数据,很是尴尬,然后部署到七牛云上。地址是:WeaponInfo
3. 语言
用的语言是之前学的Kotlin
。Kotlin学习笔记
4. 风格
整体的风格就是我这次分享的主题 Material Desing
风格。
二、整体内容结构的准备
在做PPT
之前,先把结构搭好,并且把PPT
的内容先准备好,到时候直接就可以复制到PPT
中。
整体结构:
- 什么是
Material Design
Material Desing
的特点- 从四个特点结合
Android
的应用剖析- 在我的公司「口袋」项目中的应用
当然内容需要看官方的文档和其他资料加上总结才能完成,所以在此感谢一下文章的帮助:
Material Design 学习笔记
Material Design 官网介绍文档
Material Design 中文介绍
Material Design in Android Developer
三、PPT
的准备
有了之前内容的编写,做PPT
就方便一点。但是因为刚买的MAC
,但又不想再装WPS
套餐,于是用的是自带的keynote
,所以使用上会有点生疏。不过,整个PPT
制作下来对其使用也熟练了起来。
如果需要的话,可以加个QQ发给你。
1、封面
进入
MD
官网首页就是这张图片。
2、介绍
从
MD
上截取的动画作为入口,大概讲解一下MD
的基础概念和特点。
3、特点
这里抽取了四个点:
Material
、Elevation
、Color
和Animation
进行分析。
4、风格背景
文字采用圆角+阴影进行包裹,至于高度和圆角效果因为时间紧迫,没有按照严格规范进行设置,如果对这方面有要求可以参考官网详细的规范要求。
5、动画效果
说起动画,为了能够模仿
MD
的交互,也是现学现卖了一把。
其实就是背景的放大效果,再加上文字的位移效果。
三、总结
这应该是本人第一次技术分享,除了内容准备的还算充分,分享的过程不是很满意。本人性格偏内向,平时只默默的撸代码、玩游戏,不愿意主动和别人交流,所以不论分享之前还是期间都表现的很紧张,声音有明显的颤抖,整体节奏把握的不好,很快。
整个分享过程,感觉自己就是为了将PPT
内容放完就等于完成任务似的,导致听的人迷迷糊糊的,一个点还没有放完就跳到了另一个点,致使整个分享结束,听众吸收的部分很少。在结束后,我们老大 也给了我不少建议:分享的内容不在于多,而在于听众吸收了多少,你匆匆忙忙的说完了,底下的人一脸懵逼,这就失去了分享的意义。
确实,技术分享本来的目的不就是为了让那些对分享主题不熟悉的人能有个大概的了解,能够从中收获到一些在自己领域中得到应用的技能,这就足够了。因此,在分享之前,自己要对分享的知识点有个充分的了解。在分享时能将每个知识点都有个透彻而又完整的分析,不要追求速度。实话说这次分享确实给我带了不少的收获,相信在下次分享中能够有一个满意的表现。
我--------------是--------------分--------------割--------------线
Material Design in Android
接下来开始分享这次分享的主要内容,因为MD
的介绍和规范在官网上都有非常详细全面的介绍,所以我就不赘述了,建议自己先看一遍官方网站的介绍,这样你对MD
的理解会更加深入一些。那我把链接再列出一下:
当你把官网的内容大致浏览一遍,相信也对MD
有个初步的了解,当然要想全部弄懂的话,还得需要消化一阵子,毕竟MD
的设计规范细致入微。越读越能感受到它的妙处,假如你能严格按照它的规范进行开发项目,哪怕你不是专业的UI设计师,相信你的产品一定不会难看的。
那接下来就主要介绍一下Material Desing
在Android
中应用。。
跟随着15年Android 5.0
的问世,谷歌设计师们还给我们带来的一系列的具有Material Design
风格控件。这些控件被统一放置在support design
库中,以供开发中使用。使用这些库的前提是API>=21
,当然如果你想在 5.0 一下的设备这些控件的话,需要添加appcompat
包进行向下兼容。
我的design
版本是26.1.0
,上图大概就是design
提供的API
,这里我只做简单的使用介绍,如果想了解其原理的话,可以看一下官方的介绍。
这么多我该从何说起呢?我想了下,就按照我做这个小项目,需要的控件顺序说起吧,这样也相当于大家跟我一起做出一个具有
Material Design
风格的APP
了。
1、主题
一个项目的开始,你得先确定这个项目的主题颜色是什么?你可以使用谷歌给你提供的Material Theme
:
-
@android:style/Theme.Material
(深色版本) -
@android:style/Theme.Material.Light
(浅色版本) @android:style/Theme.Material.Light.DarkActionBar
当然,也可以使用自定义的主题,先看一下非常普遍的图片:
可以通过定制不同的类别的主题颜色,来达到预期的主题效果。
-
colorPrimary
项目主颜色,一般是Titlebar
的背景颜色 -
colorPrimaryDark
比主颜色深一点颜色,一般是状态栏颜色 -
textColorPrimary
文字的主颜色 -
windowBackground
窗口背景颜色 -
navigationBarColor
导航栏颜色
通过在styles
中配置颜色来定制您的主题,并在AndroidManifest
中应用。
开发
[图片上传失败...(image-3f86ab-1513646879600)]
2、BottomNavigationView
主题构建好了,下面就是主要内容架构,我大致分为四个模块:武器简介、人物简介、配件简介和空头简介。那么底下就需要一个tab
进行切换,BottomNavigationView
便开始登场。从名字就可以看出 「底部导航view
」,主要的作用在于给每个模块一个导航定位的功能。
先看一下效果:
-
在
menu/
下创建菜单文件:<menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/bottom_weapon_inc" android:icon="@drawable/about" android:title="@string/weapon_inc" /> <!-- 省略部分代码 --> </group> </menu>
-
XML
中进行引用<android.support.design.widget.BottomNavigationView android:id="@+id/navigation" android:layout_width="match_parent" android:layout_height="wrap_content" app:itemBackground="@color/colorPrimary" app:itemIconTint="@android:color/white" app:itemTextColor="@android:color/white" app:menu="@menu/bottom_menu"/>
-
代码中设置点击事件
navigation!!.setOnNavigationItemSelectedListener {}
3、DrawerLayout、NavigationView
和BottomNavigationView
相对的,不得不介绍一下NavigationView
,这两者都是导航View
,后者一般需要配合DrawerLayout
实现侧滑菜单效果。
请看效果:
在XML
直接引用
<android.support.v4.widget.DrawerLayout
android:id="@+id/dl_main"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp">
<!-- 主内容 -->
<FrameLayout
android:fitsSystemWindows="true"
android:id="@+id/fl_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<!-- 侧滑菜单内容 -->
<android.support.design.widget.NavigationView
android:id="@+id/nv_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
app:menu="@menu/nav_menu"/>
</android.support.v4.widget.DrawerLayout>
通过配置layout_gravity
的属性来设置侧滑的方向:start
:从左侧划出,end
从右侧划出。
headerLayout: 设置其头布局
menu: 设置菜单布局
详细使用请看我之前写的一篇博客:高大上的DrawerLayout
4、Toolbar
整体的架构搭建好了,剩下就是开始每个模块的内容了,内容当然少不了标题,那么就开始介绍一下Toolbar
。
Toolbar
作为早期Android
中ActionBar
的替代品,定制性和操作性挺高了不少。使用的时候需要设置NoActionBar
的主题。
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"></style>
5、RecyclerView+SwipeRefreshLayout
项目中列表肯定是少不了的,那么这就不得不提RecyclerView
了,强大之处不用多说,感兴趣的话看一下我之前写的博客,对其使用有个简单的介绍:简单粗暴RecyclerView
那如果想实现侧滑删除和长按拖拽的功能怎么办呢?RecyclerView
原生就支持这些,只需要继承ItemTouchHelper.Callback
的类,并实现它几个抽象方法即可。
-
创建实现
ItemTouchHelper.Callback
的类internal inner class ItemTouchHelperCallback : ItemTouchHelper.Callback() { override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int { val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END return makeMovementFlags(dragFlags, swipeFlags) } override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { myAdapter!!.onItemMove(viewHolder.adapterPosition, target.adapterPosition) return false } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { myAdapter!!.onItemDismiss(viewHolder.adapterPosition) } }
-
和
RecyclerView
建立连接val mItemTouchHelper = ItemTouchHelper(ItemTouchHelperCallback()) mItemTouchHelper.attachToRecyclerView(mRecyclerView)
实现效果如下:
6、CardView
列表结构写好了,里面内容得优化吧,CardView
自带圆角和阴影效果,让每个Item
看起来就非常的自然,正如其名像卡片一样,也符合了Material Design
特点。
作为ViewGroup
包裹子View
实现圆角和阴影的效果:
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="2dp"
app:cardCornerRadius="5dp"
app:cardElevation="5dp">
</android.support.v7.widget.CardView>
主要由两个属性控制:
-
cardCornerRadius
:圆角半径 -
cardElevation
:高度(直接影响阴影的大小)
7、CoordinatorLayout+AppBarLayout+Toolbar
列表写好了,接下来就是滑动的交互,CoordinatorLayout
:作为根View
或者是一个活多个子View
特定的容器,用于协调子View
之间滑动的交互,可以说CoordinatorLayout
是整个Design
库中最核心的控件。
AppBarLayout
其实就是LinearLayout
,通过layout_scrollFlags
来控制滑动的效果。前提是滑动view
必须实现NestedScrollingChild
的接口,且需要配置behavior
,最基本的使用就是:
<android.support.design.widget.CoordinatorLayout
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.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed"
app:popupTheme="@style/Theme.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundGravity="center" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
有两个重点:
- 滑动的
view
必须实现NestedScrollingChild
接口。比如RecyclerView
、NestedScrollView
. - 必须配置
behavior
。app:layout_behavior="@string/appbar_scrolling_view_behavior"
来看一下layout_scrollFlags
有哪些属性,为了方便理解,将可以滑动的view
简称为ScrollView
,设置了layout_scrollFlags
称为DependentView
:
1. scroll
子view
必须设置该属性其他的属性的才会生效,这个是最基本的属性。
2. scroll|enterAlways
只要ScrollView
滑动,滑动事件就会交给设置DependentView
,当DependentView
滑动结束才会将事件交给ScorllView
。也就是下面的效果:
3. scroll|enterAlwaysCollapsed
当ScrollView
向下滑动时,DependentView
先折叠到最小高度(这里是0),然后将事件交给ScrollView
,当ScrollView
滑动结束,DependentView
才继续滑动事件,直至展开,如下图所示:
4. scroll|enterAlwaysCollapsed|enterAlways
这边就展示一下折叠的效果,我们先设置最小的高度
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="100dp"
android:minHeight="50dp"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed|enterAlways" />
展示一下效果:
5. scroll|exitUntilCollapsed
这个搭配重点在于上拉的时候,DependentView
会先折叠到最小高度,然后事件全部交给ScrollView
。那下拉的时候就是当ScrollView
滑动结束,才开始DependentView
的滑动事件。
6. scroll|enterAlways|snap
这个snap
就是在上面的基础上多了一个回弹的效果,当DependentView
正在滑动,此时手指离开屏幕时,DependentView
会自动移动到离自己较劲的终点或者始点。效果如下:
上面的属性完全可以像第四种情况叠加使用,至于效果自己尝试了了才能感觉到它的奥妙之处。
8、转场动画
交互有了,现在看是添加点击跳转效果了。咱们之前跳转动画都是在startActivity
之后调用overridePendingTransition
方法,传入进入和退出的动画实现跳转动画。Android 5.0
提供了强大的转场动画,给每个item
赋予了生命,跳转时,仿佛每块布局都参与了这次搬迁大运动。
使用时,需在setContentView()
之前加上
window.requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)
跳转时候这样写:
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(activity).toBundle())
跳转的界面设置转场动画或者出场动画:
window.enterTransition = Explode()
window.exitTransition = Slide()
为了看出效果我设置了2s的延迟:
9、Toast、SnackBar和AlertDialog
基本的界面写完了,剩下的就是一些逻辑上的操作啦,比如「提示」。那么Android
提示分为三种:
- 友好的
Toast
(比如网络失败) - 拥有附加行为的提示
SnackBar
(比如误删信息回撤) - 强制让用户做出选择的
AlertDialg
(比如未登录)
那么这三种的效果是什么呢?
大概先讲这些,有时间再进行后续补充。
Material Design
在「口袋」中的应用
其实在咱们的「口袋贵金属」项目中也到找到很多MD
的元素。
首先是点击的水波纹效果:
其次是交易圈的滑动交互:
还有就是本人在「口袋」接手的第二个需求,「个人中心」。看一下效果:
严格按照
Material Design
风格进行开发,相信一定能开发出非常漂亮的APP
!