设计原则

实体感隐喻

通过构建系统化的动效和空间合理化利用,并将两个理念合二为一,构成了实体隐喻。与众不同的触感是实体的基础,这一灵感来自我们对纸墨的研究,但是我们相信,随着科技的进步,应用前景将不可估量。

实体的表面和边缘提供基于真实效果的视觉体验,熟悉的触感让用户可以快速地理解和认知。实体的多样性可以让我们呈现出更多反映真实世界的设计效果,但同时又绝不会脱离客观的物理规律。

光效、表面质感、运动感这三点是解释物体运动规律、交互方式、空间关系的关键。真实的光效可以解释物体之间的交合关系、空间关系,以及单个物体的运动。

鲜明、形象、深思熟虑

新的视觉语言,在基本元素的处理上,借鉴了传统的印刷设计——排版、网格、空间、比例、配色、图像使用——这些基础的平面设计规范。在这些设计基础上下功夫,不但可以愉悦用户,而且能够构建出视觉层级、视觉意义以及视觉聚焦。精心选择色彩、图像、选择合乎比例的字体、留白,力求构建出鲜明、形象的用户界面,让用户沉浸其中。

Material Design设计语言强调根据用户行为凸显核心功能,进而为用户提供操作指引。

有意义的动画效果

动画效果(简称动效)可以有效地暗示、指引用户。动效的设计要根据用户行为而定,能够改变整体设计的触感。

动效应当在独立的场景呈现。通过动效,让物体的变化以更连续、更平滑的方式呈现给用户,让用户能够充分知晓所发生的变化。

动效应该是有意义的、合理的,动效的目的是为了吸引用户的注意力,以及维持整个系统的连续性体验。动效反馈需细腻、清爽。转场动效需高效、明晰。

Material 主题

android提供了三种Material Design风格Theme:

    @android:style/Theme.Material (dark version)@android:style/Theme.Material.Light (light version)    @android:style/Theme.Material.Light.DarkActionBar

我们还可以根据自己的需求继承主题,修改颜色实现我们自己的主题

<resources><!-- inherit from the material theme --><style name="AppTheme" parent="android:Theme.Material"><!-- Main theme colors --><!--   your app branding color for the app bar --><item name="android:colorPrimary">@color/primary</item><!--   darker variant for the status bar and contextual app bars --><item name="android:colorPrimaryDark">@color/primary_dark</item><!--   theme UI controls like checkboxes and text fields --><item name="android:colorAccent">@color/accent</item></style>
</resources>

Creating Lists and Cards

在程序中创建复杂的Material Design 样式的 List和Card,可以使用RecyclerView和CardView组件。

RecylerView类简化大数据集的显示和处理,通过提供:
- 布局管理者控制元素定位。
- 在通用的元素上操作上显示默认的动画,比如移除和增加元素。

使用RecyclerView组件,你需要指定一个Adapter和布局管理器,创建一个Adapter继承RecyclerView.Adapter类,具体的实现细节要根据数据集合视图的类型变化。

一个布局管理器定位Item视图在RecyclerView中,决定什么时候去回收它当他不再可见时。当重用(或者回收)一个视图时,布局管理器可能会请求适配器(Adapter)去替换子视图中的内容用不同的内容。通过这种方式回收重用视图,可以减少view的创建和避免更多的findViewById(),从而提高性能。

RecyclerView提供了以下内建的布局管理器:

LinearLayoutManager 显示Item 在一个水平或者垂直的滚动列表中。
GridLayoutManager 显示Item作为网格布局。
StaggeredGridLayoutManager 显示Item在交错的网格布局。

例子:

<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
    android:id="@+id/my_recycler_view"android:scrollbars="vertical"android:layout_width="match_parent"android:layout_height="match_parent"/>
