安卓学习笔记之Drawable

4 篇文章 0 订阅

1 Drawable基础

1.1什么是Drawable

首先Drawable是一个抽象类,表示的是可以在Canvas中绘制的图像,常被用作一个view的背景,有多种实现类完成不同的功能。其次Drawable大致可以分为这几类:图片、由颜色构成的图像。一般用xml中进行定义。

1.2 Drawable的继承体系

这里写图片描述

1.3 Drawable的实现类及标签

这里写图片描述
图片来源于网络。

1.4 Drawable内部宽高的获取

使用方法getIntrinsicWidth、getIntrinsicHeight来获取宽高

  • 当Drawable由图片构成时方法返回的是图片的宽高
  • 当Drawable由颜色构成时则没有宽高的概念,返回-1

2 各类Drawable及其用法

2.1 BitmapDrawable

用于显示一张图片,如下示例

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:antialias="true"
    android:dither="true"
    android:filter="true"
    android:gravity="top"
    android:src="@mipmap/girl"
    android:tileMode="repeat" />
常用属性
android:antialias 是否开启抗锯齿
android:dither 是否开启防抖动
android:filter 是否开启过滤效果
android:gravity 用于对图片进行定位
android:src 图片资源id
android:tileMode 平铺模式,repeat、mirror、clamp三种 

2.2 ColorDrawable

代表了单色可绘制区域,包装了一种固定的颜色,在画布上绘制一块单色的区域。

示例:
<?xml version="1.0" encoding="utf-8"?>
<color xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/colorAccent">
</color>

还可以用代码创建

ColorDrawable drawable = new ColorDrawable(int color); //传入一个color的integer值

2.3 NinePatchDrawable

即9-patch图,可以根据内容进行自由缩放宽高而不失真

示例:
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
    android:dither="true"
    android:filter="true"
    android:src="@color/colorAccent">
</nine-patch>
用draw9patch设定缩放区域

图中1、2方向表示在draw9patch中绘制黑线,黑线长度交集为可拉伸的范围
图中3、4方向黑线长度交集表示内容可以填充的区域
这里写图片描述

2.4 ShapeDrawable

通过颜色来构造图形,既可以为纯色图形,也可以为具有渐变效果的图形。能构成的图形有rectangle、oval、ring、line

具有渐变效果的圆示例:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <gradient
        android:angle="45"
        android:centerColor="@color/colorAccent"
        android:centerX="50%"
        android:centerY="50%"
        android:endColor="@color/colorPrimary"
        android:gradientRadius="150dp"
        android:startColor="@color/colorPrimaryDark"
        android:type="sweep" />
    <size
        android:width="260dp"
        android:height="260dp" />
</shape>

注意:1、android:angle值必须为45的倍数 2、oval用于绘制椭圆,当size的宽高相等时绘制成圆

圆环示例:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="100dp"
    android:shape="ring"
    android:thickness="10dp"
    android:useLevel="false" >

    <stroke
        android:width="10dp"
        android:color="@color/colorAccent" />
</shape>

注意:

  • 1、android:useLevel设置为false,否则无法显示理想效果
  • 2、innerRadius为圆环内半径,innerRadiusRation为内半径占圆环宽度的比率,两者以innerRadius为主
  • 3、thickness为圆环的宽度,thicknessRatio为此宽度占圆环宽度的比率,以thickness为主
常用属性
  • android:shape 要绘制的形状,rectangle、oval、ring、line

  • stroke 形状的描边,有如下属性

    • android:width 描边的宽度
    • android:color 描边的颜色
    • android:dashGap 绘制虚线的线宽
    • android:dashWidth 绘制虚线的线段间隔 (要绘制虚线,后两者均不能为0)
  • solid 纯色填充,android:color指定shape颜色

  • gradient 渐变效果,与solid不可一起用,有如下属性

    • android:angle 渐变的角度,必须为45的倍数
    • android:startColor 渐变的起始颜色
    • android:centerColor 渐变的中间颜色
    • android:endColor 渐变的结束颜色
    • android:centerX 渐变的中心点横坐标
    • android:centerY 渐变的中心点纵坐标
    • android:gradientRadius 渐变半径
    • android:type 渐变类型,linear(线性)、sweep(扫视)、radial(径向)
  • corners 表示矩形(rectangle)的四个角的角度,不适用于其他shape ,有如下属性

    • android:topLeftRadius、android:topRightRadius、android:bottomLeftRadius、android:bottomRightRadius 分别为设置左上角、右上角、左下角、右下角的角度
    • android:radius 为四角设置相同角度,优先级低,会被其他四个属性覆盖
  • size shape的宽高,对应着android:width、android:height

    • shape默认无宽高,getIntrinsicHeight、getIntrinsicWidth返回-1
    • 通过size可以设置其宽高,但作为view背景时任然会被拉伸或缩小为 view大小
  • padding 设置容纳shape的view的空白间距

