自定義控件繪制(Paint函數(shù)匯總)篇五

參考:

  1. https://blog.csdn.net/harvic880925/article/details/51010839

基本用法

基本設(shè)置函數(shù)

  • reset() 重置畫筆
  • setColor(int color) 給畫筆設(shè)置顏色值
  • setARGB(int a, int r, int g, int b) 同樣是設(shè)置顏色锨阿,但是利用ARGB分開設(shè)置
  • setAlpha(int a) 設(shè)置畫筆透明度
  • setStyle(Paint.Style style) 設(shè)置畫筆樣式宵睦,取值有
    • Paint.Style.FILL :填充內(nèi)部
    • Paint.Style.FILL_AND_STROKE :填充內(nèi)部和描邊
    • Paint.Style.STROKE :僅描邊
  • setStrokeWidth(float width) 設(shè)置畫筆寬度
  • setAntiAlias(boolean aa) 設(shè)置畫筆是否抗鋸齒

以上函數(shù),我們基本上都用過了墅诡;

其他設(shè)置函數(shù)

  • setStrokeCap(Paint.Cap cap) 設(shè)置線冒樣式壳嚎,取值有:
    • Cap.ROUND(圓形線冒);
    • Cap.SQUARE(方形線冒)
    • Cap.BUTT(無線冒)
  • setStrokeJoin(Paint.Join join) 設(shè)置線段連接處樣式末早,取值有:
    • Join.MITER(結(jié)合處為銳角)烟馅;
    • Join.Round(結(jié)合處為圓弧);
    • Join.BEVEL(結(jié)合處為直線)
  • setStrokeMiter(float miter) 設(shè)置筆畫的傾斜度
  • setPathEffect(PathEffect effect) 設(shè)置路徑樣式;取值類型是所有PathEffect的子類:
    • ComposePathEffect荐吉;
    • CornerPathEffect;
    • DashPathEffect;
    • DiscretePathEffect,
    • PathDashPathEffect,
    • SumPathEffect

setStrokeCap

設(shè)置線帽樣式焙糟,什么叫做線帽,看下面圖示:

val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
    strokeWidth = 80f
    color = Color.GREEN
    style = Paint.Style.STROKE
}

paint.strokeCap = Paint.Cap.BUTT        // 無線帽
canvas.drawLine(100f, 200f, 400f, 200f, paint)

paint.strokeCap = Paint.Cap.SQUARE      // 方形
canvas.drawLine(100f, 400f, 400f, 400f, paint)

paint.strokeCap = Paint.Cap.ROUND       // 圓形
canvas.drawLine(100f, 600f, 400f, 600f, paint)

paint.strokeWidth = 2f
paint.color = Color.RED
canvas.drawLine(100f, 0f, 100f, height.toFloat(), paint)
圖片來自源博客

從無線冒出來的那塊區(qū)域就是線帽样屠!就相當(dāng)于給原來的直線加上一個帽子一樣穿撮,所以叫線帽缺脉;

Android 目前只有3種線帽子;

setStrokeJoin(Paint.Join join)

設(shè)置線段連接處樣式;

val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
    strokeWidth = 40f
    color = Color.GREEN
    style = Paint.Style.STROKE
}

Path().let {
    it.moveTo(100f, 100f)
    it.lineTo(200f, 100f)
    it.lineTo(100f, 200f)
    paint.strokeJoin = Paint.Join.MITER     // 銳角
    canvas.drawPath(it, paint)

    it.moveTo(100f, 300f)
    it.lineTo(200f, 300f)
    it.lineTo(100f, 400f)
    paint.strokeJoin = Paint.Join.BEVEL     // 結(jié)合處為直線
    canvas.drawPath(it, paint)

    it.moveTo(100f, 500f)
    it.lineTo(200f, 500f)
    it.lineTo(100f, 600f)
    paint.strokeJoin = Paint.Join.ROUND     // 結(jié)合處為圓弧
    canvas.drawPath(it, paint)
}
效果圖

從圖上看悦穿,BEVELROUND并沒有明顯區(qū)別攻礼;

setPathEffect

設(shè)置路徑樣式;取值類型是所有派生自PathEffect的子類;

1. CornerPathEffect-圓形拐角效果
將原來Path生硬的直線拐角,變成圓形拐角栗柒,從下圖示

圖片來自源博客

