Android簡單的繪圖機(jī)制與技巧

導(dǎo)語

為了用戶體驗(yàn)更好嚣潜,優(yōu)美的界面必不可少碧注,所以嘶窄,繪圖就很重要了。

主要內(nèi)容

  • Android屏幕相關(guān)知識(shí)
  • Android 2D繪圖基礎(chǔ)
  • Android XML繪圖
  • Android繪圖簡單技巧

具體內(nèi)容

屏幕的尺寸信息

主要還是因?yàn)锳ndroid的屏幕確實(shí)五花八門脊僚,所以在一定程度上的適配問題也是很捉急的相叁,所以我們要對這塊屏幕充分的認(rèn)識(shí)。

屏幕參數(shù)

一塊屏幕通常具備以下的幾個(gè)參數(shù):

  • 屏幕大辛苫稀:指屏幕對角線的長度增淹,通常用寸來表示,例如4.7寸舶衬,5.5寸埠通。
  • 分辨率:分辨率是指實(shí)際屏幕的像素點(diǎn)個(gè)數(shù),例如720X1280就是指屏幕的分辨率逛犹,寬有720個(gè)像素點(diǎn)端辱,高有1280個(gè)像素點(diǎn)。
  • PPI:每英寸像素又稱為DPI虽画,他是由對角線的的像素點(diǎn)數(shù)除以屏幕的大小所得舞蔽,通常有400PPI就已經(jīng)很6了。
系統(tǒng)屏幕密度

每個(gè)廠商的安卓手機(jī)具有不同的大小尺寸和像素密度的屏幕码撰,安卓系統(tǒng)如果要精確到每種DPI的屏幕渗柿,基本上是不可能的,因此系統(tǒng)定義了幾個(gè)標(biāo)準(zhǔn)的DPI。

密度 密度值 分辨率
ldpi 120 240×320
mdpi 160 320×480
hdpi 240 480×800
xhdpi 320 720×1280
xxhdpi 480 1080×1920
獨(dú)立像素密度dp

這是由于各種屏幕密度的不同,導(dǎo)致同樣像素大小的長度朵栖,在不同密度的屏幕上顯示長度不同颊亮,因此相同長度的屏幕,高密度的屏幕包含更多的像素點(diǎn)陨溅,在安卓系統(tǒng)中使用mdpi密度值為160的屏幕作為標(biāo)準(zhǔn)终惑,在這個(gè)屏幕上,1px = 1dp门扇,其他屏幕則可以通過比例進(jìn)行換算雹有,例如同樣是100dp的長度,mdpi中為100px臼寄,而在hdpi中為150霸奕,我們也可以得出在各個(gè)密度值中的換算公式,在mdpi中 1dp = 1px吉拳,在hdpi中质帅,1dp = 1.5px,在xhdpi中合武,1dp = 2px临梗,在xxhdpi中1dp = 3px,由此可見稼跳,我們換算比例即: l:m:h:xh:xxh = 3:4:6:8:12盟庞。

單位換算

在程序中,我們可以非常方便地對一些單位的換算汤善,下面的代碼給出了一種換算的方法我們可以把這些代碼作為工具類保存在項(xiàng)目中什猖。

package com.lgl.playview;

import android.content.Context;


/**
 * dp,sp轉(zhuǎn)換成px的工具類
 * Created by lgl on 16/3/23.
 */
public class DisplayUtils {

    /**
     * 將px值轉(zhuǎn)換成dpi或者dp值红淡,保持尺寸不變
     *
     * @param content
     * @param pxValus
     * @return
     */
    public static int px2dip(Context content, float pxValus) {
        final float scale = content.getResources().getDisplayMetrics().density;
        return (int) (pxValus / scale + 0.5f);
    }

    /**
     * 將dip和dp轉(zhuǎn)化成px,保證尺寸大小不變不狮。
     *
     * @param content
     * @param pxValus
     * @return
     */
    public static int dip2px(Context content, float pxValus) {
        final float scale = content.getResources().getDisplayMetrics().density;
        return (int) (pxValus / scale + 0.5f);
    }

    /**
     * 將px轉(zhuǎn)化成sp,保證文字大小不變。
     *
     * @param content
     * @param pxValus
     * @return
     */
    public static int px2sp(Context content, float pxValus) {
        final float fontScale = content.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValus / fontScale + 0.5f);
    }

    /**
     * 將sp轉(zhuǎn)化成px,保證文字大小不變在旱。
     *
     * @param content
     * @param pxValus
     * @return
     */
    public static int sp2px(Context content, float pxValus) {
        final float fontScale = content.getResources().getDisplayMetrics().scaledDensity;
        return (int) (pxValus / fontScale + 0.5f);
    }
}