public class MyActivity extends Activity {private RecyclerView mRecyclerView;private RecyclerView.Adapter mAdapter;private RecyclerView.LayoutManager mLayoutManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.my_activity);mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);// use this setting to improve performance if you know that changes// in content do not change the layout size of the RecyclerViewmRecyclerView.setHasFixedSize(true);// use a linear layout managermLayoutManager = new LinearLayoutManager(this);mRecyclerView.setLayoutManager(mLayoutManager);// specify an adapter (see also next example)mAdapter = new MyAdapter(myDataset);mRecyclerView.setAdapter(mAdapter);}...
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {private String[] mDataset;// Provide a reference to the views for each data item// Complex data items may need more than one view per item, and// you provide access to all the views for a data item in a view holderpublic static class ViewHolder extends RecyclerView.ViewHolder {// each data item is just a string in this casepublic TextView mTextView;public ViewHolder(TextView v) {super(v);mTextView = v;}}// Provide a suitable constructor (depends on the kind of dataset)public MyAdapter(String[] myDataset) {mDataset = myDataset;}// Create new views (invoked by the layout manager)@Overridepublic MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {// create a new viewView v = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_text_view, parent, false);// set the view's size, margins, paddings and layout parameters...ViewHolder vh = new ViewHolder(v);return vh;}// Replace the contents of a view (invoked by the layout manager)@Overridepublic void onBindViewHolder(ViewHolder holder, int position) {// - get element from your dataset at this position// - replace the contents of the view with that elementholder.mTextView.setText(mDataset[position]);}// Return the size of your dataset (invoked by the layout manager)@Overridepublic int getItemCount() {return mDataset.length;}
}

CardView继承FrameLayout类,通过它可以显示信息在卡片内部,并且在不同的平台上有统一的样式。CardView组件可以有阴影和圆角。

创建有阴影的Card,使用card_view:cardElevation属性。CardView 使用真实的高度和动态阴影在Android5.0(API 21)和更高版本,较早的版本则使用传统的阴影。

使用这些属性去定制CardView的外观:

使用card_view:cardCornerRadius属性设置圆角的半径,在布局文件中。
使用CardView.setRadius方法设置圆角的半径在java代码中。
设置卡片的背景颜色,使用card_view:cardBackgroundColor属性。

下面是一个在xml布局文件中包含一个CardView的示例:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
... >
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="200dp"
android:layout_height="200dp"
card_view:cardCornerRadius="4dp"><TextView
android:id="@+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v7.widget.CardView>
</LinearLayout>

Defining Shadows and Clipping Views

Material Design 为用户界面元素引入了深度这个元素。深度帮助用户理解各个元素之间的重要关联和帮助用户关注他们手上的任务。

视图的高度

视图的高度(elevation),通过Z属性表现,通过他的阴影确定:Z值更高的视图投影出更大的阴影。视图只在Z=0的平面上投影处阴影;他们不会投影阴影在其他放在下面的视图上面和高于Z=0的平面。

有更高Z值的视图挡住Z值较低的视图。无论如何,Z值不会影响到View的大小。

一个View的Z值有两个组成部分,elevation(高度)和translation(平移).elevation是一个静态部分,translation 用于动画:

  • Z = elevation + translationZ


在布局文件中设置evelation 使用android:elevation,在代码中使用View.setElevation()方法。
设置一个视图的平移,使用View.setTranslationZ()方法。

新的方法ViewPropertyAnimator.z()和ViewPropertyAnimator.translationZ()可以让你更容易的变动视图的高度。

自定义视图阴影和轮廓

背景是一个圆角矩形:

<!-- res/drawable/myrect.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="rectangle"><solid android:color="#42000000" /><corners android:radius="5dp" />
</shape>

当这个背景drawable作为视图的轮廓,视图投射出圆角阴影。提供一个自定义的轮廓,可以覆盖默认视图阴影的形状。
在自己的代码中自定义一个轮廓:

  1. 继承ViewOutlineProvider类
  2. 重写getOutline()方法
  3. 在视图中设置轮廓,使用View.setOutlineProvider()方法

你可以创建椭圆和圆角矩形轮廓使用OutLine类中的方法。视图默认的outline provider会根据视图的背景来生成轮廓。可以设置视图的outline provider为null,来阻止投射阴影。

裁剪视图

裁剪视图功能,可以让你更容易的改变视图的形状。你可以裁剪视图为了和其他的设计元素保持一致,或者改变成形状响应用户的输入。你可以裁剪一个视图的轮廓使用View.setClipToOutLine()方法,或者android:clipToOutline属性。只有矩形,圆角矩形,圆圈的轮廓支持被裁剪,可以使用Outline.canClip()方法检测是否支持被裁剪。

裁剪视图到一个drawable的形状,设置drawable作为视图的背景(让视图显示在其上),并且调用View.setClipToOutline()方法。

