6.3 Android中的Drawable

8. ScaleDrawable

ScaleDrawable对应于<scale>标签,它可以根据自己的等级将指定的Drawable缩放到一定比例。

Amy_LuLu__的图

<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/drawable_resource"
    android:scaleGravity=["top" | "bottom" | "left" | "right" | 
    "center_vertical" | "fill_vertical" | "center_horizontal" | 
    "fill_horizontal" | "center" | "fill" | "clip_vertical" | 
    "clip_horizontal"]
    android:scaleHeight="percentage"
    android:scaleWidth="percentage" />
  • android:scaleGravity: 缩放的方向, 比如: top, 缩放的时候就会向顶部靠拢,bottom, 缩放时会向底部靠拢;
  • android:scaleHeight: 表示Drawable能够在高度上缩放的百分比, 比如: 50%,
  • android:scaleWidth: 表示Drawable能够在宽度上缩放的百分比, 同上;

ScaleDrawable的缩放,并不是自动的建立在原有Drawable尺寸的基础上的。而是,需要给原有的Drawable指定一个Level,然后ScaleDrawable是在这个Level的基础上进行缩放的!!

更加坑爹的事情是,在设置百分比的时候,设置的值是缩小的比例。也就是说,设置0.1,意为缩小10%!!而不是原始大小的10%!!

ScaleDrawable不能单独的使用, 他需要配合Level等级使用, level的取值是0~10000, (0为不可见)

<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@android:color/holo_green_dark"
    android:scaleGravity="left"
    android:scaleWidth="30%"
    android:scaleHeight="30%">

</scale>

作为背景使用

<TextView
    android:id="@+id/tv"
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:text="Hello World!"
    android:gravity="center"
    android:clickable="true"
    android:background="@drawable/scale_drawable"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

在Java中使用

tv = findViewById(R.id.tv);
final ScaleDrawable scaleDrawable = (ScaleDrawable) tv.getBackground();
scaleDrawable.setLevel(0); // 不显示

tv.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        scaleDrawable.setLevel(5000);
    }
});

先来理清下View的宽高, Drawable的宽高, 可缩放的百分比,Level等级三者间的关系: 一个个来说:

  • View的宽高: 在整个过程中是不会发生变化的;
  • 可缩放的百分比: 先搞清楚这个百分比, 它是控件能够缩小的最小尺寸, 比如:10%, 表示Drawable最小能缩小到控件的10%宽或者高, 这时候还需要加上一个level等级
  • Level等级:取值是0~10000; 上面Drawable能放大或缩小的区间是10%~100%, 这个区间就是用0~10000是描述. 它们和缩放后的宽高存在一个等式:
缩放后的宽高 = Drawable显示的宽高(大多时候是View的宽高) - Drawable显示的宽高(大多时候是View的宽高) * 可缩放的百分比 * (设置的Level/10000);

9. ClipDrawable


ClipDrawable对应于<clip>标签,它可以根据自己当前的等级(level)来裁剪另一个Drawable,裁剪方向可以通过android:clipOrientationandroid:gravity这两个属性来共同控制。
其中clipOrientation表示裁剪方向,有水平和竖直两个方向,gravity比较复杂,需要和clipOrientation一起才能发挥作用。
gravity属性

在XML中设置

<?xml version="1.0" encoding="utf-8"?>
<clip
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/circle"
    android:clipOrientation="vertical"
    android:gravity="bottom">

</clip>

在布局中使用

<ImageView
    android:id="@+id/imageView"
    android:layout_width="384dp"
    android:layout_height="511dp"
    android:src="@drawable/drawable_clip"/>

在Java中使用

imageView = findViewById(R.id.imageView);
clipDrawable = (ClipDrawable) imageView.getDrawable();
clipDrawable.setLevel(5000);

Drawable的等级(level)是有范围的,即0~10000,最小等级是0,最大等级是10000,对于ClipDrawable来说,等级0表示完全裁剪,即整个Drawable都不可见了,而等级10000表示不裁剪。在上面的代码中,将等级设置为8000,表示裁剪了2000,即在底部裁减掉20%的区域,被裁减的区域就相当于不存在了。

等级越大,表示裁剪的区域越小,因此等级10000表示不裁剪,这个时候整个图片都可以完全显示出来;而等级0则表示裁剪全部区域,这个时候整个图片将不可见。另外裁剪效果还受裁剪方向和gravity属性的影响。

10. 自定义Drawable

Drawable的使用范围很单一,一个是作为ImageView中的图像来显示,另外一个就是作为View的背景,大多数情况下Drawable都是以View的背景这种形式出现的。

通常我们没有必要去自定义 Drawable,这是因为自定义的Drawable无法在XML中使用,这就降低了Drawable的使用范围。

public class CustomDrawable extends Drawable{

    private Paint mPaint;

    public CustomDrawable(int color) {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(color);
    }


    @Override
    public void draw(@NonNull Canvas canvas) {
        final Rect rect = getBounds();
        float cx = rect.exactCenterX();
        float cy = rect.exactCenterY();
        canvas.drawCircle(cx,cy,Math.min(cx,cy),mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        invalidateSelf();
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }
}

在Java中

imageView2 = findViewById(R.id.imageView2);
CustomDrawable drawable = new CustomDrawable(R.color.colorPrimary);
imageView2.setImageDrawable(drawable);
借用开心wonderful的图

getIntrinsicWidthgetIntrinsicHeight这两个方法需要注意一下,当自定义的Drawable有固定大小时最好重写这两个方法,因为它会影响到Viewwrap_content布局。
Drawable的实际大小可以通过它的getBounds方法来得到。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 前言 本文是本人阅读《Android开发艺术探索》的第6章《Android的Drawable》后的总结笔记。包含了...
    daking阅读 5,262评论 2 29
  • 一、 Drawable简介 1 Drawable表示的是一种可以在Canvas上进行绘制的抽象的概念,可以是纯颜色...
    黄海佳阅读 1,121评论 0 10
  • 看到微信的的时候,我简直不敢相信自己的眼睛。 “告诉你个好消息,我决定去青海支教了。” 其实我第一想到的是,艰苦的...
    鹿浪漫阅读 6,595评论 0 0
  • 穿着最爱的百事小内裤 披着黑色羽绒服 站在阳台上,靠着栏杆 嘴里是蛋明给的,用插在在书馆的某本小说里的一百块钱买的...
    苏锐叔叔阅读 292评论 0 3