書中的示例代碼:github
本章主要介紹的是Android的繪圖技巧
1.屏幕尺寸的信息:
- 屏幕參數(shù)有
屏幕大小
即屏幕對角線的長度赫悄,用“寸”來表示寺酪、分辨率
裸准、PPI
即每英寸像素梅尤,它由對角線的像素點(diǎn)除以屏幕大小獲得柜思。 - 系統(tǒng)屏幕密度如下
ldpi---120---240X320分辨率
mdpi---160---320X480分辨率
hdpi---240---480X800分辨率
xhdpi---320---720X1280分辨率
xxhdpi---480---1080X1920分辨率
2.單位轉(zhuǎn)換工具類(這種百度一堆 在此省略)
3.2D繪圖基礎(chǔ):
Paint類的一些屬性和對應(yīng)的功能:
setAntiAlias();//設(shè)置畫筆的鋸齒效果
setColor();//設(shè)置畫筆的顏色
setARGB();//設(shè)置畫筆的A,R,G,B的值
setAlpha();//設(shè)置畫筆的Alpha值
setTextSize();//設(shè)置字體的尺寸
setStyle();//設(shè)置畫筆的風(fēng)格(空心或者實(shí)心)
-
setStrokeWidth();//設(shè)置空心邊框的寬度
Canvas類主要的繪畫功能: canvas.drawPoint(x,y,paint);//繪制點(diǎn)
canvas.drawLine(startX,startY,endX,endY,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,...,xn,yn},paint);//指定位置繪制文本
//繪制多條直線
float[] pts={
startX1,startY1,endX1,endY1
......
startXn,startYn,endXn,endYn}
canvas.drawLines(pts,paint);
//繪制路徑
Path path=new Path();
path.moveTo(50,50);
path.lineTo(100,100);
path.lineTo(300,50);
canvas.drawPath(path,paint)
//繪制弧形或扇形
canvas.drawArc(left,top,right,bottom,startAngle,sweepAngle,useCenter,paint);
這里useCenter傳入true則繪制扇形 反之繪制弧形
4.Android的Xml繪圖:
* Bitmap:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"/>
這樣就能直接將圖片轉(zhuǎn)成bitmap在程序中使用了
* Shape:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line|oval|ring|rectangle">
<corners
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer"
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer" />
<gradient
android:angle="integer"
android:centerColor="color"
android:centerX="integer"
android:centerY="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type="linear|radial|sweep"
android:useLevel="boolean" />
<padding
android:bottom="integer"
android:left="integer"
android:right="integer"
android:top="integer" />
<size
android:width="integer"
android:height="integer" />
<!--指定大小,一般用在imageview配合scaleType使用-->
<solid android:color="color" />
<!--填充顏色-->
<stroke
android:width="integer"
android:color="color"
android:dashGap="integer"
android:dashWidth="integer" />
<!--邊框,dashGap為虛線間隔寬度巷燥,dashWidth為虛線寬度-->
</shape>
* Layer:大家可以自己試試效果 這里就不貼圖了
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_launcher" />
<item
android:drawable="@mipmap/ic_launcher"
android:left="10dp"
android:top="10dp" />
<item
android:drawable="@mipmap/ic_launcher"
android:left="20dp"
android:top="20dp" />
</layer-list>
* Selector:
通常用于view的觸摸反饋
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#334444" />
</shape>
</item>
<item android:state_pressed="false">
<shape android:shape="rectangle">
<solid android:color="#444444" />
</shape>
</item>
</selector>
5.Android繪圖技巧:
`canvas.save()`:保存之前在畫布上的操作赡盘,之后的操作就像是在新的圖層操作一樣。
`canvas.restore()`:可以理解為Photoshop中合并圖層的操作缰揪,作用是將save后的圖層與之前的圖層合并亡脑。
`canvas.translate()`:將畫布進(jìn)行平移。
`canvas.rotate()`:將畫布進(jìn)行旋轉(zhuǎn)邀跃。這兩個方法都是用來簡化繪圖而創(chuàng)建的霉咨。
`canvas.saveLayer()`:創(chuàng)建一個圖層,并將他加入一個圖層的棧拍屑,通過調(diào)用restore或者restoreToCount使其出棧途戒,出棧后會把圖像繪制到上層canvas上。
`canvas.saveLayerAlpha()`:同上僵驰,區(qū)別是可以設(shè)置圖層的透明度
6.Android色彩特效處理:
圖像的色調(diào)喷斋、飽和度、亮度這三個屬性在圖像處理中使用非常之多蒜茴,Android封裝了一個`ColorMatrix`類(顏色矩陣)星爪,通過改變矩陣值來處理這些屬性。
* 色調(diào):
//第一個參數(shù)分別為red粉私、green顽腾、blue 第二個參數(shù)為要處理的值。
ColorMatrix hueMatrix=new ColorMatrix();
hueMatrix.setRotate(0, hue);
hueMatrix.setRotate(1, hue);
hueMatrix.setRotate(2, hue);
* 飽和度:
//參數(shù)即為飽和度,當(dāng)飽和度為0時圖像就變成灰圖像了抄肖。
ColorMatrix saturationMatrix=new ColorMatrix();
saturationMatrix.setSaturation(saturation);
* 亮度:
//當(dāng)三原色以相同比例進(jìn)行混合的時候久信,就會顯示出白色,從而調(diào)節(jié)亮度漓摩。
ColorMatrix lumMatrix=new ColorMatrix();
lumMatrix.setScale(lum, lum, lum, 1);
* 讓三種效果疊加:
ColorMatrix imageMatrix=new ColorMatrix();
imageMatrix.postConcat(hueMatrix);
imageMatrix.postConcat(saturationMatrix);
imageMatrix.postConcat(lumMatrix);
7.Android圖形特效處理:
通過Matrix類來操作圖形矩陣的變換
private float[] mImageMatrix=new float[9];
Matrix matrix=new Matrix();
matrix.setValues(mImageMatrix);
//當(dāng)獲得一個變換矩陣以后通過以下代碼將一個圖像以這個變換矩陣的形式繪制出來
canvas.drawBitmap(mBitmap,matrix,null);
以下是一些變換的方法:
* `setScale();` 縮放變換
* `setSkew();` 錯切變換
* `setRotate();` 旋轉(zhuǎn)變換
* `setTranslate();` 平移變換
* `pre()和post()` 提供矩陣的前乘和后乘運(yùn)算
圖形特效這塊由于開發(fā)用的比較少 暫時記到這里
8.Android畫筆特效:
* `PorterDuffXfermode`:
[經(jīng)典示意圖](http://img.blog.csdn.net/20130828212947609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdDEyeDM0NTY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)(貼圖不方便偷個懶)
這里要注意的是裙士,PorterDuffXfermode設(shè)置的是兩個圖層交集區(qū)域的顯示方式,dst是先畫的圖形管毙,而src是后畫的圖形腿椎。比較常用的是DST_IN和SRC_IN模式來實(shí)現(xiàn)一個圓角圖形。
private Bitmap getRoundPic() {
//原圖
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.head1);
//創(chuàng)建一個和原圖一樣寬高的圖片
Bitmap out = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
//構(gòu)造畫布
Canvas canvas = new Canvas(out);
//初始化畫筆
Paint paint = new Paint();
paint.setAntiAlias(true);
//繪制形狀
canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, Math.min(bitmap.getWidth() / 2, bitmap.getHeight() / 2), paint);
//設(shè)置paint的xfermode
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//把原圖繪制上去
canvas.drawBitmap(bitmap, 0, 0, paint);
//返回新創(chuàng)建的bitmap夭咬,即圓形圖標(biāo)酥诽。
return out;
}
* `Shader`:
Shader也被稱之為著色器、渲染器皱埠,它用來實(shí)現(xiàn)一些列的漸變肮帐、渲染的效果。
* `BitmapShader` --- 位圖Shader
* `LinearGradient` --- 線性Shader
* `RadialGradient` --- 光束Shader
* `SweepGradient` --- 梯度Shader
* `ComposeShader` --- 混合Shader
除第一個Shader以外 其他Shader都實(shí)現(xiàn)了名副其實(shí)的漸變边器。BitmapShader產(chǎn)生的是一個位圖训枢,它的作用就是通過Paint對畫布進(jìn)行指定Bitmap的填充,填充有以下幾種模式可以選擇:
* `CLAMP`拉伸 --- 拉伸的是圖片最后一個像素 不斷重復(fù)
* `REPEAT`重復(fù) --- 橫向縱向不斷重復(fù)
* `MIRROR`鏡像 --- 橫向不斷旋轉(zhuǎn)重復(fù)忘巧,縱向不斷旋轉(zhuǎn)重復(fù)
這里推薦大家看下這篇[博客](http://blog.csdn.net/aigestudio/article/details/41799811)寫的非常詳細(xì)恒界。
9.`SurfaceView`:
與view的區(qū)別:
* View主要適用于主動更新的情況下,而SurfaceView 主要適用于被動更新砚嘴,例如頻繁的刷新十酣。
* View在主線程中對畫面進(jìn)行刷新,而SurfaceView通常會通過一個子線程來進(jìn)行頁面刷新际长。
* View在繪圖時沒有使用雙緩沖機(jī)制耸采,而SurfaceView在底層實(shí)現(xiàn)機(jī)制中就已經(jīng)實(shí)現(xiàn)了雙緩沖。
以下是SurfaceView的模板代碼:
public class MySurfaceView extends SurfaceView implements Runnable, SurfaceHolder.Callback {
//SurfaceHolder
private SurfaceHolder mSurfaceHolder;
//用于繪圖的Canvas
private Canvas mCanvas;
//子線程標(biāo)志位
private boolean mIsDrawing;
public MySurfaceView(Context context) {
super(context);
init();
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
// mSurfaceHolder.setFormat(PixelFormat.OPAQUE);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
@Override
public void run() {
while (mIsDrawing) {
draw();
}
}
private void draw() {
try {
//每次獲得的canvas對象都是上次的 因此上次的繪畫操作都會保存
mCanvas = mSurfaceHolder.lockCanvas();
//draw here
} catch (Exception e) {
} finally {
if (mCanvas != null) {
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
}
}