Working with Drawables

图片资源着色

在android 5.0(api 21)和更高版本,可以着色bitmap和.9 png 通过定义透明度遮盖。你可以着色通过使用颜色资源或者主题的属性去解析颜色资源(比如,?android:attr/colorPrimary).通常我们创建一次,然后资源自适应主题。

你可以给BitmapDrawable或NinePatchDrawable对象着色使用setTint()方法。你可以可以在布局文件中使用android:tint和android:tintMode属性设置着色颜色和着色模式。

从图片中抽取高亮颜色

support library r21和更高的版本中包括了Palette类,可以从一个图片中提取高亮颜色。这个类可以提起以下几种突出颜色:

  • Vibrant 充满生机
  • Vibrant dark 亮的充满生机
  • Muted 柔和
  • Muted dark 暗的柔和
  • Muted light 亮的柔和

传递一个Bitmap对象给静态方法Palette.generate(),它会在后台线程帮你从后台线程提取颜色。如果你不能使用这个后台线程,使用Palette.generateAsync()方法,并且设置一个监听器listener.

Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
public void onGenerated(Palette palette) {
// Do something with colors...
palette.getVibrantColor(Color.BLACK); //get a color in rgb value
}
});

创建矢量drawables

在android 5.0和更高版本中,可以创建矢量的drawable,在缩放的时候不会失真。你只需要定义一个矢量图片文件,相反的,使用bitmap位图则需要针对不同的分辨率创建多个文件。创建一个矢量图片,你需要说明图形的详细,在xml文件的标签下。

<!-- res/drawable/heart.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"<!-- intrinsic size of the drawable -->android:height="256dp"android:width="256dp"<!-- size of the virtual canvas -->android:viewportWidth="32"android:viewportHeight="32"><!-- draw a path --><path android:fillColor="#8fff"android:pathData="M20.5,9.5c-1.955,0,-3.83,1.268,-4.5,3c-0.67,-1.732,-2.547,-3,-4.5,-3C8.957,9.5,7,11.432,7,14c0,3.53,3.793,6.257,9,11.5c5.207,-5.242,9,-7.97,9,-11.5C25,11.432,23.043,9.5,20.5,9.5z" />
</vector>

Defining Custom Animations

自定义触摸反馈

触摸反馈在Material Design中在触摸点提供了一个即时视觉确认当用户作用在UI元素。按钮的默认触摸反馈动画是使用了新的RippleDrawable类,它会是波纹效果在不同状态间变换。

大多数情况下,我们可以使用这个功能通过在xml文件中定义背景:

?android:attr/selectableItemBackground 有界限的波纹
?android:attr/selectableItemBackgroundBorderless 可以超出视图区域的波纹(是21新添加的api)

另外,还以使用ripple元素定义RippleDrawable作为一个xml资源。

你可以给RippleDrawable对象分配一个颜色。使用主题的android:colorControlHighlight属性可以改变默认的触摸反馈颜色。

使用渐变效果

渐变动画为用户提供视觉上的持续性挡显示或者隐藏一组界面元素。ViewAnimationUtils.createCircularReveal()方法使你可以使用动画效果来显示或者隐藏一个视图。

显示一个先前隐藏的视图:

// previously invisible view
View myView = findViewById(R.id.my_view);// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());// create the animator for this view (the start radius is zero)
Animator anim =ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();

隐藏一个先前显示的视图:

// previously visible view
final View myView = findViewById(R.id.my_view);// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;// get the initial radius for the clipping circle
int initialRadius = myView.getWidth();// create the animation (the final radius is zero)
Animator anim =ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);myView.setVisibility(View.INVISIBLE);}
});// start the animation
anim.start();

自定义activity转换效果

activity间转换在Material Design程序中提供不同状态间的视觉连接通过在公用元素上动作或者转换。你可以为进入或退出的转换自定义动画,共享元素在不同的activity之间的转换效果。
android 5.0(api 21)提供以下进入和退出效果:

  • explode(爆裂) - 从场景中间移动视图进入或者退出
  • slide(滑动) - 视图从场景的一个边缘进入或者退出
  • fade(淡入淡出)从场景添加或者移除一个视图通过改变他的透明

