本帖最后由 武汉-就业部 于 2017-8-17 19:30 编辑
Android 5.0介绍
Android 5.0最主要的变化就是采用了全新的Material Design界面。 Material Design就是材质化设计,材质化设计指的是物体是有质地的,2个控件之间是有实体的,不允许互相穿墙。
使用Material主题使用的时候的向下兼容: 默认的style.xml还用之前的主题,但是新增一个“values-21”的文件夹,在下面的style.xml中设置主题为Material Design相关主题。同时,V7包的新的AppCompat相关主题包含了支持Material Design的兼容代码与资源文件,如果关联了V7包,也可以直接配置Theme.AppCompat相关主题。
相关资料网站: Metrarial Design风格配色: www.materialpalette.com/ Metrarial Design主题介绍: http://developer.android.com/intl/zh-cn/training/material/theme.html
Android 5.0提供了三种Metrarial Design的材质化主题: l Theme.Material l Theme.Material.Light l Theme.Material.Light.DarkActionBar 除此之外,我们还可以自定义一些主题样式: 属性 | | | | | | | | android:textColorSecondary | | android:navigationBarColor | | | | | |
如果是在自己的xml布局中,希望自己设定的颜色跟着主题的颜色发生变化,那么可以考虑直接取用系统主题的颜色值来作为背景的属性值: <!-- 让背景颜色与应用默认的窗体背景颜色值一致 --> android:background="?android:windowBackground" |
主题编辑器AndroidStudio提供了一个主题编辑器,我们可以通过主题编辑器对主题中的各种颜色统一进行设置。
打开方式: AndroidStudio -> Tools -> Android -> Theme Editor
注意: 若是预览Android N(Android 7.x版本)的效果图,需要JDK 1.8的环境,否则会报错。
动态切换主题如果想快速定位一个功能是在哪被实现的,可以通过全局搜索关键字来实现。 在AndroidStudio中,我们可以通过“右键选中项目 -> Find in Path…”来进行全局搜索。
我们可以通过搜索“主题选择”关键字,来看一下主题选择按钮的点击事件实现逻辑:
动态切换主题的实现逻辑: 1. 首先,先在styles.xml文件夹下定义一堆样式 2. 在Activity中定义一个成员变量,来标识当前默认显示的主题: public static int mTheme = -1; |
3. 在Activity的onCreate方法中通过系统的“setTheme()”方法来设置当前Activity要显示的主题。 注意:必须在“super.onCreate()” 方法执行之前调用“setTheme()”方法: @Override
protected void onCreate(Bundle savedInstanceState) {
if (mTheme != -1) {
setTheme(mTheme);
}
super.onCreate(savedInstanceState);
…… } |
4. 在更改主题时,根据被更改的主题,设置mTheme的值: private void setTheme(int index) {
switch (index) {
case DEFAULT_THEME:
MainActivity.mTheme = R.style.DefaultTheme;
break;
case DEFAULT_LIGHT_THEME:
MainActivity.mTheme = R.style.DefaultLightTheme;
break;
case DEFAULT_LIGH_DARK_THEME:
MainActivity.mTheme = R.style.DefaultLightDarkTheme;
break;
case RED_THEME:
MainActivity.mTheme = R.style.RedTheme:
break; ……
default:
break;
}
} |
5. 更改完mTheme的值之后,关闭当前Activity,并重新加载Activity。当重新加载Activity的时候,就会执行到Activity的onCreate方法,setTheme方法就会被调用,修改的主题生效。 注意:关闭Activity之前,要取消Activity的动画,开启Activity之前也一样,要取消掉动画,造成一种主题颜色直接被刷新的假象,提升用户体验。 protected void reload() {
// 获取开启这个Activity时的那个Intent
Intent intent = getActivity().getIntent();
// 取消关闭Activity时的默认动画
getActivity().overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
// 关闭Activity
getActivity().finish();
// 取消开启Activity时的默认动画
getActivity().overridePendingTransition(0, 0);
// 重启Activity
startActivity(intent);
} |
细节处理: l 假如应用中存在大量的Activity,应抽取一个BaseActivity,在BaseActivity中的onCreate方法中设置主题,使所有的Activity的主题一起得到更改; l 如果想更新过一次主题后,下次再进应用的时候,主题仍旧生效,需要每次更新主题后,将其标识存到SP中。 阴影的作用
Android 5.0提供了一个Z轴的概念,Z轴的高度决定了控件的默认的阴影的大小: Z = elevation + translationZ 其中,elevation 是相对于父控件的高度,translationZ是该组件在Z方向(垂直屏幕方向)上的位移。
translationZ允许你创建一个动画暂时的反应出View的高度值(elevation)变化。
在设置Z轴的高度时,建议层次控制在0-5(6个) 不同的层次范围内,2dp一层,选中状态可以提升3层(6dp)。
Z轴的高度决定了View的遮盖关系。
有关Z轴设计的介绍:
Google官方对不同的控件的高度的推荐值: <!-- 阴影的作用 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:background="@drawable/circle_shape"
android:elevation="5dp" android:gravity="center"
android:text="高度5dp" />
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-20dp" android:background="@drawable/head"
android:elevation="10dp"
android:gravity="center"
android:text="高度10dp" />
</LinearLayout>
|
设置阴影的显示方式 - outlineProviderAndroid提供了一个outlineProvider属性,用于设置阴影的类型。它有四个属性值:none、background、bounds、paddedBounds。 在drawable文件夹下创建一个shape资源作为背景:shape_bg_circle.xml <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- 边框 -->
<stroke
android:width="1dip"
android:color="#eaff35" />
<!-- 填充 -->
<solid android:color="#eaff35" />
</shape> |
以上面的shape资源作为TextView的背景,修改outlineProvider属性: <TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="10dp"
android:background="@drawable/circle_shape"
android:elevation="10dp"
android:gravity="center"
android:outlineProvider="background"
android:text="background" /> |
outlineProvider的四种属性对应的效果为:
none : 不设置阴影 background:围绕着背景产生一圈阴影 bounds:围绕着控件的边框产生一圈阴影 paddedBounds:和bounds类似,如果有padding,根据padding值产生阴影
注意一点:带有透明通道的背景,默认不显示阴影
自定义阴影 - setOutlineProviderAPI 21以上,View提供了一个setOutlineProvider的方法,用来自定义阴影的形状。 /** * 自定义阴影 */private void initShadow() {
mTvShapeAlpha.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, view.getWidth(), view.getHeight());
}
});
mTvImg.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, view.getWidth(), view.getHeight());
}
});
} |
根据阴影裁剪控件 - setClipToOutline将控件的背景按阴影的样式进行裁剪,需要进行以下几步: 1. 给控件设置OutlineProvider 2. 将控件的setClipToOutline方法设置true 注意:并不所有的形状都可以剪裁,可通过OutlineProvider.canClip()确认当前形状是否可以裁剪
原始控件的布局设置: <TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="10dp"
android:background="#88FF0000"
android:elevation="5dp"
android:gravity="center"
android:text="原始图像" /> |
根据阴影进行裁剪: /** * 阴影的裁剪 */private void clipShadow() {
// 三角形的阴影
ViewOutlineProvider triangleProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
Path path = new Path();
path.moveTo(view.getWidth() / 2, 0);
path.lineTo(0, view.getHeight());
path.lineTo(view.getWidth(), view.getHeight());
path.close();
outline.setConvexPath(path);
Log.e(TAG, "三角形阴影,是否可裁剪:" +outline.canClip());
}
};
// 圆形的阴影
ViewOutlineProvider ovalProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, view.getWidth(), view.getHeight());
Log.e(TAG, "圆形阴影,是否可裁剪:" +outline.canClip());
}
};
// 设置阴影
mTvTriangle.setOutlineProvider(triangleProvider);
mTvOval.setOutlineProvider(ovalProvider);
// 裁剪控件
mTvTriangle.setClipToOutline(true);
mTvOval.setClipToOutline(true);
} |
裁剪的效果:
打印日志:
|