黑马程序员技术交流社区

标题: 安卓5.0特性简介之一 [打印本页]

作者: 曹老师    时间: 2017-8-17 19:09
标题: 安卓5.0特性简介之一
本帖最后由 武汉-就业部 于 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:colorPrimary
标题栏颜色
android:colorPrimaryDark
状态栏颜色
android:textColorPrimary
主要文本颜色
android:textColorSecondary
次要文本颜色
android:navigationBarColor
底部导航栏颜色
android:windowBackground
默认背景颜色
colorAccent
控件在活动状态的颜色


如果是在自己的xml布局中,希望自己设定的颜色跟着主题的颜色发生变化,那么可以考虑直接取用系统主题的颜色值来作为背景的属性值:
<!-- 让背景颜色与应用默认的窗体背景颜色值一致 -->
android:background="?android:windowBackground"

主题编辑器
AndroidStudio提供了一个主题编辑器,我们可以通过主题编辑器对主题中的各种颜色统一进行设置。

打开方式:
        AndroidStudio -> Tools -> Android -> Theme Editor

注意:
        若是预览Android N(Android 7.x版本)的效果图,需要JDK 1.8的环境,否则会报错。

动态切换主题
如果想快速定位一个功能是在哪被实现的,可以通过全局搜索关键字来实现。
在AndroidStudio中,我们可以通过“右键选中项目 -> Find in Path…”来进行全局搜索。

我们可以通过搜索“主题选择”关键字,来看一下主题选择按钮的点击事件实现逻辑:
[attach]178925[/attach]

动态切换主题的实现逻辑:
        1. 首先,先在styles.xml文件夹下定义一堆样式
[attach]178926[/attach]
        
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轴设计的介绍:
http://www.google.com/design/spec/what-is-material/elevation-shadows.html#elevation-shadows-elevation-android-

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>




设置阴影的显示方式 -
outlineProvider
Android提供了一个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值产生阴影

注意一点:带有透明通道的背景,默认不显示阴影


自定义阴影 - setOutlineProvider
API 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);
}

裁剪的效果:


打印日志:
[attach]178940[/attach]



作者: 我不是李清照    时间: 2017-8-18 08:56
谢谢分享了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2