MaterialDesign
标签(空格分隔): Android
ToolBar###
可以看一下自己写的demo,名字叫TestMaterial
这个demo主要参考文章:博客一
也可以看一下这篇文章,知道一下开发过程中的坑,博客二
关于ToolBar与ActionBar的比较,还有ToolBar的用法博客三
ToolBar的一些特技:博客四
注意事项
1、不要把兼容包中的 Material Theme 使用到 Activity 上
兼容包中的 Material Theme 是提供给 AppCompatActivity 使用的
2、兼容包中与 Android 5.x 中的 Material Theme 在 style 中设置有区别
沉浸式状态栏###
第一种:实现toolBar与状态栏同色
请看鸿洋博客
实现原理请看为什么根布局加了一个与状态栏等高的View,就可以将那个新增的view放到StatusBar的位置,实现沉浸式布局
这篇文章当中还有一些开发过程中的坑
第二种:实现用图片覆盖状态栏
请见博客中的ImageTranslucentTheme
注意:StatusBar和NavigationBar都是系统级别的空间,开发者不可以像TextView那样随意调用,但是可以在Style.xml中设置
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
分别将StatusBar和NavigationBar变成透明
DrawerLayout实现抽屉菜单###
注意DrawerLayout不是materialDesign推出的,但是称用于搭配MaterialDesign####
效果一:抽屉菜单覆盖AppBar
1、使用toolBar实现:请参考这篇博客的效果一的有关段落
2、使用ActionBAr实现。其实这当中的原理跟使用ToolBar来实现差不多,只是ToolBar与ActionBar的区别而已,只要把DrawerLayout 写在主布局的的最外层,这样就可以是实现抽屉菜单覆盖AppBar
效果二:抽屉菜单显示在AppBar下方
1、使用ActionBAr实现:请参考这篇博客的效果二的有关段落
把DrawerLayout 写在主布局的的最外层,可是使用的是ActionBAr,所以抽屉菜单不会覆盖AppBar
这篇翻译文档也是实现抽屉菜单显示在AppBar下方
2、使用toolBar实现。只要不把DrawerLayout 写在主布局的的最外层,然后记得ToolBar的布局也不要被DrawerLayout包裹,这样就可以是实现抽屉菜单显示在AppBar下方
现在新出的Design Support Library,可以让在6.0之前的版本可以更加方便的使用materialDesign的一些空间或者特性,例如里面的Navigation View通过使用menu,headerLayout等属性进一步简化了抽屉式导航框架的使用:
RippleDrawable###
视图的水波纹效果,RippleDrawable 其实就可以当作一个 Drawable,
单一效果:
在控件中直接使用
android:attr/selectableItemBackground 有界限的波纹(低版本也可以使用)
android:attr/selectableItemBackgroundBorderless 可以超出视图区域的波纹(minSdkVersion至少要21才能使用)
更多的效果:
drawable 文件夹中定义一个以 <ripple> 为根控件的 xml 文件,然后作为一个控件的背景即可。具体请看博客中的RippleDrawable部分【这个方法低版本不可以使用,只能用于5.0或之上】
Material Design动画###
还没了解
palette###
最新的用法看这篇博客
无论是5.0还是5.0以下的都可使用,要引入[v7 support libraries r21],并且使用Theme.AppCompat主题
应用场景:
说Palette之前先说下前面提到的Pager。ViewPager是什么大家应该都是知道的了,一般ViewPager、xxxTabStrip、Fragment三个好基友是一起出现的。这里的xxxTabStrip是使用Github上的PagerSlidingTabStrip。当我们的Pager切换时伴随着Fragment的变化,而Fragment里的内容一般是不同的,所以每个Fragment里的一般视觉效果也是不同的,所以我们可以用Palette来去提取Fragment中的主色调,那Fragment中的拿什么给Palatte去提取颜色呢,这就需要自己根据自己的情况来决定的。比如我这个demo里,Fragment就一个TextView和给Fragment设了背景,那么我就可以把背景的图片给Palette去提取颜色了。
视图与阴影###
在5.0中加入了z值属性,对应垂直方向上的高度变化
Z值由elevation与translation组成,
在layout中使用 android:elevation属性去定义
在代码中使用 View.setElevation 方法去定义
设置视图的translation,可以使用View.setTranslationZ方法
(改变视图高度的属性只支持5.0)
或者在属性动画中view.annimate().translationZ(100);加入一个Z高度变化的动画。
新的ViewPropertyAnimator.z和ViewPropertyAnimator.translationZ方法可以设置视图的elevation值
(是否支持5.0以下的版本,还有待验证!!!!)
可以参考一下这篇博客相应的部分
应用场景:
translationZ允许你创建一个动画暂时的反应出View的高度值(elevation)变化。
这对于响应触摸手势很有用处,请看下面代码
(官方Demo中的代码):
int action = motionEvent.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "ACTION_DOWN on view.");
view.setTranslationZ(120);
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "ACTION_UP on view.");
view.setTranslationZ(0);
break;
default:
return false;
}
应用场景图:
Tinting(着色)###
Android L还有一个独特的特点就是现在可以定义图片的alpha遮罩,并且可以轻松的使用android:tint属性去调整色调。
使用tint属性给背景调整不同颜色的例子:
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<ImageView
...
android:src="@drawable/xamarin_white"
android:background="@drawable/mycircle"/>
<ImageView
...
android:src="@drawable/xamarin_white"
android:background="@drawable/mycircle"
android:tint="#2C3E50"/>
<ImageView
...
android:src="@drawable/xamarin_white"
android:background="@drawable/mycircle"
android:tint="#B4BCBC"/>
</LinearLayout>
Clipping Views(裁剪视图)###
略
RecyclerView###
参考鸿洋大神博客,但是这篇博客的Click and LongClick请与泡在网上的日子的这篇博客一起看
可以引入支持包兼容低版本
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.+'
}
以下的内容参考张涛博客
RecyclerView重要的五个类:####
RecyclerView.LayoutManager 负责Item视图的布局的显示管理
RecyclerView.ItemDecoration 给每一项Item视图添加子View,例如可以进行画分隔线之类
RecyclerView.ItemAnimator 负责处理数据添加或者删除时候的动画效果
RecyclerView.Adapter 为每一项Item创建视图
RecyclerView.ViewHolder 承载Item视图的子布局
ItemDecoration 工作原理
temDecoration 是为了显示每个 item 之间分隔样式的。它的本质实际上就是一个 Drawable。当 RecyclerView 执行到 onDraw() 方法的时候,就会调用到他的 onDraw(),这时,如果你重写了这个方法,就相当于是直接在 RecyclerView 上画了一个 Drawable 表现的东西。 而最后,在他的内部还有一个叫getItemOffsets()的方法,从字面就可以理解,他是用来偏移每个 item 视图的。当我们在每个 item 视图之间强行插入绘画了一段 Drawable,那么如果再照着原本的逻辑去绘 item 视图,就会覆盖掉 Decoration 了,所以需要getItemOffsets()这个方法,让每个 item 往后面偏移一点,不要覆盖到之前画上的分隔样式了。ItemAnimator工作原理
每一个 item 在特定情况下都会执行的动画。说是特定情况,其实就是在视图发生改变,我们手动调用notifyxxxx()的时候。通常这个时候我们会要传一个下标,那么从这个标记开始一直到结束,所有 item 视图都会被执行一次这个动画。Adapter工作原理(与listView的adapter不同)
首先是适配器,适配器的作用都是类似的,用于提供每个 item 视图,并返回给 RecyclerView 作为其子布局添加到内部。
但是,与 ListView 不同的是,ListView 的适配器是直接返回一个 View,将这个 View 加入到 ListView 内部。而 RecyclerView 是返回一个 ViewHolder 并且不是直接将这个 holder 加入到视图内部,而是加入到一个缓存区域,在视图需要的时候去缓存区域找到 holder 再间接的找到 holder 包裹的 View。ViewHolder
每个 ViewHolder 的内部是一个 View,并且 ViewHolder 必须继承自RecyclerView.ViewHolder类。 这主要是因为 RecyclerView 内部的缓存结构并不是像 ListView 那样去缓存一个 View,而是直接缓存一个 ViewHolder ,在 ViewHolder 的内部又持有了一个 View。既然是缓存一个 ViewHolder,那么当然就必须所有的 ViewHolder 都继承同一个类才能做到了。
缓存与复用的原理:####
RecyclerView 的内部维护了一个二级缓存,滑出界面的 ViewHolder 会暂时放到 cache 结构中,而从 cache 结构中移除的 ViewHolder,则会放到一个叫做 RecycledViewPool 的循环缓存池中。
顺带一说,RecycledView 的性能并不比 ListView 要好多少,它最大的优势在于其扩展性。但是有一点,在 RecycledView 内部的这个第二级缓存池 RecycledViewPool 是可以被多个 RecyclerView 共用的,这一点比起直接缓存 View 的 ListView 就要高明了很多,但也正是因为需要被多个 RecyclerView 公用,所以我们的 ViewHolder 必须继承自同一个基类(即RecyclerView.ViewHolder)。
默认的情况下,cache 缓存 2 个 holder,RecycledViewPool 缓存 5 个 holder。对于二级缓存池中的 holder 对象,会根据 viewType 进行分类,不同类型的 viewType 之间互不影响。
CardView###
它是一个使用了Material Desgin风格的FrameLayout,只不过比普通的FrameLayout多了圆角背景和阴影效果。所以它常用作ListView 或者 RecyclerView等视图Item的布局容器;
使用场景请看这篇博客有关CardView的部分
可以引入支持包支持低版本
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.+'
}
Meterial Dialog###
关于Meterial Dialog可以看一下这篇博客,当中也有讲palette和CardView
Android Support Library v22.1 中开始提供了 Material 风格的 Dialog 控件(官方提供的,很好,很强大)
其实就是V7包的22版本
Activity的过渡动画###
取代overpendingtranstion。
可是只支持5.0版本
基本用法可以看看《群英传》
Circular Reveal###
只支持5.0版本
参考网上资料
View state changes Animation###
根据视图状态改变来设置一个视图的状态切换动画
只支持5.0版本
- StateListAnimator
可以让你定义动画集,能在view状态改变时工作。在切换状态的时候有个切换动画,不会像以前那么生硬!参考博客 - animated-selector
Curved motion(曲线运动)###
只支持5.0版本
Material design中的动画依靠曲线,这个曲线适用于时间插值器和控件运动模式。
PathInterpolator类是一个基于贝塞尔曲线(Bézier curve)或路径(Path)对象上的新的插值器。
Notification###
维护兼容性###
请看官方中文文档
Theme.AppCompat 主题中提供了这些组件的 Material Design style:
EditText
Spinner
CheckBox
RadioButton
SwitchCompat
CheckedTextView
Material适配详解###
请看泡在网上的日子博客
Android Design Support Library
关于Android Design Support Library的使用请看这两篇博客的大概盘点:博客一、博客二
导读:
这个兼容库很容易和之前的 Android Support Library 22.1混淆,都是兼容库,区别是这个库多了个Design。 Android Support Library 22.1只是支持了一些基本控件的材料设计化,但是这个库更多的是对一些特效的实现,这个库和github上的很多开源项目是有很大关系的,material design的很多效果,同一种效果在github上有太多的实现,现在官方把部分效果标准化了。
- Snackbar
Snackbar提供了一个介于Toast和AlertDialog之间轻量级控件,它可以很方便的提供消息的提示和动作反馈。(可以设置点击监听) Snackbar在出现一定时间后,就会消失,这与Toast一模一样。
Snackbar.make(view, "Snackbar comes out", Snackbar.LENGTH_LONG)
.setAction("Action", new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(
MainActivity.this,
"Toast comes out",
Toast.LENGTH_SHORT).show();
}
}).show();
- Navigation View——更好地实现抽屉菜单
简单例子:
<android.support.v4.widget.DrawerLayout
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:fitsSystemWindows="true">
<!-- your content layout -->
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
//app:headerLayout - 控制头部的布局,
//app:menu - 导航菜单的资源文件(也可以在运行时配置)。
NavigationView处理好了和状态栏的关系,可以确保NavigationView 在API21+设备上正确的和状态栏交互。不用担心会覆盖住StatusBar!!
以通过设置一个OnNavigationItemSelectedListener,使用其setNavigationItemSelectedListener()来获得元素被选中的回调事件。它为你提供被点击的 菜单元素 ,让你可以处理选择事件,改变复选框状态,加载新内容,关闭导航菜单,以及其他任何你想做的操作。例如这样:
private void setupDrawerContent(NavigationView navigationView) {
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
return true;
}
});
}
剩下的控件就不一一列出来了
Goolge新的开源项目——FlexboxLayout###
简单使用:博客