CornerPathEffect構(gòu)造:

// radius 當(dāng)前連接兩條直線所使用的圓的半徑
public CornerPathEffect(float radius)  
來自源博客礁扮,說明radius

上圖為利用半徑R=50的圓來代替原來兩條直線間的夾角;

示例代碼:

val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
    strokeWidth = 2f
    color = Color.GREEN
    style = Paint.Style.STROKE
}

Path().let {
    it.moveTo(100f,600f)
    it.lineTo(400f,100f)
    it.lineTo(700f,900f)
    canvas.drawPath(it, paint)

    paint.pathEffect = CornerPathEffect(100f)       // radius = 100f
    canvas.drawPath(it, paint.apply { color = Color.BLACK })

    paint.pathEffect = CornerPathEffect(200f)
    canvas.drawPath(it, paint.apply { color = Color.RED })
}
不同radius的CornerPathEffect效果

2. DashPathEffect——虛線效果

功能能夠?qū)崿F(xiàn)虛線段的效果瞬沦,如下圖:


圖片來自源博客

DashPathEffect構(gòu)造

public DashPathEffect(float intervals[], float phase)  

參數(shù):

  • intervals[]:表示組成虛線的各個線段的長度太伊;整條虛線就是由intervals[]中這些基本線段循環(huán)組成的。比如逛钻,我們定義new float[] {20,10}僚焦;那這個虛線段就是由兩段線段組成的,第一個可見的線段長為20曙痘,每二個線段不可見芳悲,長度為10;
  • phase:開始繪制的偏移值


    圖片來自源博客

intervals 的 長度必須大于等于2边坤;必須有一個實線段和一個空線段來組成虛線名扛,個數(shù)必須為偶數(shù),如果是基數(shù)茧痒,最后一個數(shù)字將被忽略肮韧;

Path().let {
    it.moveTo(100f, 600f)
    it.lineTo(400f, 100f)
    it.lineTo(700f, 900f)
    canvas.drawPath(it, paint)

    // 第一條實線長度為20,第二個空線長度為10旺订,第三個實線長為100惹苗,第四條空線長充為100
    paint.pathEffect = DashPathEffect(floatArrayOf(20f, 10f, 100f, 100f), 0f)
    canvas.translate(0f, 100f)
    canvas.drawPath(it, paint.apply { color = Color.BLACK })

    // 設(shè)置偏移值
    paint.pathEffect = DashPathEffect(floatArrayOf(20f, 10f, 50f, 100f), 15f)
    canvas.translate(0f, 100f)
    canvas.drawPath(it, paint.apply { color = Color.RED })
}
效果圖

注意上面藍(lán)色箭頭,因為第二條耸峭,開始偏移了15f,所以開始是5了,明顯縮短了淋纲;

讓線動起來(不斷改變 偏離量 phase)劳闹;

// 20f, 10f, 100f, 100f 和為 230
val valueAnim1 = ValueAnimator.ofFloat(0f, 230f).apply {
    duration = 1000
    repeatMode = ValueAnimator.RESTART
    repeatCount = ValueAnimator.INFINITE
    interpolator = LinearInterpolator()
    addUpdateListener {
        path1Phase = it.animatedValue as Float
        postInvalidate()
    }
}

// 區(qū)間為(15, -165), 15 + 165 = 180
val valueAnim2 = ValueAnimator.ofFloat(15f, -165f).apply {
    duration = 2000
    repeatMode = ValueAnimator.RESTART
    repeatCount = ValueAnimator.INFINITE
    interpolator = LinearInterpolator()
    addUpdateListener {
        e("size: ${path2Phase}")
        path2Phase = it.animatedValue as Float
        postInvalidate()
    }
}

// 聯(lián)合動畫
AnimatorSet().apply {
    play(valueAnim1).with(valueAnim2)
}.start()

3.DiscretePathEffect——離散路徑效果
如下圖,圖中第一條線是原生的洽瞬,第二條線加上離散路徑效果后的樣式本涕;
DiscretePathEffect就是將原來路徑分隔成定長的線段,然后將每條線段隨機偏移一段位置伙窃; Discrete 離散的菩颖;

圖片來自源博客

DiscretePathEffect構(gòu)造:

public DiscretePathEffect(float segmentLength, float deviation) 

