Paint(画笔),Android中制作界面最常见的一个类,它的规划思路其实也遵从实际中画笔的界说:在画布(Canvas)上制作内容的目标。

咱们经过设置Paint相关特点,就能够在画布上制作不同款式的图画。

1、常用API

函数 解说
void setColor(int color) 设置画笔色彩
void setStyle(Style style) 描边作用。
可选值包括FILLFILL_AND_STROKESTROKE
void setStrokeWidth(float width) 设置画笔宽度,单位是px。
只在Style为STROKEFILL_AND_STROKE时有用
void setAntiAlias(boolean aa) 抗锯齿,制作不规则图形运用,假如制作矩形、位图,就不需求打开
void setDither(boolean dither) 抗颤动
setStrokeMiter(float miter)
void setStrokeCap(Cap cap) 线帽风格。
Cap.ROUND(圆形),Cap.SQUARE(方形),Cap.BUTT (无线帽)。
void setStrokeJoin(Join join) 拐角风格。
Join.MITER(锐角), Join.ROUND(圆弧),Join.BEVEL(直线)
void setFilterBitmap(boolean filter) 双线性滤波

留意:在Android体系在,色彩一般由一个int值表示:int color = (alpha<<24) | (red<<16) | (green<<8) | blue


2、文字相关API

2.1、文字相关函数

函数 解说
void setTextSize(float textSize) 设置字体大小
void setTextAlign(Align align) 设置文字对齐办法,包括LEFTCENTERRIGHT
void setFakeBoldText(boolean) 设置是否为粗体
void setUnderlineText(boolean) 设置下划线
void setTextSkewX(float) 设置字体水平倾斜度,普通斜体字设为-0.25
void setStrikeThruText(boolean) 设置带有删去线作用
void setTextScaleX(2) 水平缩放

2.2、字体相关函数

1、设置字体款式

Typeface setTypeface(Typeface typeface)

typeface取值:Typeface.SANS_SERIFTypeface.MONOSPACETypeface.SERIF,但对中文支持欠好,一般都不运用。

2、依据字体款式获取对应的默许字体

Typeface defaultFromStyle(int style)

直接经过指定字体名来加载体系中自带的字体款式,假如字体款式不存在,则回来体系款式。

style取值如下:

  • Typeface.NORMAL: 正常字体。
  • Typeface.BOLD: 粗体。
  • Typeface.ITALIC: 斜体。
  • Typeface.BOLD_ITALIC: 粗斜体。

3、创建字体

3.1、获取体系自带的字体

Typeface create(String familyName, int style)

3.2、获取应用Asset目录下的字体

Typeface createFromAsset(AssetManager mgr, String path)

3.3、从字体文件中获得字体

Typeface createFromFile(String path)
Typeface createFromFile(File path)

2.3、文字的丈量

1、文字的外接矩形

void getTextBounds(String text, int start, int end, Rect bounds)

留意,这个矩形是依据基线方位为(0,0)得到的

2、丈量文字宽度

float measureText(char[] text, int index, int count)
float measureText(String text, int start, int end)
float measureText(String text)
float measureText(CharSequence text, int start, int end)

3、文字的基线 文字的制作方位,不是由文字左上角方位所决定的,而是由文字的TextAlignbaseline所操控的:

  • 当TextAlign为LEFT时(默许),制作点为(x=文字开始方位,y=baseline)
  • 当TextAlign为CENTER时,制作点为(x=文字中心方位,y=baseline)
  • 当TextAlign为RIGHT时,制作点为(x=文字结束方位,y=baseline)

由此可见,制作文字的要害,在于找到baseline,这时就要用到Paint.getFontMetrics()函数了,该函数回来一个FontMetrics目标,其中包括以下变量:

变量 意义
ascent 字体最佳制作区域顶部到baseline的间隔
top 字体最大制作区域顶部到baseline的间隔
descent 字体最佳制作区域底部到baseline的间隔
bottom 字体最大制作区域底部到baseline的间隔
leading 上一行字符的descent到下一行的ascent之间的间隔

它们与baseline的方位关系如图所示:

三、Android制作常识总结(画笔篇)

咱们经过FontMetrics,能够很快的计算出baseLine留意,由于坐标系的关系,FontMetrics的bottom为正数,top为负数。


3、高档

3.1、setShadowLayer

假如需求给TextView的文字增加暗影,有两种办法:

