是什麼
Paint,顧名思義,就是畫,作動詞畫畫,引申為畫筆,是以paint就相當于我們平常使用的畫筆,而對paint的一些setXXX操作就是日常對畫筆粗細,顔色等的操作,但是程式中的paint可能會比生活中的更強大些。
怎麼樣
API文檔解釋:
The Paint class holds the style and color information about how to draw geometries, text and bitmaps.
從Api定義可知,畫筆持有樣式和顔色資訊,關于怎麼樣的資訊呢,關于如何繪制幾何圖形,文本和位圖的樣式和顔色資訊。
大體分為兩類,圖形繪制和文本繪制。
怎麼用
從構造方法開始看

有圖可知,Paint有三個構造方法,
- 第一個是無參數構造方法,也是預設構造方法,攜帶預設設定,比如預設黑色,無坑鋸齒,不加粗等。
- 第二個是帶flags參數的構造方法,将光标移到這個構造方法上,會對flags做這樣的解釋
Android學習之Paint圖形圖像處理(一)
初看以為是flags的枚舉,于是在使用時這樣
發現沒有,原來重點在前一句
set the paint's flags
設定paint的flags,當然是用Paint去獲得flags呀~
對着api文檔,一一解釋這裡的枚舉類型是什麼作用,也可以直接檢視API文檔
截了一張圖,更直覺
分别表示:
- 可抗鋸齒
- 可設定字間距
- 可抖動
- 可設定标記
- 可過濾位圖
- 設定暗示模式為HINTING_OFF,不可暗示
- 設定暗示模式為HINTING_OFF,可暗示
- 設定為線性文本
- 設定為删除線效果文本
- 設定為可亞像素文本
- 設定為下劃線效果文本
當在構造方法中設定了這些值,就不用通過paint對象去設定了,但我個人認為,通過對象去設定更為友善
- 第三個是設定Paint參數的構造方法,初始化paint的屬性,感覺和第二個構造方法很相似,不知道有啥差別,而且paint都有那麼多setXXX方法了為什麼還要加這兩個個構造方法呢,直接對預設的對象進行設定不行麼?這是我的疑問,可能很無知,但我确實不知道,如果有幸被哪位知道的人看到了,麻煩告訴我一聲,謝謝~
從API開始看
圖形繪制
// 參數1,透明度,參數2:紅,參數3:綠,參數4:藍 均為int 類型,取值範圍0~255,不是小數
setARGB(int a,int r,int g,int b);
//設定透明度,參數同上參數1,取值範圍相同
setAlpha(int a);
//設定顔色,使用顔色值來表示,該顔色值包括透明度和RGB顔色
setColor(int color);
//設定是否坑鋸齒,會消耗大量資源,繪圖速度變慢[這個屬性要實際了解,在後面借用别人的一張圖]
setAntiAlias(boolean b);
//設定是否使用圖像抖動處理,設定為true會使繪制出來的圖像更加平滑飽滿[這個屬性要實際了解,在後面借用别人的一張圖]
setDither(boolean dither);
//設定是否使用圖像抖動處理,如果該項設定為true,則圖像在動畫進行中會濾掉對Bitmap圖像的優化操作,加快顯示速度,但圖檔效果可能會受影響,本設定項依賴于dither和xfermode的設定[這個屬性要實際了解,在後面借用别人的一張圖]
setFilterBitmap(boolean filter);
//設定MaskFilter,可以用不同的MaskFilter實作濾鏡的效果,如濾化,立體等 ,後面在研究
setMaskFilter(MaskFilter maskfilter);
//設定顔色過濾器,可以在繪制顔色時實作不用顔色的變換效果,後面研究
setColorFilter(ColorFilter colorfilter);
//設定畫筆樣式
setStyle(Paint.Style style);
//設定繪制路徑的效果,如點畫線,線畫幾何等
setPathEffect(PathEffect effect)
//設定圖像效果,使用Shader可以繪制出各種漸變效果[後面的文章再詳細複習]
setShader(Shader shader);
//在圖形下面設定陰影層,産生陰影效果,radius為陰影的角度,dx和dy為陰影在x軸和y軸上的距離,color為陰影的顔色
setShadowLayer(float radius ,float dx,float dy,int color);
//當畫筆樣式為STROKE或FILL_OR_STROKE時,設定筆刷的圖形樣式,如圓形樣式Cap.ROUND,或方形樣式Cap.SQUARE,與setStyle結合使用
setStrokeCap(Paint.Cap cap);
//設定繪制時各圖形的結合方式,如平滑效果等[後面詳細複習]
setSrokeJoin(Paint.Join join);
//設定描邊寬度,與setStroke結合使用
setStrokeWidth(float width);
//設定圖形重疊時的處理方式,如合并,取交集或并集,經常用來制作橡皮的擦除效果,參數設定可參照這篇文章[Xfermode ](http://407827531.iteye.com/blog/1470519)
setXfermode(Xfermode xfermode);
文本繪制
//模拟實作粗體文字,如果字型太小會擠成一團,效果不好
setFakeBoldText(boolean fakeBoldText);
//設定設定亞像素文本,該項為true,将有助于文本在LCD螢幕上的顯示效果,該設定與第二個構造方法中SUBPIXE_TEXT_FLAG一樣
setSubpixelText(boolean subpixelText);
//設定繪制文字的對齊方向
setTextAlign(Paint.Align align);
//設定繪制文字x軸的縮放比例,可以實作文字的拉伸的效果
setTextScaleX(float scaleX);
//設定繪制文本的大小
setTextSize(float textSize);
//設定斜體文字,skewX為傾斜弧度
setTextSkewX(float skewX);
//設定Typeface對象,即字型風格,包括粗體,斜體以及襯線體,非襯線體等
//Typeface.DEFAULT:預設字型。Typeface.DEFAULT_BOLD:加粗字型。Typeface.MONOSPACE:monospace字型。Typeface.SANS_SERIF:sans字型。Typeface.SERIF:serif字型。
setTypeface(Typeface typeface);
設定帶有下劃線的文字效果
setUnderlineText(boolean underlineText);
//設定帶有删除線的效果
setStrikeThruText(boolean strikeThruText);
着重API
- setColor(int color)
在xml裡面我們通常使用#加A~F六位或者八位來設定顔色值,帶#号的顔色表示方法
其實就是32位argb的表示方案,然而在setColor裡面我們需要傳入int值,是以需要把#改成0x,比如白色在xml中表示為#ffffff,在java代碼中表示為0xffffff。
-
setARGB(int a,int r.int g,int b)
和setColor差不多,也是設定顔色值,但這裡是分開設定,同樣的每個參數還可以用十六進制的int值來傳入,比如綠色 #FF00FF00 就可以傳入,setARGB(0xFF,0x00,0xFF,0x00),同理也可以用十進制的來傳入,setARGB(255,0,255,0)
-
setStyle(Paint.Style s)
設定畫筆的樣式, 樣式取值 有三種:
Paint.Style.FILL :填充内部
Paint.Style.FILL_AND_STROKE :填充内部和描邊
Paint.Style.STROKE :僅描邊
-
setStrokeWidth(float w)
設定畫筆描邊寬度
-
setAntAlias(boolean b)
設定是否坑鋸齒,設定抗鋸齒會增加資源消耗,使繪制時間增長。
盜用五長老的圖加以了解
Android學習之Paint圖形圖像處理(一) -
setStrokeJoin(Paint.Join j)
設定線段連接配接處的連接配接模式,取值有:
Join.MITER(結合處為銳角)
Join.Round(結合處為圓弧)
Join.BEVEL(結合處為直線)
-
setTypeface(Typeface typeface) 字型樣式
有五種:
Typeface.DEFAULT:預設字型。
Typeface.DEFAULT_BOLD:加粗字型。
Typeface.MONOSPACE:monospace字型。
Typeface.SANS_SERIF:sans字型。
Typeface.SERIF:serif字型。
-
setDither(boolean dither);
設定是否使用圖像抖動處理,會使繪制出來的圖檔顔色更加平滑和飽滿,圖像更加清晰
這裡我盜用五長老的兩張圖看看效果
設定為false的情況
Android學習之Paint圖形圖像處理(一)
設定為true的情況
true比false更柔和。
- setLetterSpacing(float letterSpacing):設定行間距,預設為0
- setLinearText (boolean linearText)
這個引用五長老的解釋
設定是否打開線性文本辨別,這玩意對大多數人來說都很奇怪不知道這玩意什麼意思。想要明白這東西你要先知道文本在Android中是如何進行存儲和計算的。在Android中文本的繪制需要使用一個bitmap作為單個字元的緩存,既然是緩存必定要使用一定的空間,我們可以通過setLinearText (true)告訴Android我們不需要這樣的文本緩存。
-
setXfermode (Xfermode xfermode)
參考文章http://407827531.iteye.com/blog/1470519
-
setColorFilter(ColorFilter filter)
比較複雜,參照文章http://www.cnblogs.com/tianzhijiexian/p/4297104.html
- reset();畫筆重置,将設定歸0,設為預設值。
小
Demo
建立項目,建立java類
MyView
繼承View,重寫構造方法和onDraw方法
package com.cd.paintdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Sky
* on 2016/10/28.
* Describe:
*/
public class MyView extends View {
Paint mPaint;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//指定畫布的背景為白色
canvas.drawColor(Color.WHITE);
//建立采用預設設定的畫筆
mPaint=new Paint();
//使用坑鋸齒功能
mPaint.setAntiAlias(true);
//設定筆觸的寬度
mPaint.setStrokeWidth();
//設定填充樣式為描邊
mPaint.setStyle(Paint.Style.STROKE);
//繪制藍色的圓形
mPaint.setColor(Color.BLUE);
canvas.drawCircle(,,,mPaint);
//繪制黃色的圓形
mPaint.setColor(Color.YELLOW);
canvas.drawCircle(,,,mPaint);
//繪制黑色的圓形
mPaint.setColor(Color.BLACK);
canvas.drawCircle(,,,mPaint);
//繪制綠色的圓形
mPaint.setColor(Color.GREEN);
canvas.drawCircle(,,,mPaint);
//繪制紅色的圓形
mPaint.setColor(Color.RED);
canvas.drawCircle(,,,mPaint);
}
}
删除xml中預設的textview,使用自定義的這個view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cd.paintdemo.MainActivity">
<com.cd.paintdemo.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
運作結果
參考文章:
http://www.jianshu.com/p/7116e1b429c0
http://www.jianshu.com/p/be3785a33582
http://www.jianshu.com/p/f801a4528651
http://www.jianshu.com/p/3edecb48aa68