其實(shí)的density就是前面所說的換算比例摇零,這里使用的是公式換算方法進(jìn)行轉(zhuǎn)換,同時(shí)系統(tǒng)也提供了TypedValue幫助我們轉(zhuǎn)換桶蝎。

/**
 * dp2px
 * @param dp
 * @return
 */
protected int dp2px(int dp){
    return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,getResources().getDisplayMetrics());
}

/**
 * sp2px
 * @param dp
 * @return
 */
protected int sp2px(int sp){
    return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,sp,getResources().getDisplayMetrics());
}

2D繪圖基礎(chǔ)

系統(tǒng)通過提供的Canvas對象提供繪圖方法驻仅。它提供了各種繪制圖像的API,如drawPoint(點(diǎn))登渣、drawLine(線)噪服、drawRect(矩形)、drawVertices(多邊形)胜茧、drawArc(徽秤拧)、darwCircle(圓),等等雹顺。Paint作為一個(gè)非常重要的元素丹墨,功能也是很強(qiáng)大的,這里簡單地列舉一些它的屬性和對應(yīng)的功能嬉愧。

  • setAntiAlias():設(shè)置畫筆的鋸齒效果带到。
  • setColor():設(shè)置畫筆的顏色。
  • setARGB():設(shè)置畫筆的A英染、R、G被饿、B值四康。
  • setAlpha():設(shè)置畫筆的Alpha值。
  • setTextSize():設(shè)置字體的尺寸狭握。
  • setStyle():設(shè)置畫筆的風(fēng)格(空心或?qū)嵭模?/li>
  • setStrokeWidth():設(shè)置空心邊框的寬度闪金。
  • getColor():獲取畫筆的顏色。

設(shè)置Paint的Style可以畫出空心或者實(shí)心的矩形:

paint.setStyle(Paint.Style.STROKE);  // 空心效果
paint.setStyle(Paint.Style.FILL);  // 實(shí)心效果

系統(tǒng)通過提供的Canvas對象來提供繪圖方法:

  • canvas.drawPoint(x, y, paint):繪制點(diǎn)论颅。
  • canvas.drawLine(startX, startY ,endX, endY, paint):繪制直線哎垦。
  • canvas.drawLines(new float[]{startX1, startY1, endX1, endY1,……,startXn, startYn, endXn, endYn}, paint):繪制多條直線。
  • canvas.drawRect(left, top, right, bottom, paint):繪制矩形恃疯。
  • canvas.drawRoundRect(left, top, right, bottom, radiusX, radiusY, paint):繪制圓角矩形这刷。
  • canvas.drawCircle(circleX, circleY, radius, paint):繪制圓绘搞。
  • canvas.drawOval(left, top, right, bottom, paint):繪制橢圓。
  • canvas.drawText(text, startX, startY, paint):繪制文本。
  • canvas.drawPosText(text, new float[]{X1,Y1,X2,Y2,……Xn,Yn}, paint):在指定位置繪制文本而涉。
  • Path path = new Path();
    path.moveTo(50, 50);
    path.lineTo(100, 100);
    path.lineTo(100, 300);
    path.lineTo(300, 50);
    canvas.drawPath(path, paint):繪制路徑。
  • 繪制扇形:
    paint.setStyle(Paint.Style.STROKE);
    drawArc(left, top, right,bottom, startAngle, sweepAngle, true, paint);
  • 繪制弧形:
    paint.setStyle(Paint.Style.STROKE);
    drawArc(left, top, right,bottom, startAngle, sweepAngle, false, paint);
  • 繪制實(shí)心扇形:
    paint.setStyle(Paint.Style.FILL);
    drawArc(left, top, right,bottom, startAngle, sweepAngle, true, paint);
  • 繪制實(shí)心弧形:
    paint.setStyle(Paint.Style.FILL);
    drawArc(left, top, right,bottom, startAngle, sweepAngle, false, paint);

Android XML繪圖

XML在Android系統(tǒng)中不僅是Java中的一個(gè)布局文件灸姊、配置列表诡挂。在Android開發(fā)者的手上,它可以變成一張畫腾仅、一幅圖乒裆。Android的開發(fā)者給XML提供了幾個(gè)強(qiáng)大的技能來幫助實(shí)現(xiàn)這一功能。

