Material Design 最全解析_4 视图和效果

6 篇文章 1 订阅
6 篇文章 1 订阅

概述

Material Design为开发者提供了一系列的效果、特性和控件,对于开发者来说实在是福音。
今天这篇博客就记录一下视图和效果方面的知识。

先看一下大纲

这里写图片描述


阴影的产生、高度的计算

阴影的产生是因为高度差,阴影的大小是由相对高度差决定的。

阴影示例

在以前UI只是二维时,View的位置参数有以下公式
X = Left + translationX
Y = Top = translationY;
Material新增的第三维度同样遵循这个公式
Z = elevation + translationZ

在初始化View的时候,elevation被复制,之后在Z轴上做属性动画,改变translationZ,两者之和是View的绝对高度。

设置Elevation

  • 在layout.xml中设置
    android:elevation="2dp"

  • 在代码中设置
    mButton.setElevation(4f);

Palette取色器

这个类挺有意思,在Android的版本发展中,UI越来越成为Google的发展中心,这次的Android5.X创新的使用了Palette来提取颜色,从而让主题能够动态适应当前页面的色调,使得整个app的颜色基本和谐统一。

Android内置了几种提取颜色的种类:

  • Vibrant(充满活力的)
  • Vibrant dark(充满活力的黑)
  • Vibrant light(充满活力的白)
  • Muted(柔和的)
  • Muted dark(柔和的黑)
  • Muted light(柔和的白)

使用:
1. gradle
compile 'com.android.support:palette-v7:21.0.+'
2. Api

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        etContentView(R.layout.activity_main);
        setPalette();
    }

    private void setPalette() {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        //创建Palette对象
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                //通过Palette来获取对应的色调
                Palette.Swatch vibrant = palette.getDarkVibrantSwatch();
                //将颜色设置给相应的组件
                getSupportActionBar().setBackgroundDrawable(new ColorDrawable(vibrant.getRgb()));
                Window window = getWindow();
                window.setStatusBarColor(vibrant.getRgb());
            }
        });
    }

3.效果
palette效果
4.分析

  • 生成Palette对象的方法有好多
Palette palette = Palette.from(bitmap).generate();
Palette palette = Palette.generate(bitmap);
Palette palette = Palette.generate(bitmap, 24);

这几个都是同步的获取,如果bitmap很小可以这样使用,如果bitmap很大,就需要使用异步获取。

Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
    @Override
    public void onGenerated(Palette palette) {

    }
});

然而以上方法最新版本都deprecated了,建议使用Builder来构建Palette,Builder方式也支持同步和异步两种方式。

同步:

Palette palette = new Palette.Builder(bitmap).generate();

异步:

new Palette.Builder(bitmap).generate(new Palette.PaletteAsyncListener() {
    @Override
    public void onGenerated(Palette palette) {

    }
});

Ps:重要的一点
上面有一个方法传了24,这个值代表的是取样的最大颜色数,默认是16,建议范围8-32.
数值越大,取样耗时越长,但是取样代表性越强,所以根据你的图片的大小和需求,自己确定数值的大小。

取样风格
Palette.Swatch vibrant = palette.getDarkVibrantSwatch();

Palette提供了6种取样风格:

palette.getVibrantSwatch(); //充满活力的
palette.getDarkVibrantSwatch(); //充满活力的黑
palette.getLightVibrantSwatch(); //充满活力的白
palette.getMutedSwatch(); //柔和的
palette.getDarkMutedSwatch(); //柔和的黑
palette.getLightMutedSwatch(); //柔和的白

Ps:这里的黑、白是指深色系和浅色系

  • 样本值
    Demo里用到的vibrant.getRgb()是获取取样后的颜色RGB值
    除了这个api,还有以下:

    getPopulation():Swatch所代表的取样样本的像素个数
    getRgb():Swatch取样的颜色RGB
    getHsl():Swatch取样的颜色HLS
    getBodyTextColor():在此取样颜色上,显示Body文本的推荐色
    getTitleTextColor():在此取样颜色上,显示Title文本的推荐色

Tinting着色器

先看一个例子,Tinting的使用非常的简单,只要在XML中配置好tint和tintMode就可以了,对于配置组合效果,只需要大家实际操作一下,就能非常清晰的理解处理效果。
“`

<TextView
    android:id="@+id/tv_rect"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:elevation="1dp" />

<TextView
    android:id="@+id/tv_circle"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:elevation="1dp" />
@Bind(R.id.tv_rect)
TextView tv1;

@Bind(R.id.tv_circle)
TextView tv2;

ViewOutlineProvider vlp1 = new ViewOutlineProvider() {
    @Override
    public void getOutline(View view, Outline outline) {
        outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 30);
    }
};

ViewOutlineProvider vlp2 = new ViewOutlineProvider() {
    @Override
    public void getOutline(View view, Outline outline) {
        outline.setOval(0, 0, view.getWidth(), view.getHeight());
    }
};

tv1.setOutlineProvider(vlp1);
tv2.setOutlineProvider(vlp2);

方形裁剪 圆形裁剪
Ps:这个灰色边框是因为elevation>0而产生的阴影

打开Outline.java文件,公开的方法并不算多

outline.canClip();
是否支持裁剪,目前只有矩形、圆形、圆角矩形支持裁剪
outline.getAlpha();
设置透明度
outline.isEmpty();
是否是空的。刚创建的时候是空的,调用了setEmpty后是空的。
outline.offset(0, 0);
设置x、y的偏移量
outline.setAlpha(1);
设置透明度
outline.setConvexPath(null);
设置用于构造一个outline的path
outline.setEmpty();
置空
outline.setOval(0, 0, 0, 0);
设置椭圆
outline.setOval(new Rect(0, 0, 0, 0));
同上
outline.setRoundRect(0, 0, 0, 0, 10);
设置圆角矩形
outline.setRoundRect(new Rect(0, 0, 0, 0), 10);
同上

以上都是在操作outline,有了outline就可以用它来裁剪View。 view.setClipToOutline(true)

还用以上面的例子来说:
一个TextView,设置背景颜色
原始textview

<TextView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="#d0d0d0"
    android:text="OutLine"
    android:gravity="center"
    android:elevation="2dp"/>

设置一个outline
tv.setOutlineProvider(outline);
设置outlineprovider的textview
你会发现并没有变化。
因为outline并没有应用到裁剪view的内容,需要调用tv.setClipToOutline(true)
这句话会用当前的outline裁剪view的内容,需要canClip返回true,之前提到,目前只有矩形、圆形、圆角矩形支持裁剪。
裁剪结果:
裁剪效果

Ps:关于outline、clipping、background、alpha
Outline可以影响投影的轮廓,但如果setClipToOutline(false),那它并不会裁剪view的内容,所以也不能改变background和forground的形状。
Outline只是用path描述的一种形状,本身并没有颜色,但是它却有alpha值,并且它的alpha值会影响阴影的透明度。
按照Material的原则,光照不透明的实体才会产生阴影,outline能影响阴影轮廓,却又没有改变view的实体形状,这就不好理解了。
setClipToOutline内部调用了native方法,没法知道具体的实现。


以上就是这篇文章的全部内容,从下一篇开始,就开始讲解UI控件相关,相信是大多数人关心的。

本期节目就到这里,感谢大家收看,我们下期再见~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值