http://blog.csdn.net/bbld_/article/details/40400343
Android Material Design-Getting Started(入门)-(一)
要创建materialdesign的app,我们按照如下的几个步骤:
1. 回顾material design的规范。
2. 在app中使用material主题样式。
3. 跟随material design准则去创建你的布局。
4. 在你的view控件指定elevation(高度,可使控件投影的仰角变化)属性来投射阴影。
5. 使用系统的控件来设计列表和卡片。
6. 在你的app中使用自定义动画。
保持向后兼容
你可以在你的app中添加许多material design的功能特性,同时对Android5.0之前的版本保持兼容。要获得更多这方面的信息请参看保持程序的兼性(MaintainingCompatibility)。
采用material design更新你的app
要更新现有的app去包含体现material design,(你应该)跟随materialdesign的规范指导去更新你的布局。另外,还要确保结合深入、触摸反馈和动画。
采用material design创建新的app
如果你要通过materialdesign创建一个全新的app,material design的规范指导为你提供了一个紧密结合的设计框架。在Android框架设计和你的应用开发中遵循这些指导并使用新的功能特性。
使用Material主题
在你的app中使用material主题,(你应该)继承指定的主题:android:Theme.Material。
- <!– res/values/styles.xml –>
- <resources>
- <!– your theme inherits from the material theme –>
- <style name=“AppTheme” parent=“android:Theme.Material”>
- <!– theme customizations –>
- </style>
- </resources>
该material主题提供了已经更新的系统控件使得让你可以去设置它们(控件)的调色板和触摸反馈的默认动画和activity的过渡动画效果。获取更多的细节,请参看Using the Material Theme [Android Material Design-Using the Material Theme(使用Material主题)-(二)]。
设计你的布局
除了使用或定制material主题,你的布局同样应该符合materialdesign的规范指导。 当你设计布局时,需要特别注意一下几点:
l 基线网格
l 关键的边
l 间隔
l 触摸目标的大小
l 布局结构
在你控件中指定elevation (属性)
控件能够投射阴影,此外elevation属性值决定了一个view控件的影子和它绘制顺序的大小。要设置一个view控件的elevation属性,可以在布局中使用android:elevation属性去设置。
- <TextView
- android:id=“@+id/my_textview”
- android:layout_width=“wrap_content”
- android:layout_height=“wrap_content”
- android:text=“@string/next”
- android:background=“@color/white”
- android:elevation=“5dp” />
新的translationZ属性可以让你创建反映在临时更改view控件levation属性时的动画效果。Elevation属性改变可能是有用的当响应触摸手势时。
更多详情,请参看Defining Shadows and Clipping Views(定义阴影和裁剪视图)。
创建列表和卡片(控件)
RecyclerView是一个支持不同的布局类型同时提高了显示动态视图性能的增强版ListView。
CardView是一个卡片视图,可以在卡片内显示信息。可以使用下面的方式创建CardView。
- <android.support.v7.widget.CardView
- android:id=“@+id/card_view”
- android:layout_width=“200dp”
- android:layout_height=“200dp”
- card_view:cardCornerRadius=“3dp”>
- …
- </android.support.v7.widget.CardView>
更多的信息,参看Creating Lists and Cards(创建列表和卡片)。
自定义你的动画
Android 5.0(API级别21)包含许多新的API使得你可以在app中去创建自定义的动画。例如,你可以启用activity的过渡动画和定义activity的退出动画:
- public class MyActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // enable transitions
- getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
- setContentView(R.layout.activity_my);
- }
- public void onSomeButtonClicked(View view) {
- getWindow().setExitTransition(new Explode());
- Intent intent = new Intent(this, MyOtherActivity.class);
- startActivity(intent,
- ActivityOptions
- .makeSceneTransitionAnimation(this).toBundle());
- }
- }
当你从这个activity跳转到另一个activity时,退出过渡动画是激活的。
要了解更多关于新动画的API,请参看Defining Custom Animations(自定义动画)。
Android Material Design-Using the Material Theme(使用Material主题)-(二)
新的material主题提供了:
l 可以让你设置调色板的系统控件。
l 为控件(设计的)触摸反馈动画。
l Activity过渡动画
你可以根据调色板,控制你定制的material主题。你也可以调整标题栏(Action Bar),并使用主题属性的状态栏,如图三。
提供的系统控件有了全新的设计和触摸反馈动画。你可以在app中自定义调色板,触摸反馈的动画,和activity的过渡动画。
Material主题定义为如下:
l @android:style/Theme.Material (dark version)
l @android:style/Theme.Material.Light (light version)
l @android:style/Theme.Material.Light.DarkActionBar
更多可使用的material样式,请参阅R.style的API参考。
图一:dark material theme 图二:light material theme
注意:这个material主题只有在Android 5.0(API级别21)以上才可用。在v7支持库中提供了一些控件的material主题样式和调色板的兼容支持,要了解更多信息,请参阅Maintaining Compatibility(保持兼容性)。
自定义调色板
要定义主题的基础颜色去适应你的(app设计)品牌,定义你自己的颜色在(material)主题中使用这个颜色属性:
- <resources>
- <!– inherit from the material theme –>
- <style name=”AppTheme”parent=”android:Theme.Material”>
- <!– Main theme colors –>
- <!– your app branding color for the app bar –>
- <itemnameitemname=“android:colorPrimary”>@color/primary</item>
- <!– darker variant for thestatus bar and contextual app bars –>
- <itemnameitemname=“android:colorPrimaryDark”>@color/primary_dark</item>
- <!– theme UI controls likecheckboxes and text fields –>
- <itemnameitemname=“android:colorAccent”>@color/accent</item>
- </style>
- </resources>
自定义状态栏
使用该material主题,你可以轻松地自定义状态栏,你也可以指定一个颜色基调去适应你的(app设计)品牌并 提供足够的对比度去显示白色的状态栏图标。要自定义状态栏的颜色,你可以在继承了material主题后使用android:statusBarColor属性。默认情况下android:statusBarColor属性的值是android:colorPrimaryDark。
你也可以自己定义状态栏的表现形式。例如,如果你想在一张照片之上显示透明的状态栏,用一种微妙的深色渐变确保白色状态图标是可见的。要做到这点,(应该)把android:statusBarColor属性设置为@android:color/transparent(透明),同时根据需要调整窗口的标识。你也可以使用Window.setStatusBarColor()方法用于动画或者褪色(fading)。
图三:自定义material主题
注意:状态栏应该总是跟工具栏有一个明显的界定,除非你在这里展示了边缘到边缘之间丰富的图像或者媒体内容,(或者你)使用了渐变确保了图标仍然可见的情况下。
主题的个人建议
在XML布局里的元素也可以定义android:theme属性,该属性是引用主题资源。这个属性修改的主题元素和任何的子元素是用于在一个特别的接口中改变主题颜色调色板。
Demo演示效果:
Demo源码下载地址:http://download.csdn.net/detail/bbld_/8073913
Android Material Design-Creating Lists and Cards(创建列表和卡片)-(三)
为了在你的app中用material design风格去创建复杂的列表和卡片(布局界面),你可以使用RecyclerView和CardView控件。
创建列表
该RecyclerView控件是比ListView更先进、灵活的版本。这个控件是一个的容器,用于显示有大量数据的view并且在有限制数量的view下能够高效地滚动。当你有数据集合时,它的元素在用户操作发生改变时或者在网络事件下发生改变时,(这时你就该)使用RecyclerView。
该RecyclerView类通过以下几点简化了显示和处理大量的数据:
l 为(管理)位置item的布局管理器
l 为通用的item操作显示的默认动画,例如删除或者增加item
你还可以灵活地自定义RecyclerView控件的布局管理器和它的动画效果。
图一:RecyclerView控件
要使用RecyclerView控件,你必须指定一个适配器和一个布局管理器。要创建适配器,需继承RecyclerView.Adapter类。继承实现的细节取决于你的数据情况和item上view的类型。
更多的信息,请参阅接下来的例子。
一个布局管理器定位RecyclerView内部的item视图(view),并确定何时重用对用户不在可见的item视图(view)。为了重用(或者回收)视图(view),布局管理器可能会要求适配器使用数据集合中的不同的数据去替换视图(view)的内容。通过这种方式回收视图(view)避免产生不必要的视图(view)或执行代价高的findViewById()方法,提高了(RecyclerView的)性能。
RecyclerView提供这些内置的布局管理器:
l LinearLayoutManager(用来)显示垂直或水平滚动的列表项
l GridLayoutManager(用来)显示网格中的item(项)
l StaggeredGridLayoutManager(用来)显示交错的网格item(项目)
可以通过继承RecyclerView.LayoutManager类来自定义自己的布局管理器。
动画
在RecyclerView中默认是开启了添加和删除items时的动画的。要自定义这些动画,继承RecyclerView.ItemAnimator类,并使用RecyclerView.setItemAnimator()方法。
例子
图二:使用RecyclerView的列表
下面的代码示例演示如何将RecyclerView添加到布局中:
- <!– 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”/>
一旦你在布局中添加了RecyclerView控件后,(在activity中)绑定控件,将其连接到一个布局管理器中,并给他附上要显示的数据适配器。
- public class MyActivity extends Activity {
- private RecyclerView mRecyclerView;
- private RecyclerView.Adapter mAdapter;
- private RecyclerView.LayoutManager mLayoutManager;
- @Override
- protected 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 RecyclerView
- mRecyclerView.setHasFixedSize(true);
- // use a linear layout manager
- mLayoutManager = new LinearLayoutManager(this);
- mRecyclerView.setLayoutManager(mLayoutManager);
- // specify an adapter (see also next example)
- mAdapter = new MyAdapter(myDataset);
- mRecyclerView.setAdapter(mAdapter);
- }
- …
- }
该适配器提供数据集中对item(项)的访问,创建item对应的视图(view),还有在原来的item不在可见时用新的数据替代了一些的视图(view)。下面的代码显示了一个简单的实现,它由一个字符串数组的数据集用item上的TextView控件显示:
- 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 holder
- public static class ViewHolder extends RecyclerView.ViewHolder {
- // each data item is just a string in this case
- public 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)
- @Override
- public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
- int viewType) {
- // create a new view
- View 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)
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- // – get element from your dataset at this position
- // – replace the contents of the view with that element
- holder.mTextView.setText(mDataset[position]);
- }
- // Return the size of your dataset (invoked by the layout manager)
- @Override
- public int getItemCount() {
- return mDataset.length;
- }
- }
创建卡片
CardView继承了FrameLayout类,并让你在里面的卡片中(显示)有跨平台一致性的外观。CardView控件可以有阴影和圆角(效果)。
要创建具有阴影效果的卡片,可以使用card_view:cardElevation属性。CardView会在Android5.0(API级别21)以上的系统中使用真实高程(elevation)和动态阴影,(而)在较低的系统版本中会回落到程序式的阴影效果显示。欲了解更多信息,请参阅Maintaining Compatibility(保持兼容性)。
使用这些属性来定制CardView控件的外观:
l 在布局中设置圆角半径,使用card_view:cardCornerRadius属性
l 在代码中设置圆角半径,使用CardView.setRadius方法
l 要设置一个卡片的背景颜色,使用card_view:cardBackgroundColor属性
下面的代码示例显示了如何在你的布局里添加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>
更多的信息民情参阅CardView的API文档。
图三:卡片示例
添加依赖
RecyclerView和CardView控件都是v7支持库的一部分。要在项目中使用这些控件,添加下面的Gradle依赖在你的程序模块中:
- dependencies {
- …
- compile ‘com.android.support:cardview-v7:21.0.+’
- compile ‘com.android.support:recyclerview-v7:21.0.+’
- }
———————————————————————— 分割线 ————————————————————————–
Elcipse中添加RecyclerView和CardView的依赖
首先确保你的sdk里的Extras里的support library项是最新的
然后进入sdk文件夹里的如下目录里,把appcompat和cardview项目导入到eclipse的工作空间,而recyclerview则不需要了,因为里面就jar文件没有资源文件。
导入appcompat和项目后,需要把recyclerview文件夹里的jar包复制到appcompat项目的libs文件夹里然后eclipse就会相当于自动帮我们对jar包build path了,如下:
而cardview是作为一个项目导进来的,因为它需要一些自己的资源文件,如下:
我们需要把cardview项目作为Library项目去给appcompat项目依赖,这样在我们自己的项目中就只需添加appcompat依赖就好了不用再添加cardview项目的依赖。
这样我们就算完成了~可以在我们自己的项目中使用了。
Demo演示示例:
Demo源码下载地址:http://download.csdn.net/detail/bbld_/8078205
Android Material Design-Defining Shadows and Clipping Views(定义阴影和裁剪视图)-(四)
Material Design引入了深度的UI元素。深入帮助用户了解每个元素的相对重要性,并把注意力集中到手头上正在做的事情。
一个视图(控件),由Z属性表示的高程(elevation),决定了它的影子的大小:有更高的Z值得视图就具有更大的阴影。视图仅仅只投下在Z=0平面上的阴影;它们并不投影在在它们下面和上面Z=0平面的其它视图中。
具有较高Z值视图(控件)会挡住较低Z值的视图。但是,一个视图的Z值并不会影响到该视图的大小。
当控件暂时越过平面视图执行某些操作时,高程对创建动画是有用的。
在你的视图(控件)中指定高程(elevation)
一个视图的Z值由两部分组成:高程和转换。高程是静态分量,转换是用于动画的。
Z = elevation +translationZ
图一:具有不同elevation属性值的视图控件的阴影
要在布局中设置视图控件的高程,使用android:elevation属性。要在代码中去设置视图的高程,使用View.setElevation()方法。
要设置一个视图的转换(translation),使用View.setTranslationZ()方法。
新的ViewPropertyAnimator.z()和ViewPropertyAnimator.translationZ()方法能让你轻松地进行视图高程的更改。欲了解更多的信息,请参阅请参阅ViewPropertyAnimator的API文档和PropertyAnimation(属性动画)的开发者指引。
你也可以使用StateListAnimator以声明方式来指定这些动画。对于当状态改变时触发动画的一些情况,这是特别有用的,比如用户按下了一个按钮。更多的信息,请参阅Animate View State Changes(Defining Custom Animations(自定义动画))。
Z值是像X和Y值那样,在同一个(图形)单位中测量的。
自定义视图阴影和轮廓
一个视图的背景绘制决定了其阴影的默认形状。轮廓表示图形对象的外部形状,并限定了触摸反馈的波纹(ripple)区域。
请看下面的视图(TextView),定义了背景的图片资源:
- <TextView
- android:id=“@+id/myview”
- …
- android:elevation=“2dp”
- android:background=“@drawable/myrect” />
背景资源被定义为带有圆角的矩形。
- <!– 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>
该视图控件蒙上了带有圆角的阴影,因为背景图片资源定义了这个视图的轮廓。提供自定义的轮廓去覆盖视图阴影的默认形状。
在你的代码中自定义视图的轮廓:
1. 继承ViewOutlineProvider类
2. 重写getOutline() getOutline()方法
3. 使用View.setOutlineProvider()方法分配新的轮廓给你的视图
通过Outline类里的方法,你可以创建带圆角的椭圆和矩形形状。视图的默认轮廓提供者(provider)是从视图的背景来获得其轮廓的。为了防止为视图蒙上阴影,设置它的轮廓提供者为空。
裁剪视图
裁剪视图能让你轻松地改变视图的形状。你可以为了一致性而使用其它的设计元素裁剪视图或者为了响应用户的输入改变视图的形状。你可以使用View.setClipToOutline()方法或者使用android:clipToOutline属性来裁剪视图自己的轮廓形状。只有矩形、圆形、圆角矩形的轮廓支持裁剪,这是由Outline.canClip()方法来决定的。
为了裁剪视图得到指定的形状的图像资源,设置视图的背景资源(如上面所示),并调用View.setClipToOutline方法。
裁剪视图是一个代价较高的操作,所以不要使形状看起来生动而去裁剪视图,实现这样的效果你应该使用Reveal Effect(Defining Custom Animations(自定义动画))动画。
demo比较简单,就上面的两片代码就不贴上来了。
Android Material Design-Working with Drawables(使用Drawable)-(五)
下面的几点drawables 的功能帮助你在你的app中实现material design:
l 可绘制着色
l 突出的颜色提取
l 矢量可绘性
本章节向你展示了怎么在你的app中使用这些功能。
色调Drawable资源
如果使用Android5.0(API级别21)以上的系统版本,你可以着色位图和9patch图作为透明度蒙板。你可以使用颜色资源或者主题属性中的颜色资源(例如,?android:attr/colorPrimary)给它们着色。通常,你只需一次即可创建这些资源,并自动将它们上色以匹配你的主题。
你可以使用setTint()方法给位图资源或者9patch资源对象着色。你还可以在你的布局中使用android:tint属性和android:tintMode属性设置着色的颜色和模式。
从图像中提取突出的颜色
Android r21或以上的支持库中包含了Palette类,它能让你从图像中提取突出的颜色。这个类能提取以下突出的颜色:
l Vibrant(充满活力的)
l Vibrant dark(充满活力的黑)
l Vibrant light(充满活力的亮)
l Muted(柔和的)
l Muted dark(柔和的黑)
l Muted lighr(柔和的亮)
要提取这些颜色,在你加载图片的后台线程中传递一个位图对象给Palette.generate()静态方法。如果你不适用线程,则调用Palette.generateAsync()方法并且提供一个监听器去替代。
你可以在Palette类中使用getter方法来从检索突出的颜色,比如Palette.getVibrantColor。
要在你的项目中使用Palette类,增加下面的Gradle依赖到你的程序的模块(module)中:
- dependencies {
- …
- compile ‘com.android.support:palette-v7:21.0.+’
- }
补充:在Eclipse中使用Palette类:
很简单,把sdk里的extras里的v7支持库里的palette支持jar包复制到你项目的libs文件夹即可。
更多的信息,请参阅Palette类的API文档说明。
创建矢量(vector)Drawables
在Android 5.0(API级别21)或以上的系统中,则可以定义矢量drawables,它可以在不失清晰度的情况下进行缩放。你仅仅需要需要一个矢量图片的资源文件,而需要为每个屏幕密度设置一个资源文件。要创建一个矢量图片,你需要定义形状元素的细节在<vector>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.5
- c-1.955,0,-3.83,1.268,-4.5,3
- c-0.67,-1.732,-2.547,-3,-4.5,-3
- C8.957,9.5,7,11.432,7,14
- c0,3.53,3.793,6.257,9,11.5
- c5.207,-5.242,9,-7.97,9,-11.5
- C25,11.432,23.043,9.5,20.5,9.5z” />
- </vector>
矢量图像在Android中被表示为VectorDrawable对象。更多有关pathData语法的信息,请参阅SVG Path 的文档参考。更多有关动画矢量drawable属性,请参阅AnimatingVector Drawables(Defining Custom Animations(自定义动画))。
Demo演示效果:
demo源码下载地址:http://download.csdn.net/detail/bbld_/8094905
Android Material Design-Defining Custom Animations(自定义动画)-(六)
用户跟你的app进行交互时,material design中的动画给予用户动作的反馈和提供视觉的一致性(感受)。Material主题提供了一些默认的按钮和activity过渡的动画效果,而在Android 5.0(API级别21)或以上的系统版本中你可以自定义这些动画,还可以创建新的动画:
l Touch feedback(触摸反馈)
l Circular Reveal(循环显示)
l Activity transitions(Activity过渡)
l Curved motion(曲线运动)
l View state changes(视图状态改变)
自定义触摸反馈
当用户与用户界面进行交互时,materialdesign中的触摸反馈在触摸点上提供了一种瞬时视觉确认。按钮的默认触摸反馈动画使用新的RippleDrawable类,它使用涟漪(波纹)效应在不同状态间转换。
在大多数情况下,你应该在你的布局XML文件中使用如下的方法去指定视图的背景:
l ?android:attr/selectableItemBackground for a bounded ripple(有界的波纹)
l ?android:attr/selectableItemBackgroundBorderless for a ripple that extends beyond the view(能越界的波纹)
注意:selectableItemBackgroundBorderless是API级别21上的新属性。
或者,你可以定义一个RippleDrawable作为波纹元素的XML资源
你可以给RippleDrawable对象指定一种颜色。要更改默认的触摸反馈颜色,使用主题的android:colorControlHighlight属性。
更多的信息,请参阅RippleDrawable类的API文档说明。
使用揭示效果
当你显示或隐藏一组UI元素时,显示动画为用户提供视觉的连续性(感受)。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 = myView.getWidth();
- // create and start the animator for this view
- // (the start radius is zero)
- Animator anim =
- ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
- 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() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- myView.setVisibility(View.INVISIBLE);
- }
- });
- // start the animation
- anim.start();
自定义Activity的过渡
在materialdesign的app中Activity的过渡中,手势产生的不同状态和常见的元素之间的转换(都)提供了视觉的连接。在activities之间,你可以为进入、退出、共享元素的过渡指定自定义动画。
l 一个进入的过渡(动画)决定activity中的所有的视图怎么进入屏幕。例如,在分解(explode)进入过渡(动画)中,所有视图从屏幕外进入并且一起飞向屏幕中心。
l 一个退出的过渡(动画)决定一个activity中的所有视图怎么退出屏幕。例如,在分解(explode)退出过渡(动画)中,所有视图总是从屏幕中间退出。
l 一个共享元素过渡(动画)决定两个activities之间的过渡,怎么共享(它们)的视图。例如,如果两个activities有相同的图像且是有不同的位置和大小,那么changeImageTransform(原文的单词,改变图像变换?)共享元素的过渡转换盒平滑的缩放图像。
图一:共享元素的过渡。
Android 5.0(API级别21)支持这些进入和退出的过渡动画:
l explode(分解) –进或出地移动视图,从屏幕中间
l slide(滑动) -进或出地移动视图,从屏幕边缘
l fade(淡出) –通过改变屏幕上视图的不透明度达到添加或者移除视图(的效果)
任何继承了Visibility类的过渡都支持进入或退出的过渡。欲了解更多的信息,请参阅Transition类的API文档说明。
Android 5.0(API级别21)也支持这些共享元素的过渡:
l changeBounds –以动画(的效果)更改目标视图的布局界限
l changeClipBounds -以动画(的效果)更改目标视图的裁剪界限
l changeTransform -以动画(的效果)更改目标视图的缩放和旋转
l changeImageTransform -以动画(的效果)更改目标图像的缩放和大小
当你在你的app中启用activity的过渡(动画),activities的进入和退出将会显示默认的交叉渐变过渡效果。
图二:伴随一个共享元素的屏幕装换
自定义转换(动画)
第一,当你定义继承了material主题样式时,使用android:windowContentTransitions属性启用窗口的内容转换(效果)。你还可以指定进入、退出、和共享元素的转换:
- <style name=“BaseAppTheme” parent=“android:Theme.Material”>
- <!– 启用窗口的内容转换–>
- <item name=“android:windowContentTransitions”>true</item>
- <!– 进入、退出的转换(效果) –>
- <item name=“android:windowEnterTransition”>@transition/explode</item>
- <item name=“android:windowExitTransition”>@transition/explode</item>
- <!—指定共享元素的转换(效果)–>
- <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类。更多的信息,请参阅Transition的API文档说明。
在代码中启用窗口内容的过渡,调用Window.requestFeature()方法:
- //在你的activity中(如果你没有在主题中启用转换)
- getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
- // 设置一个退出的过渡(动画)
- getWindow().setExitTransition(new Explode());
要在代码中指定转换,调用这些方法with一个Transition对象:
l Window.setSharedElementEnterTransition()
l Window.setSharedElementExitTransition()
该setExitTransition()方法和setSharedElementExitTransition()方法为正在调用(开启)的activity(将要隐藏的activity)定义退出过渡(动画)。该setEnterTransition()方法和setSharedElementEnterTransition()方法为被调用(开启)的activity(将要显示的activity)定义进入过渡(动画)。
为了得到一个过渡的完整效果,你必须在转换的两个activities都启用窗口内容过渡。否则,将要显示的activity会开始退出过渡动画,但随后你会看到一个窗口的过渡(如缩放或渐变)。
要尽快地开始一个进入的过渡,在即将显示的activity中使用Window.setAllowEnterTransitionOverlap()方法。这让你有更引人注目的进入过渡动画。
使用过渡(动画)开启activity
如果你为一个activity启用了过渡动画并设置了退出过渡动画,那么过渡动画将会被激活当你启动另一个activity时:
- startActivity(intent,
- ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
如果你设置了一个过渡给第二个activity,那么过渡也是在该activity开启时激活的。要禁用开启另一个activity时的过渡,可以提供一个空选项的bundle。
使用共享元素开启activity
为了使有一个共享元素的两个activities间使用过渡动画:
1. 在你的主题中启用窗口内容过渡
2. 在你的主题样式中指定共享元素的过渡
3. 定义你的过渡动画为XML资源
4. 使用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() {
- @Override
- public 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 activity
- startActivity(intent, options.toBundle());
- }
- });
对于你在代码中去生成共享的动态视图,在两个activities中使用View.setTransitionName()方法去指定一个相同的元素名字。
为了扭转场景过渡动画,当你在finish掉第二个activity时,调用Activity.finishAfterTransition()方法而不是调用Activity.finish()方法。
开启有多个共享元素的activity
为了使两个activities有多个共享元素,在两个布局中使用android:transitionName属性定义共享元素(或者在两个activities中使用View.setTransitionName()方法),并像如下创建一个ActivityOptions对象:
- ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
- Pair.create(view1, “agreedName1”),
- Pair.create(view2, “agreedName2”));
使用曲线运动
Material design中的动画依靠曲线,这个曲线适用于时间插值器和控件运动模式。Android5.0(API级别21)或者以上的系统版本中,你可以自定义定时的曲线和曲面运动模式的动画。
PathInterpolator类是一个基于贝塞尔曲线(Bézier curve)或路径(Path)对象上的新的插值器。这个插值器指定了一个1×1的方形运动曲线,用(0,0)点和(1,1)定位点还有控制点来作为构造方法中的参数。你还可以定义一个XML资源的路径插值器:
- <pathInterpolator xmlns:android=“http://schemas.android.com/apk/res/android”
- android:controlX1=“0.4”
- android:controlY1=“0”
- android:controlX2=“1”
- android:controlY2=“1”/>
在materialdesign规范中,系统提供了三个基本的曲线:
l @interpolator/fast_out_linear_in.xml
l @interpolator/fast_out_slow_in.xml
l @interpolator/linear_out_slow_in.xml
你可以传递一个PathInterpolator对象给Animator.setInterpolator()方法。
ObjectAnimator类有了新的构造方法,使你能够一次能同时使用两个或多个属性去绘制动画的路径。例如,下面的动画使用一个Path对象进行视图X和Y属性的动画绘制:
- ObjectAnimator mAnimator;
- mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
- …
- mAnimator.start();
创建视图更改的动画
StateListAnimator类可以让你定义动画集,能在view状态改变时工作。下面的实例显示了如何定义一个XML资源的StateListAnimator。
- <!– animate the translationZ property of a view when pressed –>
- <!- view被按下时绘制translationZ 属性上的动画 –>
- <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 elements
- here for “x” and “y”, or other properties —>
- <!- 你还可以有其它的objectAnimator元素设置给x、y或其它的元素 –>
- </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()方法分配动画到你的视图上。
当你的主题继承了material主题,默认情况下按钮都有一个Z动画。为了避免在你的按钮中表现这个默认的行为,设置android:stateListAnimator属性为@null。
AnimatedStateListDrawable类让你去创建drawable资源,该资源在相关联的视图的状态更改时展示动画。一些Android5.0中的系统控件使用这些默认的动画。下面的例子显示了如何定义一个AnimatedStateListDrawable作为XML资源:
- <!– res/drawable/myanimstatedrawable.xml –>
- <animated-selector
- xmlns:android=“http://schemas.android.com/apk/res/android”>
- <!– provide a different drawable for each state–>
- <!- 为不同状态提供一个不同的drawable –>
- <item android:id=“@+id/pressed” android:drawable=“@drawable/drawableP”
- android:state_pressed=“true”/>
- <item android:id=“@+id/focused” android:drawable=“@drawable/drawableF”
- android:state_focused=“true”/>
- <item android:id=“@id/default”
- android:drawable=“@drawable/drawableD”/>
- <!– specify a transition –>
- <!- 定义一个过渡 –>
- <transition android:fromId=“@+id/default” android:toId=“@+id/pressed”>
- <animation-list>
- <item android:duration=“15” android:drawable=“@drawable/dt1”/>
- <item android:duration=“15” android:drawable=“@drawable/dt2”/>
- …
- </animation-list>
- </transition>
- …
- </animated-selector>
创建矢量Drawable动画
矢量drawable(Vector Drawables)具有可扩展性却不失清晰。AnimatedVectorDrawable类可以去创建一个矢量资源的动画。
你通常在三个XML文件中定义矢量资源的动画载体:
l <vector>元素的矢量资源,在res/drawable/(文件夹)
l <animated-vector>元素的矢量资源动画,在res/drawable/(文件夹)
l < objectAnimator>元素的一个或多个对象动画器,在res/anim/(文件夹)
矢量资源动画能创建<group>和<path>元素属性的动画。<group>元素定义了一组路径或子组,并且<path>元素定义了要被绘制的路径。
当你想要创建动画时去定义矢量资源,使用android:name属性分配一个唯一的名字给组和路径,这样你可以从你的动画定义中查询到它们。例如:
- <!– res/drawable/vectordrawable.xml –>
- <vector xmlns:android=“http://schemas.android.com/apk/res/android”
- android:height=“64dp”
- android:width=“64dp”
- android:viewportHeight=“600”
- android:viewportWidth=“600”>
- <group
- android:name=“rotationGroup”
- android:pivotX=“300.0”
- android:pivotY=“300.0”
- android:rotation=“45.0” >
- <path
- android:name=“v”
- android:fillColor=“#000000”
- android:pathData=“M300,70 l 0,-70 70,70 0,0 -70,70z” />
- </group>
- </vector>
矢量资源动画的定义指的是矢量资源中的组和路径,通过它们的名字:
- <!– res/drawable/animvectordrawable.xml –>
- <animated-vector xmlns:android=“http://schemas.android.com/apk/res/android”
- android:drawable=“@drawable/vectordrawable” >
- <target
- android:name=“rotationGroup”
- android:animation=“@anim/rotation” />
- <target
- android:name=“v”
- android:animation=“@anim/path_morph” />
- </animated-vector>
动画的定义代表ObjectAnimator或者AnimatorSet对象。这个例子中,第一个动画是旋转目标组360度:
- <!– res/anim/rotation.xml –>
- <objectAnimator
- android:duration=“6000”
- android:propertyName=“rotation”
- android:valueFrom=“0”
- android:valueTo=“360” />
这个例子的第二个动画(如下)改变了矢量资源的路径,从一个形状到另一个形状。两个形状必须是变形兼容:他们必须是具有相同数目的命令和相同数量的命令参数。
- <!– res/anim/path_morph.xml –>
- <set xmlns:android=“http://schemas.android.com/apk/res/android”>
- <objectAnimator
- android:duration=“3000”
- android:propertyName=“pathData”
- android:valueFrom=“M300,70 l 0,-70 70,70 0,0 -70,70z”
- android:valueTo=“M300,70 l 0,-70 70,0 0,140 -70,0 z”
- android:valueType=“pathType” />
- </set>
更多的信息,请参阅AnimatedVectorDrawable的API文档说明。
demo示例效果:
另外github上有一个比较好的矢量drawable的示例(animated-vector-drawable),其效果:
demo源码下载地址:http://download.csdn.net/detail/bbld_/8102797
animated-vector-drawable的源码(Eclipse工程)下载地址:http://download.csdn.net/detail/bbld_/8102935
Android Material Design-Maintaining Compatibility(保持兼容性)-(七)
一些materialdesign中的功能像material主题和自定义activity的过渡只能在Android 5.0(API级别21)或以上的系统版本中才能使用。但是你可以设计你的app去使用那些功能,无论在支持materialdesign的设备上亦或是早期的Android版本上。
定义可选的样式
你可以配置你的app去使用material design在支持它的设备上,在早期的Android版本中使用旧的主题:
1. 定义一个主题,它继承一个旧的主题(像Holo),放在res/values/styles.xml。
2. 定义一个相同名字主题,继承material主题,放在res/values-21/styles.xml。
3. 在manifest文件中设置这个主题为你的app主题。
注意:如果你的app使用了material主题但是没有提供一个可替代的主题,你的app将无法在Android 5.0之前的系统中运行。
提供可替代的布局
如果你根据设计准则不使用任何Android5.0引入的新的XML的属性去设计你的布局,他们能在Android的早期版本上运行。否则,你可以提供可选择的布局。你也可以提供可替代的布局,以自定义你的app看起来是在早期的Android版本上。
为Android 5.0(API级别21)或以上系统创建布局时则布局文件放在res/layout-v21/文件夹里,早期Android版本的可替代的布局则放在res/layout/文件夹里。例如,res/layout/my_activity.xml是res/layout-v21/my_activity.xml的一个可替代的布局
为了避免重复的代码,在res/values/里定义你的样式资源,为新的API修改的样式则放在res/values-v21/文件夹里,并且使用样式继承,在res/values/中定义基本的样式,在res/values-v21/.中继承基本的样式。
使用支持库
v7支持库r21及以上的版本包含以下的material design的特点:
l 当你应用Theme.AppCompat的主题时,一些控件具有materialdesign style的特征。
l Theme.AppCompat具有Color palette theme属性。
l RecyclerView控件显示数据集合。
l CardView控件创建卡片。
l Palette类去从图片中提取突出的颜色。
系统控件
Theme.AppCompat主题为这些控件提供了material design styles:
l EditText
l Spinner
l CheckBox
颜色调色板
为了在Android v7支持库中获得material design styles和自定义调色板,使用一个Theme.AppCompat的主题:
- <!– extend one of the Theme.AppCompat themes –>
- <style name=“Theme.MyTheme” parent=“Theme.AppCompat.Light”>
- <!– customize the color palette –>
- <item name=“colorPrimary”>@color/material_blue_500</item>
- <item name=“colorPrimaryDark”>@color/material_blue_700</item>
- <item name=“colorAccent”>@color/material_green_A200</item>
- </style>
列表和卡片
RecyclerView和CardView控件可以通过Android v7支持包在早期的Android版本上使用。但是有这些限制:
l CardView回退到使用有规则的阴影通过使用额外的填充。
l CardView不会裁剪它的子视图,使用圆角相交。
依赖
要在早于Android5.0(API级别21)的系统中使用这些功能,需添加Android v7支持库到你的项目中,下面是添加Gradle依赖:
- dependencies {
- compile ‘com.android.support:appcompat-v7:21.0.+’
- compile ‘com.android.support:cardview-v7:21.0.+’
- compile ‘com.android.support:recyclerview-v7:21.0.+’
- }
补充:Eclipse中添加依赖在前面的博客中我已做了说明(Android Material Design-Creating Lists and Cards(创建列表和卡片)-(三))。
检查系统版本
以下功能仅适用于Android的5.0(API等级21)以上:
l Activity transitions(Activity的过渡转换)
l Touch feedback(触摸反馈)
l Reveal animations(显示、揭露动画)
l Path-based animations(基于路径的动画)
l Vector drawables(矢量绘图资源)
l Drawable tinting(Drawable着色)
为了保持与早期Android版本的兼容性,在调用这些API之前检查系统的版本:
- // Check if we’re running on Android 5.0 or higher
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- // Call some material design APIs here
- } else {
- // Implement this feature without material design
- }
注意:要指定你的app所能支持的版本,使用在你的manifest文件中android:minSdkVersion和android:targetSdkVersion属性去声明。要在Android 5.0中需要使用material desing的功能,设置android:targetSdkVersionattribute属性的值为21.。更多的信息请参阅<uses-sdk>的API文档说明。
—————————————————————– Material Design系列的翻译完结 ———————————————————————-