Material Design 中的素描阴影绘画技巧是UI画上去的,还是程序员写上去的

为何有应用宁可使用一套奇丑无比的界面,也不愿意跟进 Material Design? - 简书
为何有应用宁可使用一套奇丑无比的界面,也不愿意跟进 Material Design?
这个问题其实是相当复杂的。从 Google 的发布会提出 Material Design 的设计规范以来,许多人都为 Material Design 所惊艳到。但事实上,大多数应用都无法很好及时跟进这一设计标准。这一点,尤其是在国内,显得更为的突出。我自己实践 Material Design 也有了一段时间,我觉得至少有三点原因。一、Material Design 设计语言非常复杂,学习成本高,实现难度大。于 Material Design 复杂的设计语言相比,我敢说,学习难度比你跟进 iOS 的平面化的开发标准要困难十倍以上。Material Design 并不是使用 Google 提供的这些控件、图片设计出来的东西就是 Material Design 了。Material Design 的核心是一个高度抽象化的设计逻辑是对真实事物的逻辑层面的模拟,比起 iOS 以前那种单纯视觉上的拟物比起来,这是一种非常高层次的拟物概念,理解起来确实比较费事。举个例子来说,当你有一个如同这样的页面布局。
上传失败,请重试。
这样的页面布局下,当用户手指从下向上滚动屏幕的时候,我们先想象一下,这个布局应该如何跟随调整?通常情况下,我们会选择整页内容一起向上滚动。但实际上,这种方法并不是很正确。我们仔细观察这个布局,去掉状态栏,这个页面也有五个不同的“色块”组成的独立元素。他们分别是 用来选择操作的顶栏Toolbar,然后是 Featured Image,然后是 Topic,下方的 Detail,和一个标记状态的 Button。然后我们把这五个东西想象成五张真实存在的纸片,他们堆叠在一起类似于下图这样的:
当你移动下面的 Detail 页的时候,其他元素其实应该有着不同的相对运动才对,而不是整体上移。比如 Featured Image 不动,下面的纸片从它上方运动覆盖移动过去,而推到顶时,Topic 页可以成为这页的标题,而下方的 Detail 也继续移动。这个设计来自于 Google I/O 2014 App 的设计。(此应用源代码可以到
下载)这样的设计逻辑并不是来自于哪个现成的模板,而是针对你应用的不同布局不同考虑的,甚至是像素级的细节考虑,对设计者的要求很高,对程序实现的要求同样也很高。这是 Material Design 中许多细腻的 “激动人心的细节” 背后深藏的设计逻辑。更何况,我只能说,我举的这个例子也是 Material Design 复杂语言的一个很小的部分而已。二、Material Design 的设备兼容性不够好。Material Design 的设备兼容性是比较差的,当然比起当年 Holo 设计在 Android 2.x 上的完全不兼容不同,Material Design 是可以做到 4.x 的半兼容的。所谓半兼容,指的是使用 Google 提供的控件和兼容包,可以基本显示。但是比如状态栏的颜色的设置、各个控件的 elevation 阴影、selectableBackground 的按钮响应动画都会失效。
(如上图这样的 Elevation 效果,在 Android 4.x 上会被直接“压扁”显示)而与 Android 2.x 更是完全不兼容了。开发者即使愿意忍痛让 4.x 用户看一个不完整的设计,也不能满足 2.x 用户的兼容需求。虽然这种苛刻的兼容需求对于大多数应用来说都不是很有关系,但是比如像 QQ(最低兼容至 Android 1.6)、微信(最低兼容至 Android 2.2)这样的应用,他们的市场的广度迫使他们不能尝试这样的事情,毕竟在中国,使用 Android 2.x 的手机的用户依然还是有相当一部分的。在这样的背景下,Material Design 在 QQ、微信、淘宝 这样的应用上,短时间是不可能实现的。他们处于兼容性的考量,需要使用系统最基础的控件以及利用这些控件组合的自定义控件,而不能去使用高版本才拥有的特性。这样的应用又卡、又慢、又丑也是有一定客观原因的。三、Material Design 的一些其他劣势。当然上述的两点原因并不是一些大厂商不使用 Material Design,宁可用自己设计的极丑无比的界面的唯一原因。还有一些细碎的原因,也是左右这个设计普及受阻的砝码。比如像阿里、腾讯、百度这样的企业,他们并不是设计驱动的,而是商业驱动的。如果跟进 Material Design,势必会影响他们的一些商业利益。比如说,页面的逻辑会受到牵制,他们再也无法放一些活动、广告的按钮放在用户最易点击的地方,颜色也不能总是整片整片的大红大绿。一些页面的访问频次会随着逻辑层级变深而降低。这也是当时 微信 5.2 测试版刚开始试图 Holo 化又叫停的重要原因。
(微信 5.2 内测版截图,图源网络)更有一些想法是希望 Android 和 iOS 能拥有一样的 UI,使得用户降低学习成本,更快上手,更好赚钱。所以在 Android 上出现底栏两层皮、三层皮什么的就是出于这样的想法。在目前中国市场上,用户对设计的品味还处于一个比较初级的阶段,对设计几乎没有要求。而你就算有要求,你为了使用应用也愿意去做这样的妥协。开发者做跟进花费的代价远小于他们的收益。恐怕这是许多公司宁可设计一套奇丑无比的 UI,也不愿意跟进 Material Design 的核心原因。Material Design使用总结
Material Design是在5.0时新推出的一种设计规范,现在绝大部分的app都已经使用这种新的设计规范来进行界面设计。其主要是强调材质和层次感在设计中的应用,Android中也做了一些原生态的支持,但是要使用这些都必须最小兼容到Android5.0,也就是API 21,或者是添加Material Design的一个支持库。
推荐两个Material Design的配色和图标网站:
一个是可以在线进行配色方案的查看:
一个是提供Material Design风格的图标:
图不重要,看字!!!!!图不重要,看字!!!!!图不重要,看字!!!!!
最基本的主题有三个:
@android:style/Theme.Material
@android:style/Theme.Material.Light
@android:style/Theme.Material.Light.DarkActionBar
这几个是基本的主题,也是分别代表三种风格的主题,更多的需要我们自己根据自己的需要来进行定制。vcD4NCjxwcmUgY2xhc3M9"brush:">
@android:color/holo_green_light
@android:color/holo_green_light
主要由几部分组成,colorPrimary,colorPrimaryDark,colorAccent,textColorPrimary,windowPrimary,navigationBarColor这个值可以使用已经提供的颜色值,也可以直接自己定制。
基本使用方式:
Android中为我们提供了一个便捷的提取相应主题的工具&Palette。其能根据传入的Bitmap来获取到一系列特定风格的颜色值,使得当前主题和传入的图片更为的贴切。使用该工具能很方便的创建出各种风格的主题。
要使用需要导入相应的包&com.android.support:palette-v7。如果是AS,则直接打开module setting,在dependencies中进行添加即可。如果是Eclipse,这需要去sdk文件夹&&extras&android&support&v7文件夹中将palette项目导入工作空间,并作为主工程的依赖项目。
导入完成后直接在代码中使用。
//声明一个Bitmap对象
Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.study55);
// 声明一个palette对象
Palette.Builder palette = Palette.from(bitmap);
//获取到相应的色调,并设置个相应的。
Palette.Swatch
darkMutedSwatch = palette.generate().getDarkMutedSwatch();
MainActivity.this.getWindow().setStatusBarColor(darkMutedSwatch.getRgb());
效果如下:
常见的一些提取的色调:
getDarkMutedColor(int defaultColor)&&获取一个柔和的,深色的颜色
getLightMutedColor(int defaultColor)&&获取一个柔和的,亮色的颜色
getDarkVibrantColor(int defaultColor)&&获取一个有活力的,深色的颜色
getLightVibrantColor(int defaultColor)&&获取一个有活力的,浅色的颜色
getMutedColor(int defaultColor)&&获取一个柔和的颜色
getVibrantColor(int defaultColor)&&获取最为有活力的颜色
视图与阴影:
在Material Design中新添加了一个布局属性,除了原本的X,Y之外,新添加了Z轴(包含静态的高度和动态的高度),使得视图在垂直与手机屏幕的方向上也有了属性,也就是产生了视图和阴影效果,而不像是之前所有的视图都在同一个平面上。
一张图来说明在Material Design中视图的推荐高度:
阴影效果:**Z轴由两部分组成,静态高度和动态高度。静态高度常用于视图的固定布局,动态高度则常用于实现动画效果。即 **Z =elevation + translationZ
elevation=0
elevation = 100
我们可以使用SeekBar在代码里动态的修改阴影的高度,更多的还是将其作为动画来使用。
mSeekBarElevation.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mCardView.setCardElevation(progress);
public void onStartTrackingTouch(SeekBar seekBar) {
public void onStopTrackingTouch(SeekBar seekBar) {
裁剪与着色:
新添加的一种对图像的修改方式,通过修改图像中的Alpha遮罩来修改图像。
基本使用方式:
在xml文件中:直接为需要的图片设置着色颜色和着色的模式即可。
2. 裁剪: Clipping裁剪可以使我们能够为控件的外形绘制指定类型的形状,和之前的shape有相同的效果,只是这是直接修改外形,而不是作为一个背景。
基本使用方式:
在布局文件中放置一个需要用到的控件,无需有额外的设置。
在代码中获取到这个控件并使用ViewOutlineProvider来为其设置外形。
//声明一个ViewOutlineProvider实例,并设置需要的类型,有多种图形可以选择,只需要重写其getOutline方法即可。
ViewOutlineProvider outlineProvider = new ViewOutlineProvider() {
public void getOutline(View view, Outline outline) {
int fabSize = 100;
outline.setOval(-4,-4,fabSize+2,fabSize+2);
//调用View的setOutlineProvider()方法为控件设置外形。
View fabView = findViewById(R.id.fab_add);
fabView.setOutlineProvider(outlineProvider);
这样就做出了一个圆形的按钮(类似于FloatingActionBar):
1. RecyclerView :
RecyclerView 是对ListView进行的一次提升和拓展,同时考虑到了布局的重用问题,通过内部的ViewHolder来提升效率,同时提供了更多新的特性和定制细节,有更大的定制功能。
基本使用方式:
首先和ListView一样,做一个Item中要用到的布局,这个根据自己额业务需要来自由定制(演示只使用一个TextView)。
recycle_view_item.xml
然后和ListView相似,也是定制自己的Adapter,这里一般需要重新复写的方法有三个,并实现一个自己的ViewHolder(继承自RecyclerView.ViewHolder)
RecycleViewAdapter.java
package com.wei.desig
import android.support.v7.widget.RecyclerV
import android.view.LayoutI
import android.view.V
import android.view.ViewG
import android.widget.TextV
import java.util.ArrayL
import java.util.R
* Created by WQC
public class RecycleViewAdapter extends RecyclerView.Adapter {
//保存数据的Java Bean
private final ArrayList mD
public RecycleViewAdapter(ArrayList mDatas) {
this.mDatas = mD
* 当ViewHolder被创建时调用
* @param parent 父控件
* @param viewType View类型
* @return ViewHolder的实例
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_view_item, parent, false);
return new ViewHolder(itemView);
* 当数据和View进行绑定时被调用
* @param holder ViewHolder实例
* @param position 当前View的Item位置
public void onBindViewHolder(ViewHolder holder, int position) {
//根据Position来获取相应的数据
final DataModel rowData = mDatas.get(position);
//数据显示到视图上
holder.showTextView.setText(rowData.getShowText());
holder.showTextView.setTag(rowData);
* 获取列表项的长度
* @return 列表的长度
public int getItemCount() {
return mDatas.size();
* 实现ViewHolder的内部类,用于布局的重用
public static class ViewHolder extends RecyclerView.ViewHolder {
//这里只有一个TextView,和recycle_view_item.xml布局里边是对应的,都是根据自己的业务需要进行修改。
private final TextView showTextV
//通过itemView 来进行重用
public ViewHolder(View itemView) {
super(itemView);
showTextView = (TextView) itemView.findViewById(R.id.id_show_text_view);
然后就是在主布局中加入RecyclerView控件进行使用:
activity_recycleview.xml
android:scrollbars=&vertical&
tools:listitem=&@layout/recycle_view_item&&
接着在Java代码中使用RecyclerView:
RecycleViewActivity.java
package com.wei.desig
import android.graphics.O
import android.os.B
import android.support.v7.app.AppCompatA
import android.support.v7.widget.LinearLayoutM
import android.support.v7.widget.RecyclerV
import android.view.V
import android.view.ViewOutlineP
import android.widget.LinearL
import java.util.ArrayL
* Created by WQC.
public class RecycleViewActivity extends AppCompatActivity {
RecyclerView mRecyclerV
LinearLayoutManager linearLayoutM
RecycleViewAdapter recycleViewA
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycleview);
//获取到布局中声明的RecyclerView
mRecyclerView =(RecyclerView)findViewById(R.id.id_recycle_view);
//为RecyclerView指定一个布局管理器,可以是GridLayoutManager,LinearLayoutManager等,搭配使用有多种的表现形式。
linearLayoutManager = new LinearLayoutManager(this);
//设置布局管理器
mRecyclerView.setLayoutManager(linearLayoutManager);
//声明一个适配器实例,并传入数据。
recycleViewAdapter = new RecycleViewAdapter(initData(20));
//将适配器绑定到RecyclerView上
mRecyclerView.setAdapter(recycleViewAdapter);
* 准备初始化数据
public ArrayList initData(int size){
ArrayList datas = new ArrayList&&(size);
for (int i = 0;i
ps:DataModel.java文件(JavaBean)
package com.wei.desig
* Created by WQC
用于承载数据的Bean
public class DataModel {
private String showT
public DataModel(String showText) {
this.showText = showT
public String getShowText() {
return showT
public void setShowText(String showText) {
this.showText = showT
至此RecyclerView的简单使用就完成了,可以尝试修改其列表方向,布局管理器的种类,不同的搭配产生不一样的效果,例如列表项,图墙,画廊效果,都可以自定义实现。
附:慕课网上有一个RecyclerView的使用视频教程:
2. GardView
CardView其实就是一个像其名字一样,是一个卡片布局,并且继承自Framelayout所以其也可以作为布局容器使用。
基本使用方式:
首先要导入其所在的jar包:
android.support.v7.widget.CardView。在Android Studio中直接可以找到。右键Module,选择Open Module Setting,选择Dependencies,点右边的加号,直接输入CardView搜索即可。
在布局文件中直接使用CardView:
content_card.xml
android:elevation=&200dp&
android:layout_marginRight=&@dimen/activity_horizontal_margin&
android:layout_marginLeft=&@dimen/activity_horizontal_margin&
app:cardBackgroundColor=&@color/cardview_dark_background&
app:cardCornerRadius=&10dp&&
然后在Java文件中通过findViewById()使用即可
CardViewActivity.java
mCardView = (CardView) findViewById(R.id.id_card_view);
就是一个卡片的效果
3. FloatingActionButton
FloatingActionButton名为浮动圆形按钮,在android.support.design.widget.FloatingActionButton包下。这个兼容包主要是为了向低版本的Android设备兼容Material Design。上边图片中的邮件小图标便是FloatingActionButton的效果,其用法和ImageView相似,只是更加符合Material Design的设计规范,同时加入了阴影效果。
基本使用方法:
首先要添加上android.support.design这个库,AS中方法和之前一样,Eclipse中则需要进入sdk中,选择extra,选择android,选择support,将里边的design项目导入工作空间并作为主工程依赖的项目。
其次就是在布局文件中直接使用FloatingActionButton
布局文件中的使用:
app:backgroundTint=&#ff77&
app:fabSize=&mini&
app:elevation=&20dp&
app:rippleColor=&#FFF4D6D6&
在Java代码中获取使用:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
该控件其实就是一个特定的ImageButton,也可以设置自己的事件监听,实现需要的业务逻辑。
该片段为FloatingActionButton设置了业务逻辑,点击时弹出一个Snackbar显示消息。
fab.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Snackbar.make(view, &Replace with your own action&, Snackbar.LENGTH_LONG)
.setAction(&Action&, null).show();
4. TextInputLayout
TextInputLayout 其实是一个对于EditText进行拓展的新控件,原本的EditText的默认提示文本hint在点击输入时就会消失,而TextInputLayout使得点击输入后也依然显示提示信息。
基本使用方式:
首先也是导入android.support.design这个包,然后在布局文件中直接进行使用,将EditText放入TextInputLayout中。
然后在Java文件中进行使用
//获取布局中的控件
final TextInputLayout textInputLayout = (TextInputLayout) findViewById(R.id.textInput);
//设置Hint信息
textInputLayout.setHint(&请输入用户名&);
//获取放在textInputLayout中的EditText
EditText editText = textInputLayout.getEditText();
if (editText != null) {
//为EditText设置事件监听,用于处理输入事件
editText.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() & 10) {
//使用textInputLayout进行消息提示
textInputLayout.setError(&输入的用户名不能超出10位&);
textInputLayout.setErrorEnabled(true);
textInputLayout.setErrorEnabled(false);
public void afterTextChanged(Editable s) {
5. Tablayout
新出来的一个布局,可以很便捷的帮我们实现选项卡的功能。要使用需要导入android.support.design.widget.TabLayout包
基本使用方式:
首先导入包,然后直接在布局文件中添加上即可。
然后在Java代码中获取到,进行设置:
TabLayout tabs = (TabLayout)findViewById(R.id.tabLayout);
tabs.addTab(tabs.newTab().setText(&tab1&));
tabs.addTab(tabs.newTab().setText(&tab2&));
tabs.addTab(tabs.newTab().setText(&tab3&));
tabs.addTab(tabs.newTab().setText(&tab4&));
tabs.addTab(tabs.newTab().setText(&tab4&));
tabs.addTab(tabs.newTab().setText(&tab4&));
tabs.addTab(tabs.newTab().setText(&tab4&));
tabs.addTab(tabs.newTab().setText(&tab4&));
这样就可以做出选项卡的效果了
6. SnackBar:
SncakBar是新出来的一款控件,他提供了一个特贴轻量级的反馈,作用类似于Toast,但是又和Toast有所区别。
官方文档的内容:
Snackbars provide lightweight feedback about an operation. They show a brief message at the bottom of the screen on mobile and lower left on larger devices. Snackbars appear above all other elements on screen and only one can be displayed at a time.
Snackbars can contain an action which is set via setAction(CharSequence, android.view.View.OnClickListener).
To be notified when a snackbar has been shown or dismissed, you can provide a Snackbar.Callback via setCallback(Callback).
SnackBar为一个操作提供了一个轻量级的回馈。它在手机屏幕的底部或者是在大屏幕设备的左下方显示一个简短的消息。SnackBar位于屏幕上所有元素的上方,并且只能显示一段时间
SnackBar可以通过setAction(CharSequence, android.view.View.OnClickListener)方法来包含一个动作
可以通过提供setCallback(Callback)接口来获取SnackBar显示和消失时的通知
基本使用方式:
类似于Toast,直接在程序中使用:
Java代码:
Snackbar snackbar = Snackbar.make(actionButton, &你点击了按钮&, Snackbar.LENGTH_LONG);
snackbar.setAction(&知道了&, new View.OnClickListener() {
public void onClick(View v) {
snackbar.dismiss();
snackbar.show();
当然了Material Design中新出现的各种特性,新控件,新布局还有很多,这只是我自己使用的一个总结,欢迎交流和分享。
Git-Hub上的一个UI测试库,遵循Material Design原则:
Material Design控件demo:谷歌设计师的Material Design实践心得
招聘信息:
前不久,我们宣布了已经发布,诸位感兴趣的话,可以去Github看看我们是怎样在这个App中实现Material Design的功能和设计细节。在这篇文章中,我将分享一些我们对于Material Design的一些设计性思考。
每年Google I/O完了后,我们都会更新Google I/O相关的APP,我们做这个
有2个目的。第一,让那些在家看直播、甚至没有机会到现场的人更身临其境的了解Google I/O大会。第二,我们用Material Design的设计语言来诠释这款应用,并且提供了源码,可以作为demo,供开发人员参考。
这款应用采用了Material Design( )的设计方法,功能实现上参考了 (Android L开发者预览),最后以合理、一致、可容性强的方式来展现内容。我们来看看这款应用的设计思路。
表面和阴影
在Material Design中,表面和阴影起到了重要的作用,能够展示出应用的层级架构。Material Design官方文档勾勒出了一系列的 ,这给予了我们很多设计上的参考,让我们知晓阴影何时应该出现。下面就是我们在设计这款应用中的&日程表&时所经历的一些迭代历程:
初次迭代、二次迭代,三次迭代
第一次迭代版本问题良多。首先APP栏下面的那层阴影让人感觉,界面中只有2张纸:一张承载了App栏,另外一张承载了标签栏和屏幕内容。而APP栏下面的那张纸承载的内容太多,太复杂:本来泼墨效果务求简约的,但是在现实生活中,纸张越大,墨匀开的速度就越慢,因此可能会造成一定程度的混淆。除了2张纸的设计思路,还有一种思路是将标签也独立成一张纸,介于APP栏和内容层之间,但是层级太多,容易让人感到分心。
第二版和第三版迭代好了不少,构建了功能界面和内容之间更为清晰的辨识感,同时让匀墨效果集中在文本、图标上。
另外一个就是&表面层&的设计概念,这个在我们的细节页面中占了很大比重,我们最开始动效是这么做的:当你在细节页面进行滚动的时候。顶部Banner会渐隐,同时会从图像转化为纯色。而图像滚动的速度是标题滚动速度的一半,造成了视差滚动效果。但是我们发觉这种效果和现实中的物理规律不服,让人感觉图像上的文字和图像不是一体的,感觉像是文字漂浮在一张纸上,两者都做运动。
第一版,升级版
在六月25号的应用升级中,我们提供了更好地方法,我们引入了一种更新颖、更简短的表面层设计概念,标题文本给人的感觉不再是悬浮的,而是实实在在的印刷在纸张上的质感。这个表面层有着一致的色彩和透明度。动效是:在下滚动时,表面层(以及上面粘附的按钮)会紧紧的卡在内容的上方,在向上滚动时,由于空间冲突,内容会插入到表面层的底部。
更符合物理规律的滚动效果
这种方法更符合Material Design设计语言的规律,而且结果更符合视觉连贯性,更有交互性,动效也更有意义。 (代码见: ,
Material Design的关键性原则之一是界面应该&大胆、图形化、有意义&,利用印刷设计的一些基本元素,达成优异的视觉指引。我们来看看这两个元素:色彩和版式对齐。
在Material Design中,UI配色提倡一种主色,一种互补色。区域较大部分的色彩采用主色的500色调,区域较小的部分例如状态栏采用深一点的色调,例如,700。
互补色需要巧妙运用,用来吸引用户对关键性元素的注意。温和的主色,搭配以稍微明亮的互补色,让应用看起来大胆、充满色彩感,凸显内容。
在I/O 应用中,我们选择了两种互补色,以便在不同情况下使用。大部分地方的互补色选取了 , 这是比较明显的互补色,有些地方选用了Light Blue 500,较为保守,在应用中,我们用这个颜色来填充&添加到日程表&这个按钮,页面指示器以及用来暗示标签栏中所选标签(代码见: & ,
互补色在APP中的应用
图像下方的话题区表面层的颜色选取根据具体话题、具体页面、具体图像的颜色来选取,基本取色与图像。我们利用Material Design文档中提供的配色表,稍微调整,以确保整体亮度的一致性,以及话题区和悬浮的视觉契合感。
下面这个图像代表了我们在配色上的探索历程。
话题区颜色去饱和和全包和版本,全都附带悬浮按钮以便对照。去饱和版本帮助评估配色表亮度的一致性。
传统印刷设计中,版式边距的考量亦很重要。而重中之重的&基线&在
中有所提及。尽管我们已经习惯于使用4dp网格来为垂直布局定型(按钮和简单地列表项是48dp,标准的工具栏是56dp),但是Material Design中,基线与之前有所不同。一般来说标题和其他文本项会对其到&第二基线(Keyline 2)&(手机是72dp,平板是80dp),这种对齐规则让界面看起来清爽、具有印刷设计的阅读节奏感。让用户得以快速阅读信息,比较符合格式塔原则。
Material Design的另外一个关键原则是&这是一种能够自适应的设计&
一个单独的底层设计系统,能够有效组织交互行为,利用空间。多种设备可以使用同样的底层系统,但是显示效果不同。每种设备上的显示效果会根据屏幕尺寸和设备交互特性而定。色彩、图标、层级感、空间关系仍要保持一致。
现在,在I/O应用中得很多界面都需要呈现话题集合,让用户选择。为了呈现集合性质的内容,Material Design提供了很多容器:、、。但是既然我们展示的是性质相同的内容,所以采取卡片不合适,因为卡片的圆角和阴影会添加太多视觉干扰,无法高效编组呈现内容。自适应网格是最好的选择,我们可以定义变化栏数和屏幕尺寸 (
) , 也可以很方便的添加文本信息。
令人愉悦的细节
在这款应用中,有两处细节我们花了大工夫,一个是触控的涟漪效果/匀开效果,另外一个是点击&添加到日程表&按钮时的小动效。
在涟漪效果样式上,我们采取了两种,一种是裁剪过得涟漪效果,一种未裁剪,同时确保可以定制涟漪的颜色,以便在不同的背景色下保证涟漪的可见(但是不要太明显,隐隐若现最好,代码见: ,)
在这个应用中,我个人最喜欢的部分是点击悬浮按钮时的动效,个性十足。
我们使用了Android L开发者预览文档中一系列新的API方法:
View.setOutline和 setClipToOutline &用来裁剪涟漪效果,以及动态阴影渲染
android:stateListAnimator&用来实现当手指按压按钮式,按钮的悬浮效果(其实是增加投影造成的视觉欺骗)
RippleDrawable 用来实现按压时所呈现的匀墨反馈效果
ViewAnimationUtils.createCircularReveal 用来显示蓝/白背景
AnimatedStateListDrawable 用来定义关键帧动画,从而改变图标状态(从&+&号变成&对勾&)
最终的结果是整款应用看起来非常美丽,且具有愉悦性,我们很满意。希望你能从我们应用的开发和设计中汲取到经验。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量10968点击量8314点击量7910点击量7820点击量7393点击量6153点击量5589点击量5244点击量4907
&2016 Chukong Technologies,Inc.
京公网安备89

我要回帖

更多关于 如何在origin中画阴影 的文章

 

随机推荐