bitmap

通過這樣在XML中使用Bitmap就可以將圖片直接轉(zhuǎn)換成了Bitmap在程序中使用推励。

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@mipmap/ic_launcher">
</bitmap>

通過這樣引用圖片就可以將圖片直接轉(zhuǎn)化成Bitmap讓我們在程序中使用鹤耍。

Shape

通過Shape可以在XML中繪制各種形狀:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">
    <!--默認(rèn)是rectangle-->

    <!--當(dāng)shape= rectangle的時(shí)候使用-->
    <corners
        android:bottomLeftRadius="1dp"
        android:bottomRightRadius="1dp"
        android:radius="1dp"
        android:topLeftRadius="1dp"
        android:topRightRadius="1dp" />
    <!--半徑,會(huì)被后面的單個(gè)半徑屬性覆蓋吹艇,默認(rèn)是1dp-->

    <!--漸變-->
    <gradient
        android:angle="1dp"
        android:centerColor="@color/colorAccent"
        android:centerX="1dp"
        android:centerY="1dp"
        android:gradientRadius="1dp"
        android:startColor="@color/colorAccent"
        android:type="linear"
        android:useLevel="true" />

    <!--內(nèi)間距-->
    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

    <!--大小惰蜜,主要用于imageview用于scaletype-->
    <size
        android:width="1dp"
        android:height="1dp" />

    <!--填充顏色-->
    <solid android:color="@color/colorAccent" />

    <!--指定邊框-->
    <stroke
        android:width="1dp"
        android:color="@color/colorAccent" />
    <!--虛線寬度-->
    android:dashWidth= "1dp"

    <!--虛線間隔寬度-->
    android:dashGap= "1dp"

</shape>

shape可以說是xml繪圖的精華所在,而且功能十分的強(qiáng)大受神,無論是扁平化抛猖,擬物化還是漸變,都是十分的OK,我們現(xiàn)在來做一個(gè)陰影的效果财著。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <gradient
        android:angle="45"
        android:endColor="#805FBBFF"
        android:startColor="#FF5DA2FF" />

    <padding
        android:bottom="7dp"
        android:left="7dp"
        android:right="7dp"
        android:top="7dp" />

    <corners android:radius="8dp" />

</shape>

![Uploading 20160327205743972_658299.gif . . .]

Layer

Layer是在PhotoShop中是非常常用的功能联四,在Android中,我們同樣可以實(shí)現(xiàn)圖層的效果撑教。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--圖片1-->
    <item android:drawable="@mipmap/ic_launcher"/>

    <!--圖片2-->
    <item
        android:bottom="10dp"
        android:top="10dp"
        android:right="10dp"
        android:left="10dp"
        android:drawable="@mipmap/ic_launcher"
        />

</layer-list>
Selector

Selector的作用是幫助開發(fā)者實(shí)現(xiàn)靜態(tài)View的反饋朝墩,通過設(shè)置不同的屬性呈現(xiàn)不同的效果。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 默認(rèn)時(shí)候的背景-->
    <item android:drawable="@mipmap/ic_launcher" />

    <!-- 沒有焦點(diǎn)時(shí)候的背景-->
    <item android:drawable="@mipmap/ic_launcher" android:state_window_focused="false" />

    <!-- 非觸摸模式下獲得焦點(diǎn)并點(diǎn)擊時(shí)的背景圖片-->
    <item android:drawable="@mipmap/ic_launcher" android:state_pressed="true" android:state_window_focused="true" />

    <!-- 觸摸模式下獲得焦點(diǎn)并點(diǎn)擊時(shí)的背景圖片-->
    <item android:drawable="@mipmap/ic_launcher" android:state_focused="false" android:state_pressed="true" />

    <!--選中時(shí)的圖片背景-->
    <item android:drawable="@mipmap/ic_launcher" android:state_selected="true" />

    <!--獲得焦點(diǎn)時(shí)的圖片背景-->
    <item android:drawable="@mipmap/ic_launcher" android:state_focused="true" />

</selector>

這一方法可以幫助開發(fā)者迅速制作View的反饋伟姐,通過配置不同的觸發(fā)事件收苏,selector會(huì)自動(dòng)選中不同的圖片,特別是自定義button的時(shí)候愤兵,而我們不再使用原生單調(diào)的背景鹿霸,而是使用selector特別制作的背景,就能完美實(shí)現(xiàn)觸摸反饋了秆乳。