Android5.0(api 21)也支持共享元素过渡效果:

  • changeBounds - 改变目标视图的布局边界
  • changeClipBounds - 裁剪目标视图边界
  • changeTransform - 改变目标视图的缩放比例和旋转角度
  • changeImageTransform -改变目标图片的大小和缩放比例

例子:
首先,使用在从material theme继承的样式中,使用android:windowContentTransitions属性开启窗口内内容过渡效果。也可以在样式定义中第一进入,退出,共享元素的效果:

<style name="BaseAppTheme" parent="android:Theme.Material"><!-- enable window content transitions --><item name="android:windowContentTransitions">true</item><!-- specify enter and exit transitions --><item name="android:windowEnterTransition">@transition/explode</item><item name="android:windowExitTransition">@transition/explode</item><!-- specify shared element transitions --><item name="android:windowSharedElementEnterTransition">@transition/change_image_transform</item><item name="android:windowSharedElementExitTransition">@transition/change_image_transform</item>
</style>

示例中的过渡change_image_transform定义如下:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"><changeImageTransform/>
</transitionSet>

changeImageTransform元素对应ChangeImageTransform类

在代码中启用窗口内容过渡效果,使用Window.requestFeature()方法:

// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);// set an exit transition
getWindow().setExitTransition(new Explode());

在代码中定义过渡效果,使用下面的方法,并传一个Transition对象:

Window.setEnterTransition()
Window.setExitTransition()
Window.setSharedElementEnterTransition()
Window.setSharedElementExitTransition()

如果你为一个activity开启过渡并且设置了一个退出过渡效果,过渡效果会在你打开其他activity的时候激活,像这样:

startActivity(intent,ActivityOptions.makeSceneTransitionAnimation(this).toBundle());

打开一个activity包含一个共享元素

  1. 在theme中开启窗口内容过渡效果
  2. 在style中指定一个共享元素过渡效果
  3. 在xml中定义过渡样式
  4. 在两个activity的样式文件中给共享元素分配一个相同的名字使用android:transitionName属性
  5. 使用ActivityOptions.makeSceneTransitionAnimation()方法。
// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(this, Activity2.class);// create the transition animation - the images in the layouts// of both activities are defined with android:transitionName="robot"ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, androidRobotView, "robot");// start the new activitystartActivity(intent, options.toBundle());}
});

使用曲线运动

视图状态改变动画

StateListAnimator定义动画当视图的状态改变的时候运行,下面的例子是怎么在xml中定义一个StateListAnimator动画:

<!-- animate the translationZ property of a view when pressed -->
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true"><set><objectAnimator android:propertyName="translationZ"android:duration="@android:integer/config_shortAnimTime"android:valueTo="2dp"android:valueType="floatType"/><!-- you could have other objectAnimator elementshere for "x" and "y", or other properties --></set></item><item android:state_enabled="true"android:state_pressed="false"android:state_focused="true"><set><objectAnimator android:propertyName="translationZ"android:duration="100"android:valueTo="0"android:valueType="floatType"/></set></item>
</selector>

给视图附加自定义的视图状态动画,使用selector元素在xml文件中定义一个动画祥例子中这样,给视图分配动画使用android:stateListAnimator属性。在代码中使用,使用AnimationInflater.loadStateListAnimator()方法,并且使用View.setStateListAnimator()方法。

可绘矢量动画

可绘制矢量图在拉伸时不会失真。AnimatedVectorDrawable类让你可以在可绘制矢量图上面作用动画。

通常需要在三个xml文件中定义可动的矢量图:

  • 一个矢量图使用元素,放在res/drawable/下。
  • 一个可动的矢量图使用元素,放在res/drawable/下。
  • 一个或更多个动画对象使用元素,放在res/anim/下。

可动矢量图可以使用和元素。元素定义一系列路径或者子组,元素定义可绘图的路径。

兼容性

Use the Support Library

The v7 Support Libraries r21 and above includes the following material design features:

  • Material design styles for some system widgets when you apply one of the Theme.AppCompat themes.
  • Color palette theme attributes in theTheme。
  • AppCompat themes.
  • The RecyclerView widget to display data collections.
  • The CardView widget to create cards.
  • The Palette class to extract prominent colors from images.

The Theme.AppCompat themes provide material design styles for these widgets:

  • EditText
  • Spinner
  • CheckBox
  • RadioButton
  • SwitchCompat
  • CheckedTextView