參數(shù)說明:

  • segmentLength:表示將原來的路徑切成多長的線段。如果值為2为障,那么這個路徑就會被切成一段段由長度為2的小線段晦闰。所以這個值越小放祟,所切成的小線段越多;這個值越大呻右,所切成的小線段越少跪妥。
  • deviation:表示被切成的每個小線段的可偏移距離。值越大声滥,就表示每個線段的可偏移距離就越大眉撵,就顯得越凌亂,值越小落塑,每個線段的可偏移原位置的距離就越小纽疟。

示例代碼:

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        strokeWidth = 2f
        color = Color.GREEN
        style = Paint.Style.STROKE
    }

    val path = getPath()
    // 原始
    canvas.drawPath(path,paint)

    canvas.translate(0f, 200f)
    paint.pathEffect = DiscretePathEffect(2f, 5f)
    canvas.drawPath(path,paint)

    canvas.translate(0f, 200f)
    paint.pathEffect = DiscretePathEffect(6f, 5f)
    canvas.drawPath(path,paint)

    canvas.translate(0f, 200f)
    paint.pathEffect = DiscretePathEffect(6f, 15f)
    canvas.drawPath(path,paint)
}

private fun getPath(): Path {
    return Path().apply {
        moveTo(0f, 0f)
        for (i in 0..40) {
            lineTo(i * 35f, (Math.random() * 150).toFloat())
        }
    }
}
效果

4. PathDashPathEffect——印章路徑效果
用另一個路徑圖案做為印章,沿著指定路徑一個個蓋上去;

構(gòu)造函數(shù):

public PathDashPathEffect(Path shape, float advance, float phase,Style style)  

參數(shù)說明:

  • Path shape:表示印章路徑憾赁;
  • float advance:表示兩個印章路徑間的距離污朽,間隙;
  • float phase:路徑繪制偏移距離缠沈,與DashPathEffect中的phase參數(shù)意義相同;
  • Style style:表示在遇到轉(zhuǎn)角時膘壶,如何操作印章以使轉(zhuǎn)角平滑過渡,取值有:
    • Style.ROTATE: 表示通過旋轉(zhuǎn)印章來過渡轉(zhuǎn)角
    • Style.MORPH: 表示通過變形印章來過渡轉(zhuǎn)角
    • Style.TRANSLATE: 表示通過位移來過渡轉(zhuǎn)角

示例代碼:

override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
            strokeWidth = 2f
            color = Color.GREEN
            style = Paint.Style.STROKE
        }

        val path = getPath()
        canvas.drawPath(path, paint)

        canvas.translate(0f, 200f)
        paint.pathEffect = PathDashPathEffect(getDashPath(), 30f, 0f, PathDashPathEffect.Style.MORPH)
        canvas.drawPath(path, paint.apply { color = Color.RED })

        canvas.translate(0f, 200f)
        paint.pathEffect = PathDashPathEffect(getDashPath(), 30f, 0f, PathDashPathEffect.Style.TRANSLATE)
        canvas.drawPath(path, paint.apply { color = Color.RED })

        canvas.translate(0f, 200f)
        paint.pathEffect = PathDashPathEffect(getDashPath(), 30f, 0f, PathDashPathEffect.Style.ROTATE)
        canvas.drawPath(path, paint.apply { color = Color.RED })
    }
    // 三角形
    private fun getDashPath(): Path {
        return Path().apply {
            moveTo(10f, 10f)
            lineTo(20f, 10f)
            lineTo(15f, 20f)
            close()
        }
    }
效果

注意轉(zhuǎn)彎處洲愤,的變型

5. ComposePathEffect與SumPathEffect
用來合并兩個特效的颓芭,但有區(qū)別;

// 有先后順序的柬赐,將第二個參數(shù)的innerpe的特效作用于路徑上
// 然后再在此加了特效的路徑上,再加第一個參數(shù)dashEffect特效亡问。
public ComposePathEffect(PathEffect outerpe, PathEffect innerpe) 

// 對原始路徑分別作用第一個特效和第二個特效。然后再將這兩條路徑合并肛宋,做為最終結(jié)果州藕。 
public SumPathEffect(PathEffect first, PathEffect second)  

示例代碼:

// 原始
val path = getPath()
canvas.drawPath(path, paint)