2.5 StateListDrawable

可以看作是一个状态选择器,通过view不同的状态选择对应的item中的drawable显示

示例:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/colorPrimaryDark" android:state_pressed="false"></item>
    <item android:drawable="@color/colorAccent" android:state_pressed="true"></item>
</selector>
常见状态
android:state_pressed 当按住一个view时,按下的状态
android:state_checked  当一个view被选中时,适用于CheckBox
android:state_selected  当一个view被选择时
android:state_enabled  当一个view处于可用状态
android:state_focused  当view获取焦点

2.6 LayerDeawable

表示的是一种分层的的Drawable集合,类似于ps中的图层的概念,将多个drawable放在不同的层上面形成一种叠加的效果

示例:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/night" />
    <item
        android:drawable="@mipmap/photo6"
        android:gravity="center" />
</layer-list>
注意事项:
  • 1、layer-list可以包含多个item,每个item表示一个drawable,并且后添加的item会覆盖到之前添加的item上面
  • 2、默认情况下,layer-list所有的drawable都会缩放至view大大小,通过设施android:gravity可以调节缩放的效果
  • 3、可以设置上下左右偏移量,android:top、android:bottom、android:left、android:right

2.7 LevelListDrawable

表示一个drawable集合,集合中的每一个Drawable都有一个等级(level),通过设置不同的等级,可以使LevelListDrawable切换至不同的Drawable。等级范围在0~10000之间, android:maxLevel设置最大level, android:minLevel设置最小level
示例:

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@mipmap/photo0"
        android:maxLevel="20"
        android:minLevel="10" />
    <item
        android:drawable="@mipmap/photo1"
        android:maxLevel="40"
        android:minLevel="30" />
</level-list>

通过设置level可以切换不同的Drawable,在代码中

    //将ImageView的背景切换为photo1, 35 在30~40之间
    iv.setImageLevel(35); 
    //将ImageView的背景切换为photo0, 15在10~20之间
    iv.setImageLevel(15); 

2.8 TransitionDrawable

LayerDeawable的子类,用于实现连个Drawable的淡入淡出效果
示例:
xml文件定义

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/night" />
    <item android:drawable="@mipmap/photo6" />
</transition>

给ImageView设置src,在java代码中

    iv= (ImageView) findViewById(R.id.iv_transition);
    drawable = (TransitionDrawable) iv.getDrawable();
    drawable.startTransition(1000); // 实现淡入淡出效果
    drawable.reverseTransition(1000);

2.9 InsetDrawable

嵌入其他Drawable,并可以在四周保留一定的间距
示例:

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@mipmap/photo6"
    android:inset="20dp">
</inset>

2.10 ScaleDrawable

根据等级将一个Drawable缩放到一定的比例,当level为0时不可见,当level为10000时无缩放效果
示例:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@mipmap/night"
    android:scaleGravity="center"
    android:scaleHeight="50%"
    android:scaleWidth="50%" />

要显示出效果,必须设置level大于0

   iv = (ImageView) findViewById(R.id.iv_scale);
   ScaleDrawable drawable= (ScaleDrawable) iv.getDrawable();
   drawable.setLevel(1);
- android:scaleHeight="percentage",android:scaleWidth="percentage",设置宽高缩放为原来的比例为(100%-percentage)
- 设置level越大,图像显示越大

2.11 ClipDrawable

根据自己的等级(level)来对另一个Drawable进行裁剪,裁剪的方向由android:clipOrientation、android:gravity共同决定。设置level进行裁剪,level的大小从0到10000,level为0时完全不显示,为10000时完全显示
xml定义

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="horizontal"
    android:drawable="@mipmap/night"
    android:gravity="right"></clip>

设置给ImageView

<ImageView
     android:id="@+id/iv_clip"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:src="@drawable/drawable_clip" />

通过设置level来裁剪

    ImageView iv = (ImageView) findViewById(R.id.iv_clip);
    ClipDrawable drawable= (ClipDrawable) iv.getDrawable();
    drawable.setLevel(5000); //  设置的level越大裁剪的范围越小
属性
android:clipOrientation ,horizontal 水平方向裁剪,vertical 垂直方向裁剪
android:gravity ,配合裁剪方向

这里写图片描述


3 自定义Drawable

3.1 自定义Drawable的一般步骤

  1. 自定义Drawable类继承自Drawable
  2. 实现getOpacity,setColorFilter,setAlpha等方法
  3. 在onDraw方法中进行绘制
  4. 若自定义的Drawable有固定的大小,则需实现getIntrinsicWidth、getIntrinsicHeight方法