Create Apps with Material Design相关推荐

  1. Creating Apps With Material Design —— Defining Custom Animations

    转载请注明 http://blog.csdn.net/eclipsexys 翻译自Developer Android,时间仓促,有翻译问题请留言指出.谢谢 定义动画 在材料设计动画让用户与您的应用程序 ...

  2. Creating Apps With Material Design —— Creating Lists and Cards

    转载请注明 http://blog.csdn.net/eclipsexys 翻译自Developer Android.时间仓促,有翻译问题请留言指出,谢谢 创建Lisst和Cards 在你的应用程序创 ...

  3. Material Design设计规范

    作为技术开发者需不需要了解设计规范?个人认为非常需要,一个交流的需要,另一就是了解相关的设计才能储备相应地知识,知道UI开发的方向.这问题非常希望读者能留言讨论. **Android**的设计风格变迁 ...

  4. (10.1.4) Material Design设计规范

    下面的内容是在<移动互联网沙龙开年篇>做的一点分享,关于Material Design设计规范相关的. 作为技术开发者需不需要了解设计规范?个人认为非常需要,一个交流的需要,另一就是了解相 ...

  5. 值得一看!2018年最优秀的9个Android Material Design Apps!

    今年4月,谷歌Gmail推出了全新的设计外观,全新的配色方案,更多的空白区域和精致的图标.也带来了Material Design 的一些改变 – Material Theming (材料主题),旨在自 ...

  6. Android学习 - Material Design设计规范

    作为技术开发者需不需要了解设计规范?个人认为非常需要,一个交流的需要,另一就是了解相关的设计才能储备相应地知识,知道UI开发的方向.这问题非常希望读者能留言讨论.Android的设计风格变迁可以划分到 ...

  7. Android Material Design按钮样式

    本文翻译自:Android Material Design Button Styles I'm confused on button styles for material design. 我对材质设 ...

  8. ANDROID L——Material Design综合应用(Demo)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Material Design: Material Design是Google推出的一个全 ...

  9. Material Design风格登录注册

    本文实现了以下功能 完整的代码和样例托管在Github 当接口锁定时,防止后退按钮显示在登录Activity 上. 自定义 ProgressDialog来显示加载的状态. 符合材料设计规范. 悬浮标签 ...

最新文章

  1. 【C++】C++对象模型:对象内存布局详解(C#实例)
  2. Python——科赫曲线绘制
  3. 01 | 从神经元说起:数学篇
  4. xps15u盘装linux,Dell XPS 15 9560 安装 Ubuntu 18.04
  5. Android开发笔记(一百三十二)矢量图形与矢量动画
  6. 【GCN】2021年,我终于决定入门GCN
  7. lua开发/ 腾讯 Bugly / 截屏 / 遮罩
  8. H5 游戏 俄罗斯方块 双人互动游戏
  9. AKULAKU笔试题(还有1题未答)
  10. 让Boo成为头等语言的新尝试
  11. Android 手机红外遥控器实现
  12. SpringMVC视频-佟刚-专题视频课程
  13. 中标麒麟+QT+达梦数据库
  14. 蒙特卡洛 c语言,从伪随机数的产生到高大上的蒙特卡洛算法(C语言实现)
  15. MATLAB中audioread函数用法
  16. Vue脚手架创建项目流程
  17. linux学习(一)虚拟机界面全屏
  18. 深圳大数据培训:大数据技术可以解决哪些问题?
  19. 完美世界手游不显示服务器,完美世界手游怎么玩的角色不见了
  20. uefi启动 多硬盘gtp_BIOS支持UEFI,整个硬盘GUID(GPT)分区,能否安装原版Mac OS

热门文章

  1. Java 使用Graphics类画简单的生日蛋糕
  2. vue鼠标停留在表格table2秒后,显示悬浮快(计算模块)
  3. 摄影师必带三脚架的六个原因
  4. 会展管理SaaS如何利用帮助中心来提升服务水平?
  5. java Tree1.1计算器
  6. Kylin 在一点资讯的实践
  7. 思维导图怎样绘制?适合小学生画思维导图的软件有哪些
  8. 机器人画家,三分钟搞定一幅人物黑白肖像
  9. CAD绘制剖面图的详细步骤和方法
  10. 4个良心亲民的微信小程序,要是早点知道就好了!