// 圓角特效
canvas.translate(0f, 150f)
val cornerEffect = CornerPathEffect(100f)
paint.pathEffect = cornerEffect
canvas.drawPath(path, paint.apply { color = Color.RED })

// 虛線特效
canvas.translate(0f, 150f)
val dashEffect = DashPathEffect(floatArrayOf(2f, 5f, 10f, 10f), 0f)
paint.pathEffect = dashEffect
canvas.drawPath(path, paint.apply { color = Color.RED })

// 利用ComposePathEffect先應(yīng)用圓角特效,再應(yīng)用虛線特效
canvas.translate(0f, 150f)
paint.pathEffect = ComposePathEffect(dashEffect, cornerEffect) //位置交換就只有dashEffect效果
canvas.drawPath(path, paint)

// 利用SumPathEffect,分別將圓角特效應(yīng)用于原始路徑,然后將生成的兩條特效路徑合并
canvas.translate(0f, 150f)
paint.pathEffect = SumPathEffect(cornerEffect, dashEffect)
canvas.drawPath(path, paint)
效果圖

說明:
特別注意路徑D和路徑E:
路徑D的生成方法為:

ComposePathEffect(dashEffect, cornerEffect) //位置交換就只有dashEffect效果

表示先將圓角特效應(yīng)用于原始路徑,得到路徑B酝陈,然后再在路徑B的基礎(chǔ)上應(yīng)用虛線特效得到最終的效果D;
嘗試交換參數(shù)位置時床玻,居然只有dashEffect效果了闷沥;

路徑E的生成方法為:

SumPathEffect(cornerEffect, dashEffect)  // 參數(shù)位置可交換

先將圓角特效應(yīng)用于原始路徑A得到路徑B,然后將虛線特效應(yīng)依然應(yīng)用于原始路徑侣滩,得到路徑C. 然后將路徑B和路徑C合并(即畫在一起)阔涉,就得到路徑E ;

文字設(shè)置相關(guān)函數(shù)

常用文字設(shè)置相關(guān)函數(shù)

  • setTextSize(float textSize) 設(shè)置文字大小
  • setFakeBoldText(boolean fakeBoldText) 設(shè)置是否為粗體文字
  • setStrikeThruText(boolean strikeThruText) 設(shè)置帶有刪除線效果
  • setUnderlineText(boolean underlineText) 設(shè)置下劃線
  • setTextAlign(Paint.Align align) 設(shè)置開始繪圖點位置
  • setTextScaleX(float scaleX) 水平拉伸設(shè)置
  • setTextSkewX(float skewX) 設(shè)置字體水平傾斜度拭宁,普通斜體字是-0.25涂籽,可見往右斜
  • setTypeface(Typeface typeface)

之前都有接觸過毯欣;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吃型,一起剝皮案震驚了整個濱河市唧瘾,隨后出現(xiàn)的幾起案子喇勋,更是在濱河造成了極大的恐慌缨该,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件川背,死亡現(xiàn)場離奇詭異贰拿,居然都是意外死亡蛤袒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門壮不,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汗盘,“玉大人,你說我怎么就攤上這事询一∫酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵健蕊,是天一觀的道長菱阵。 經(jīng)常有香客問我,道長缩功,這世上最難降的妖魔是什么晴及? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮嫡锌,結(jié)果婚禮上虑稼,老公的妹妹穿的比我還像新娘。我一直安慰自己势木,他們只是感情好蛛倦,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啦桌,像睡著了一般溯壶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甫男,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天且改,我揣著相機與錄音,去河邊找鬼板驳。 笑死又跛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的若治。 我是一名探鬼主播效扫,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼直砂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起浩习,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤静暂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谱秽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洽蛀,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡摹迷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了郊供。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峡碉。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驮审,靈堂內(nèi)的尸體忽然破棺而出鲫寄,到底是詐尸還是另有隱情,我是刑警寧澤疯淫,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布地来,位于F島的核電站,受9級特大地震影響熙掺,放射性物質(zhì)發(fā)生泄漏未斑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一币绩、第九天 我趴在偏房一處隱蔽的房頂上張望蜡秽。 院中可真熱鬧,春花似錦缆镣、人聲如沸芽突。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诉瓦。三九已至,卻和暖如春力细,著一層夾襖步出監(jiān)牢的瞬間睬澡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工眠蚂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留煞聪,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓逝慧,卻偏偏與公主長得像昔脯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笛臣,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354