通常情況下懦鼠,上面提到的這些方法都可以共同實(shí)現(xiàn),下面這個(gè)例子就展示了在一個(gè)selector中使用shape作為他的item的例子屹堰,實(shí)現(xiàn)一個(gè)具體點(diǎn)擊反饋效果的肛冶,圓角矩形的selector,代碼如下扯键。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <!--填充顏色-->
            <solid android:color="#33444444" />
            <!--設(shè)置按鈕的四個(gè)角為弧形-->
            <corners android:radius="5dp" />
            <!--間距-->
            <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
        </shape>
    </item>

    <item>
        <shape android:shape="rectangle">
            <!--填充顏色-->
            <solid android:color="#FFFFFF" />
            <!--設(shè)置按鈕的四個(gè)角為弧形-->
            <corners android:radius="5dp" />
            <!--間距-->
            <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
        </shape>
    </item>
</selector>

效果圖睦袖。

Android繪圖技巧

在學(xué)完Android的基本繪圖之后我們來講解一下常用的繪圖技巧。

Canvas

Canvas作為繪制圖形的直接對象忧陪,提供了一下幾個(gè)非常有用的方法:

  • Canvas.save()扣泊。
  • Canvas.restore()。
  • Canvas.translate()嘶摊。
  • Canvas.roate()延蟹。

首先,我們來看一下前面兩個(gè)方法:

在講解這兩個(gè)方法之前叶堆,首先來了解一下Android繪圖的坐標(biāo)體系阱飘,這個(gè)其實(shí)這個(gè)前面已經(jīng)講了,這里不贅述虱颗,而Canvas.save()這個(gè)方法沥匈,從字面上的意思可以理解為保存畫布,他的作用就是講之前的圖像保存起來忘渔,讓后續(xù)的操作能像在新的畫布一樣操作高帖,這跟PS的圖層基本差不多。

而Canvas.restore()這個(gè)方法畦粮,則可以理解為合并圖層散址,就是講之前保存下來的東西合并乖阵。

而后面兩個(gè)方法尼?從字母上理解畫布平移或者旋轉(zhuǎn)预麸,但是把他理解為坐標(biāo)旋轉(zhuǎn)更加形象瞪浸,前面說了,我們繪制的時(shí)候默認(rèn)坐標(biāo)點(diǎn)事左上角的起始點(diǎn)吏祸,那么我們調(diào)用translate(x,y)之后对蒲,則將原點(diǎn)(0,0)移動(dòng)到(x,y)之后的所有繪圖都是在這一點(diǎn)上執(zhí)行的,這里可能說的不夠詳細(xì)贡翘,最典型的例子是畫一個(gè)表盤了蹈矮,那我們這里就演示一下畫一個(gè)表盤。

我們先來分析一下這個(gè)表盤有什么鸣驱?我們可以將他分解:

  • 儀表盤——外面的大圓盤含滴。
  • 刻度線——包含四個(gè)長的刻度線和其他短的刻度線。
  • 刻度值——包含長刻度線對應(yīng)的大的刻度尺和其他小的刻度尺丐巫。
  • 指針——中間的指針,一粗一細(xì)兩根勺美。

相信如果現(xiàn)實(shí)中叫你去畫一個(gè)儀表盤的話递胧,你應(yīng)該也會(huì)這樣的步驟去畫,實(shí)際上Android上的繪圖遠(yuǎn)比現(xiàn)實(shí)中的繪制十分的相似赡茸,與PS的繪圖更家相似缎脾,當(dāng)然,我們在繪制一個(gè)復(fù)雜的圖形之后占卧,不妨先把思路請清除了遗菠。

這個(gè)示例中,我們第一步华蜒,先畫表盤辙纬,現(xiàn)在畫個(gè)圓應(yīng)該很輕松了。關(guān)鍵在于確定圓心和半徑叭喜,這里直接居中吧贺拣。

// 畫外圓
Paint paintCircle = new Paint();
paintCircle.setAntiAlias(true);
paintCircle.setStyle(Paint.Style.STROKE);
paintCircle.setStrokeWidth(5);
canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, paintCircle);