3.2 自定义圆形Drawable

package com.yu.drawablelearing;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

public class CircleDrawable extends Drawable{

    private int radius;
    private int mWidth;
    private int mHeight;
    private Paint mPaint;
    @Override
    public void draw(Canvas canvas) {
        canvas.drawCircle(mWidth/2,mHeight/2,radius,mPaint);
    }

    public CircleDrawable(Bitmap bitmap) {
        radius = Math.min(bitmap.getWidth(), bitmap.getHeight())/2;
        mWidth = bitmap.getWidth();
        mHeight = bitmap.getHeight();
        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint = new Paint();
        mPaint.setShader(bitmapShader);
        mPaint.setAntiAlias(true);

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

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

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

    @Override
    public int getIntrinsicHeight() {
        return mHeight;
    }

    @Override
    public int getIntrinsicWidth() {
        return mWidth;
    }
}

3.3 自定义带圆角的矩形Drawable

package com.yu.drawablelearing;

import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

/**
 * Created by pecu on 2016/08/24.
 */
public class RoundRectangleDrawable extends Drawable {
    private RectF rectF;
    private Paint mPaint;
    Bitmap mBitmap;
    @Override
    public void draw(Canvas canvas) {
        canvas.drawRoundRect(rectF, mBitmap.getWidth()/6,mBitmap.getHeight()/6, mPaint);
    }

    public RoundRectangleDrawable(Bitmap bitmap) {
        mBitmap = bitmap;
        mPaint = new Paint();
        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        mPaint.setAntiAlias(true);
        mPaint.setShader(bitmapShader);
    }
    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        invalidateSelf();
    }

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

    }

    @Override
    public void setBounds(int left, int top, int right, int bottom) {
        super.setBounds(left, top, right, bottom);
        rectF = new RectF(left, top, right, bottom);
    }

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

    @Override
    public int getIntrinsicWidth() {
        return mBitmap.getWidth();
    }

    @Override
    public int getIntrinsicHeight() {
        return mBitmap.getHeight();
    }

}
一、[Android实例]实现TextView里的文字有不同颜色 转eoe:http://www.eoeandroid.com/thread-4496-1-1.html import android.text.Html; TextView t3 = (TextView) findViewById(R.id.text3); t3.setText( Html.fromHtml( "<b>text3:</b> Text with a " + "<a href=\"http://www.google.com\">link</a> " + "created in the Java source code using HTML.")); 二、TextView显示html文件中的图片 转javaeye:http://da-en.javaeye.com/blog/712415 我们知道要让TextView解析和显示Html代码。可以使用 Spanned text = Html.fromHtml(source); tv.setText(text); 来实现,这个用起来简单方便。 但是,怎样让TextView也显示Html中<image>节点的图像呢? 我们可以看到fromHtml还有另一个重构: fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) 实现一下ImageGetter就可以让图片显示了: ImageGetter imgGetter = new Html.ImageGetter() { @Override public Drawable getDrawable(String source) { Drawable drawable = null; drawable = Drawable.createFromPath(source); // Or fetch it from the URL // Important drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable .getIntrinsicHeight()); return drawable; } }; 至于TagHandler,我们这里不需要使用,可以直接传null。 参考文档: http://tech-droid.blogspot.com/2010/06/textview-with-html-content.html英语好的朋友就直接看英文文档吧。 三、Android---文字中插入表情 转载自:http://blog.163.com/spf9190@126/blog/static/50207531201091545954587/ 这段时间在做一个短信项目,需要实现短信中插入表情的功能,本一位非常困难,经过一段时间的研究,发现还是比较簡単的,现在总结如下。 以短信输入框为例,短信的输入框是一个EditText,它的append方法不仅可以加入字符串,还可以添加HTML标记。以下就是使用HTML标记添加表情的具体操作。 首先需要构建一个ImageGetter,作用是通过HTML标记获得对应在res目录下的图片: ImageGetter imageGetter = new ImageGetter() { @Override public Drawable getDrawable(String source) { int id = Integer.parseInt(source); //根据id从资源文件中获取图片对象 Drawable d = getResources().getDrawable(id); d.setBounds(0, 0, d.getIntrinsicWidth(),d.getIntrinsicHeight()); return d; } }; 然后就可以直接往EditText视图中添加 inputLable.append(Html.fromHtml("<img src='"+clickedImageId+"'/>", imageGetter, null)); 其中 Html.fromHtml("<img src='"+clickedImageId+"'/>"就是HTML的图片标记,在Android中支持了部分HTML标记的使用(这方面我还在继续研究),HTML标记必须被Html.fromHtml修饰。imageGetter即为之前创建的ImageGetter类型的对象。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值