1、xml布局中设置shadowRadiusshadowDxshadowDyshadowColor这4个特点
2、调用TextView的setShadowLayer办法。

这里咱们介绍第二种,setShadowLayer能够在当时图层下方制作一个暗影图层,并具有指定的偏移量和色彩以及含糊半径。

void setShadowLayer(float radius, float dx, float dy, int shadowColor)

参数意义:

  • radius:暗影含糊半径
  • dxdy:暗影方位偏移
  • shadowColor:暗影色彩

留意:设置setShadowLayer后,制作Bitmap的暗影作用会有所不同(也跟体系版本相关):

1、假如Bitmap是彩色不透明图画,如由jpg图片获取的Bitmap

暗影由Bitmap含糊后加上shadowColor的alpha得到。

三、Android制作常识总结(画笔篇)

2、假如Bitmap是单色不透明图画,如由jpg图片获取的Bitmap,并调用Bitmap.extractAlpha()

暗影由shadowColor含糊而来。

三、Android制作常识总结(画笔篇)

3、假如Bitmap是彩色透明图画,如由png图片获取的Bitmap

1、暗影不会被含糊
2、暗影由Bitmap和shadowColor的alpha得到。

三、Android制作常识总结(画笔篇)

4、假如Bitmap是单色透明图画,如由png图片获取的Bitmap,并调用Bitmap.extractAlpha()

1、暗影不会被含糊
2、暗影色彩是shadowColor。

三、Android制作常识总结(画笔篇)

总结:

1、假如图片带有透明通道,暗影将不会被含糊,并受shadowColor的alpha值影响。
2、假如图片是单色,暗影将由shadowColor决定。

当不再需求暗影时,能够经过将radius设置为0,或者调用clearShadowLayer来清除暗影。


3.2、setMaskFilter

MaskFilter setMaskFilter(MaskFilter maskfilter)

MaskFilter有2个子类:

  • BlurMaskFilter:含糊作用
  • EmbossMaskFilter:浮雕作用

其中BlurMaskFilter结构函数

public BlurMaskFilter(float radius, Blur style)

需求指定含糊半径,和含糊类型:

含糊类型 意义
NORMAL 表里都含糊
SOLID 内部直接制作,外部含糊
OUTER 内部不制作,外部含糊
INNER 含糊内部,外部不制作

三、Android制作常识总结(画笔篇)

留意:运用BlurMaskFilter含糊Bitmap时,也有跟setShadowLayer相同的限制,只有当Bitmap不透明,才会有含糊作用。那如何生成一个带透明度的纯色暗影图片呢?

可经过设置BlurMaskFilter,再调用

Bitmap extractAlpha(Paint paint, int[] offsetXY)

办法即可。

public class ShadowView extends View {
    private Paint mPaint = new Paint();
    private Bitmap mAlphaBitmap;
    public ShadowView(Context context) {
        super(context);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mPaint.setColor(Color.BLACK);
        mPaint.setTextSize(40);
//        mPaint.setShadowLayer(10, 10, 10, Color.argb(255, 255, 0, 0));
        mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cat_dog);
        mAlphaBitmap = Bitmap.createScaledBitmap(bitmap, 400, 400, true).extractAlpha(mPaint, new int[]{10, 10});
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        canvas.drawText("青云", 140, 200, mPaint);
        canvas.drawCircle(150, 400, 50, mPaint);
        canvas.saveLayerAlpha(new RectF(400, 50, 400 + mAlphaBitmap.getWidth(), 50 + +mAlphaBitmap.getHeight()), 100);
        canvas.drawBitmap(mAlphaBitmap, 400, 50, mPaint);
        canvas.restore();
    }
}

3.3、setPathEffect

setPathEffect(PathEffect effect)
public class EffectView extends View {
    private PathEffect[] mEffect = new PathEffect[6];
    private Path mPath = new Path();
    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    public EffectView(Context context) {
        super(context);
        for (int i = 0; i <= 30; i++) {
            mPath.lineTo(i * 35, (float) (Math.random() * 100));
        }
        mEffect[0] = null;
        mEffect[1] = new CornerPathEffect(30);
        mEffect[2] = new DiscretePathEffect(3.0F, 5.0F);
        mEffect[3] = new DashPathEffect(new float[]{20, 10, 5, 10}, 0);
        Path path = new Path();
        path.addRect(0, 0, 8, 8, Path.Direction.CCW);
        mEffect[4] = new PathDashPathEffect(path, 12, 0, PathDashPathEffect.Style.ROTATE);
        mEffect[5] = new ComposePathEffect(mEffect[3], mEffect[1]);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLUE);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        for (PathEffect pathEffect : mEffect) {
            mPaint.setPathEffect(pathEffect);
            canvas.drawPath(mPath, mPaint);
            canvas.translate(0, 150);
        }
    }
}