下面,我們來畫刻度尺,這個(gè)也很簡單捂蕴,一條線而已譬涡,只要確定兩個(gè)端點(diǎn)的位置就可以,第一根線還是比較容易確定的啥辨,那后面的我們怎么去確定尼涡匀?那些斜著的我們可以用三角函數(shù)去實(shí)現(xiàn)計(jì)算,但是這其實(shí)就是一個(gè)很簡單的畫圖溉知,三角函數(shù)的運(yùn)算也要這么多陨瘩,我們不經(jīng)要思考腕够,該怎么去簡化他尼?其實(shí)Google已經(jīng)為我們想好了拾酝。

我們治國與會(huì)覺得這個(gè)不好畫燕少,主要是這個(gè)角度,那么如果我們將畫布以中心為原點(diǎn)旋轉(zhuǎn)到需要的角度尼蒿囤?每當(dāng)畫好一根線客们,我們就旋轉(zhuǎn)多少級(jí)角度,但是下一次劃線的時(shí)候依然是第一次的坐標(biāo)材诽,但是實(shí)際上我們把畫布重新還原到旋轉(zhuǎn)錢的坐標(biāo)了底挫,所有的刻度線就已經(jīng)畫好了,通過旋轉(zhuǎn)畫布——實(shí)際上是旋轉(zhuǎn)了畫圖的坐標(biāo)軸脸侥,這就避免了萬惡的三角函數(shù)了建邓,通過這樣一種相對論式的變換,間接簡化了繪圖睁枕,這時(shí)再去繪制這些刻度官边,是不是要簡單了,只需要區(qū)別整點(diǎn)和非整點(diǎn)的刻度了外遇。

// 畫刻度
Paint paintDegree = new Paint();
paintDegree.setStrokeWidth(3);
        for (int i = 0; i < 24; i++) {
// 區(qū)別整點(diǎn)和非整點(diǎn)
if (i == 0 || i == 6 || i == 12 || i == 18) {
paintDegree.setStrokeWidth(5);
paintDegree.setTextSize(30);
canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth,
mHeight / 2 - mWidth / 2 + 60, paintDegree);
String degree = String.valueOf(i);
canvas.drawText(degree,
mWidth / 2 - paintDegree.measureText(degree) / 2,
mHeight / 2 - mWidth / 2 + 90, paintDegree);
} else {
paintDegree.setStrokeWidth(3);
paintDegree.setTextSize(15);
canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2, mWidth,
mHeight / 2 - mWidth / 2 + 30, paintDegree);
String degree = String.valueOf(i);
canvas.drawText(degree,
mWidth / 2 - paintDegree.measureText(degree) / 2,
mHeight / 2 - mWidth / 2 + 60, paintDegree);
}
// 通過旋轉(zhuǎn)畫布簡化坐標(biāo)運(yùn)算
canvas.rotate(15, mWidth / 2, mHeight / 2);
}

緊接著注簿,我們就可以來繪制兩根針了,我們可以這樣來繪制跳仿。

// 畫指針
Paint paintHour = new Paint();
paintHour.setStrokeWidth(20);
Paint paintMinute = new Paint();
paintMinute.setStrokeWidth(10);
canvas.save();
canvas.translate(mWidth / 2, mHeight / 2);
canvas.drawLine(0, 0, 100, 100, paintHour);
canvas.drawLine(0, 0, 100, 200, paintMinute);
canvas.restore();

這樣運(yùn)行的效果就和最上面的效果圖一樣了诡渴,這里貼上完整的代碼。

package com.lgl.dial;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowManager;

public class DialView extends View {

    // 寬高
    private int mWidth;
    private int mHeight;

    // 構(gòu)造方法
    public DialView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 獲取屏幕的寬高
        WindowManager wm = (WindowManager) getContext().getSystemService(
                Context.WINDOW_SERVICE);
        mWidth = wm.getDefaultDisplay().getWidth();
        mHeight = wm.getDefaultDisplay().getHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);

        // 畫外圓
        Paint paintCircle = new Paint();
        paintCircle.setAntiAlias(true);
        paintCircle.setStyle(Paint.Style.STROKE);
        paintCircle.setStrokeWidth(5);
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, paintCircle);

        // 畫刻度
        Paint paintDegree = new Paint();
        paintDegree.setStrokeWidth(3);
        for (int i = 0; i < 24; i++) {
            // 區(qū)別整點(diǎn)和非整點(diǎn)
            if (i == 0 || i == 6 || i == 12 || i == 18) {
                paintDegree.setStrokeWidth(5);
                paintDegree.setTextSize(30);
                canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2,
                        mWidth / 2, mHeight / 2 - mWidth / 2 + 60, paintDegree);
                String degree = String.valueOf(i);
                canvas.drawText(degree,
                        mWidth / 2 - paintDegree.measureText(degree) / 2,
                        mHeight / 2 - mWidth / 2 + 90, paintDegree);
            } else {
                paintDegree.setStrokeWidth(3);
                paintDegree.setTextSize(15);
                canvas.drawLine(mWidth / 2, mHeight / 2 - mWidth / 2,
                        mWidth / 2, mHeight / 2 - mWidth / 2 + 30, paintDegree);
                String degree = String.valueOf(i);
                canvas.drawText(degree,
                        mWidth / 2 - paintDegree.measureText(degree) / 2,
                        mHeight / 2 - mWidth / 2 + 60, paintDegree);
            }
            // 通過旋轉(zhuǎn)畫布簡化坐標(biāo)運(yùn)算
            canvas.rotate(15, mWidth / 2, mHeight / 2);
        }

        // 畫指針
        Paint paintHour = new Paint();
        paintHour.setStrokeWidth(20);
        Paint paintMinute = new Paint();
        paintMinute.setStrokeWidth(10);
        canvas.save();
        canvas.translate(mWidth / 2, mHeight / 2);
        canvas.drawLine(0, 0, 100, 100, paintHour);
        canvas.drawLine(0, 0, 100, 200, paintMinute);
        canvas.restore();
    }

}
Layer圖層

Android中的繪圖API菲语,很大程度上都來自繪圖的API妄辩,特別是借鑒了很多PS的原理,比如圖層的概念山上,相信看過圖層的也都知道是個(gè)什么樣的眼耀,我們畫個(gè)圖來分析一下。

Android通過saveLayer()方法佩憾,saveLayerAlpha()將一個(gè)圖層入棧畔塔,使用restore()方法,restoreToCount()方法將一個(gè)圖層出棧鸯屿,入棧的時(shí)候澈吨,后面的所有才做都是發(fā)生在這個(gè)圖層上的,而出棧的時(shí)候寄摆,則會(huì)把圖層繪制在上層Canvas上谅辣,我們仿照API Demo來。

@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    canvas.drawColor(Color.WHITE);
    mPaint.setColor(Color.BLUE);
    canvas.drawCircle(150, 150, 100, mPaint);

    canvas.saveLayerAlpha(0, 0,400,400,127,LAYER_TYPE_NONE);
    mPaint.setColor(Color.RED);
    canvas.drawCircle(200, 200, 100, mPaint);
    canvas.restore();
}

當(dāng)繪制兩個(gè)相交的圓時(shí)婶恼,就是圖層桑阶。
接下來將圖層后面的透明度設(shè)置成0-255不同值 柏副。
我們分別演示127、255蚣录、0三個(gè)割择。

更多內(nèi)容戳這里(整理好的各種文集)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市萎河,隨后出現(xiàn)的幾起案子荔泳,更是在濱河造成了極大的恐慌,老刑警劉巖虐杯,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玛歌,死亡現(xiàn)場離奇詭異,居然都是意外死亡擎椰,警方通過查閱死者的電腦和手機(jī)支子,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來达舒,“玉大人值朋,你說我怎么就攤上這事」” “怎么了吞歼?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長塔猾。 經(jīng)常有香客問我,道長稽坤,這世上最難降的妖魔是什么丈甸? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮尿褪,結(jié)果婚禮上睦擂,老公的妹妹穿的比我還像新娘。我一直安慰自己杖玲,他們只是感情好顿仇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著摆马,像睡著了一般臼闻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囤采,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天述呐,我揣著相機(jī)與錄音,去河邊找鬼蕉毯。 笑死乓搬,一個(gè)胖子當(dāng)著我的面吹牛思犁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播进肯,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼激蹲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了江掩?” 一聲冷哼從身側(cè)響起学辱,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎频敛,沒想到半個(gè)月后项郊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斟赚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年着降,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拗军。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡任洞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出发侵,到底是詐尸還是另有隱情交掏,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布刃鳄,位于F島的核電站盅弛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏叔锐。R本人自食惡果不足惜挪鹏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望愉烙。 院中可真熱鬧讨盒,春花似錦、人聲如沸步责。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蔓肯。三九已至遂鹊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蔗包,已是汗流浹背稿辙。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留气忠,地道東北人邻储。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓赋咽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吨娜。 傳聞我的和親對象是個(gè)殘疾皇子脓匿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容