三、Android制作常识总结(画笔篇)


3.4、setShader

Shader setShader(Shader shader)

参数:Shader 着色器目标,一般运用体系所供给的几个子类:

  • LinearGradient:线性烘托(霓虹灯文字,影子图片)
  • RadialGradient:环形烘托(水波纹作用)
  • SweepGradient:扫描烘托(雷达扫描作用)
  • BitmapShader:位图烘托
  • ComposeShader:组合烘托,例如LinearGradient+BitmapShader
public BitmapShader(Bitmap bitmap, TileMode tileX,  TileMode tileY)

TileMode取值如下:

TileMode取值 意义
TileMode.CLAMP 用边缘像素来填充多余空间
TileMode.REPEAT 重复原图画来填充多余空间
TileMode.MIRROR 运用镜像图画来填充多余空间

留意:填充顺序为先竖向填充,再横向填充,并且制作是从左上角进行制作,与画笔方位无关。

所以这会照成一些问题,如:

  • 1、单个图画不能充溢整个屏幕
  • 2、单个图画不能在控件中部方位完整显示

解决方案为:Shader.setLocalMatrix


3.5、setColorFilter

ColorFilter setColorFilter(ColorFilter filter)`

设置色彩过滤,一般运用ColorFilter的三个子类

LightingColorFilter:光照作用
PorterDuffColorFilter:指定一个色彩和一种PorterDuff.Mode与制作目标进行组合
ColorMatrixColorFilter:运用一个ColorMatrix来对色彩进行处理
    ColorMatrix类
        ColorMatrix.setScale //色度调理
        ColorMatrix.setSaturation //饱和度调理,0-无色彩,1-默许作用,>1饱和度加强
        ColorMatrix.setRotate //色彩调理

常见作用:

  • 平移运算—加法
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1, 0, 0, 0, 0,
        0, 1, 0, 0, 100,
        0, 0, 1, 0, 0,
        0, 0, 0, 1, 0,
});
  • 反相作用 — 底片作用
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        -1, 0, 0, 0, 255,
        0, -1, 0, 0, 255,
        0, 0, -1, 0, 255,
        0, 0, 0, 1, 0,
});
  • 缩放运算—乘法 — 色彩增强
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1.2f, 0, 0, 0, 0,
        0, 1.2f, 0, 0, 0,
        0, 0, 1.2f, 0, 0,
        0, 0, 0, 1.2f, 0,
});
  • 黑白照片 将三通道变为单通道的灰度模式 原理:只要把R G B 三通道的色彩信息设置成相同,那么图画就会变成灰色,一起为了确保图画亮度不变,同一个通道里的R+G+B =1
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        0.213f, 0.715f, 0.072f, 0, 0,
        0.213f, 0.715f, 0.072f, 0, 0,
        0.213f, 0.715f, 0.072f, 0, 0,
        0, 0, 0, 1, 0,
});
  • 发色作用—(比方赤色和绿色交换)
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1, 0, 0, 0, 0,
        0, 0, 1, 0, 0,
        0, 1, 0, 0, 0,
        0, 0, 0, 0.5F, 0,
});
  • 复古作用
ColorMatrix colorMartrix = new ColorMatrix(new float[]{
        1 / 2f, 1 / 2f, 1 / 2f, 0, 0,
        1 / 3f, 1 / 3f, 1 / 3f, 0, 0,
        1 / 4f, 1 / 4f, 1 / 4f, 0, 0,
        0, 0, 0, 1, 0,
});

3.6、setXfermode

混合模式是Paint绘图中最难的部分,它能够将两张图片无缝结合,实现类似Photoshop中的两张图片融合作用。

Xfermode setXfermode(Xfermode xfermode)

Xfermode是一个空类,PorterDuffXfermode是其唯一的子类。

在介绍Xfermode之前,咱们先介绍一下PorterDuff.Mode离屏烘托相关常识。