編輯:關於Android編程
現在做的這個項目需要一個折線圖的功能,當時想著使用第三方庫來實現,結果總不能令我滿意,只能通過自定義View用畫筆去畫了,這才發現 媽的 這東西我不會 趕緊去百度下,後來李大神把他畫的折線圖給我了,我一看那叫一個頂禮膜拜啊,通過百度和看源碼翻譯,一個方法一個方法的去看,,總算理出來一丟丟頭緒,先記錄下吧
在這裡邊有三個對象非常重要
Paint畫筆 Canvas畫布 Path路徑 不多說了 代碼撸起來
1.Paint畫筆和Canvas畫布
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
/**Paint畫筆 Canvas畫布
* Created by xuenan on 2016/7/14.
*/
public class MyView1 extends View{
private Paint linePaint;
public MyView1(Context context) {
super(context);
linePaint = new Paint();//初始化畫筆
//設置是否抗鋸齒;設置抗鋸齒會使圖像邊緣更清晰一些,鋸齒痕跡不會那麼明顯。
linePaint.setAntiAlias(true);
//設置填充樣式
//Paint.Style 類型:
//Paint.Style.FILL_AND_STROKE 填充且描邊
//Paint.Style.STROKE 描邊
//Paint.Style.FILL 填充
linePaint.setStyle(Paint.Style.STROKE);
//設置畫筆顏色
linePaint.setColor(Color.GREEN);
//設置畫筆寬度
linePaint.setStrokeWidth(8);
//setShadowLayer(float radius, float dx, float dy, int shadowColor) 設置陰影
//radius : 表示陰影的傾斜度
//dx : 水平位移
//dy : 垂直位移
//shadowColor : 陰影顏色
//這個方法不支持硬件加速,所以我們要測試時必須先關閉硬件加速。
//加上setLayerType(LAYER_TYPE_SOFTWARE, null); 並且確保你的最小api8以上。
//linePaint.setShadowLayer(10,15,15,Color.RED);
}
//
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//這兩個功能一樣,都是用來設置背景顏色的。
canvas.drawColor(Color.parseColor("#F5FFFA"));
//canvas.drawRGB(255, 255, 0);
//1直線繪制
//drawLine(float startX, float startY, float stopX, float stopY,@NonNull Paint paint)
//startX : 開始點X坐標
//startY : 開始點Y坐標
//stopX : 結束點X坐標
//stopY : 結束點Y坐標
//canvas.drawLine(100,100,600,600,linePaint);
//2多條直線
//drawLines(@Size(min=4,multiple=2) float[] pts, int offset, int count, Paint paint)
//drawLines(@Size(min=4,multiple=2) @NonNull float[] pts, @NonNull Paint paint)
//pts : 是點的集合且大小最小為4而且是2的倍數。表示每2個點連接形成一條直線,pts 的組織方式為{x1,y1,x2,y2….}
//offset : 集合中跳過的數值個數,注意不是點的個數!一個點是兩個數值
//count : 參與繪制的數值的個數,指pts[]裡數值個數,而不是點的個數,因為一個點是兩個數值
float [] pts={50,50,200,300,400,450,550,600};
//點(50,50)和點(200,200)連接成一條直線;點(400,400)和點(600,600)連接成直線。
//canvas.drawLines(pts,linePaint);
//表示從第二個50開始連續的4個點(50,200,200,400)連接的直線
//canvas.drawLines(pts,1,4,linePaint);
//3 點即多個點
//drawPoint(float x, float y, @NonNull Paint paint)
//canvas.drawPoint(10,10,linePaint);//一個點
//drawPoints(@Size(multiple=2) @NonNull float[] pts, @NonNull Paint paint)
//drawPoints(@Size(multiple=2) float[] pts, int offset, int count,@NonNull Paint paint)
//canvas.drawPoints(pts,linePaint);//多個點
//4矩形 區別RectF 與Rect ,RectF坐標系是浮點型;Rect坐標系是整形。
//drawRect(@NonNull RectF rect, @NonNull Paint paint)
//drawRect(@NonNull Rect r, @NonNull Paint paint)
//drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)
//left 指定矩形框左上角的x坐標
//top: 指定矩形框左上角的y坐標
//right 指定矩形框右下角的x坐標
//bottom指定矩形框右下角的y坐標
//canvas.drawRect(new Rect(20,20,300,200),linePaint);
//canvas.drawRect(new RectF(20,20,300,200),linePaint);
//canvas.drawRect(20,20,300,200,linePaint);
//5圓角矩形
//RectF: 繪制的矩形
//rx : 生成圓角的橢圓X軸半徑
//ry : 生成圓角的橢圓Y軸的半徑
//drawRoundRect(@NonNull RectF rect, float rx, float ry, @NonNull Paint paint)
//drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,@NonNull Paint paint)
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//這個方法有點坑啊 只能在5.0以上使用,推薦使用下邊的方法代替
// canvas.drawRoundRect(200,200,1000,800,15,15,linePaint);
//}
//canvas.drawRoundRect(new RectF(200,200,1000,800),15,15,linePaint);
//6圓形
//drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
//cx : 圓心X坐標
//cy : 圓心Y坐標
//radius : 半徑
//canvas.drawCircle(900,900,500,linePaint);
//7橢圓 參數為橢圓的矩形邊界
//drawOval(@NonNull RectF oval, @NonNull Paint paint)
//drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)
//canvas.drawOval(new RectF(200,200,1000,800),linePaint);
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// canvas.drawOval(200,200,1000,800,linePaint);
//}
//8 圓弧
//oval : 生成橢圓的矩形
//startAngle : 弧開始的角度 (X軸正方向為0度,順時針弧度增大)
//sweepAngle : 繪制多少弧度 (注意不是結束弧度)
//useCenter : 是否有弧的兩邊 true有兩邊 false無兩邊
//drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,@NonNull Paint paint)
//drawArc(float left, float top, float right, float bottom, float startAngle,float sweepAngle, boolean useCenter, @NonNull Paint paint)
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// canvas.drawArc(100,100,800,600,0,90,true,linePaint);
//}
//canvas.drawArc(new RectF(100,100,800,600),0,90,true,linePaint);
}
}
2.Path路徑 為了直觀 我加上了網格
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
/**Paint畫筆 Canvas畫布 Path 路徑
* Created by xuenan on 2016/7/14.
*/
/**Path的方法
*moveTo 移動起點 移動下一次操作的起點位置
*lineTo 連接直線 連接上一個點到當前點之間的直線
*setLastPoint 設置終點 重置最後一個點的位置
*close 閉合路勁 從最後一個點連接最初的一個點,形成一個閉合區域
*addRect 添加矩形 添加矩形到當前Path
*addRoundRect 添加圓角矩形 添加圓角矩形到當前Path
*addOval 添加橢圓 添加橢圓到當前Path
*addCircle 添加圓 添加圓到當前Path
*addPah 添加路勁 添加路勁到當前Path
*addArc 添加圓弧 添加圓弧到當前Path
*arcTo 圓弧 繪制圓弧,注意和addArc的區別
*isEmpty 是否為空 判定Path是否為空
*isRect 是否為矩形 判定Path是否是一個矩形
*set 替換路勁 用新的路勁替換當前路勁的所有內容
*offset 偏移路勁 對當前的路勁進行偏移
*quadTo 貝塞爾曲線 二次貝塞爾曲線的方法
*cubicTo 貝塞爾曲線 三次貝塞爾曲線的方法
*rMoveTo,rlineTo,rQuadTo,rCubicTo rXxx方法 不帶r的方法是基於原點坐標系(偏移量),帶r的基於當前點坐標系(偏移量)
*op 布爾操作 對兩個Path進行布爾運算(交集,並集)等操作
*setFillType 填充模式 設置Path的填充模式
*getFillType 填充模式 獲取Path的填充
*isInverseFillType 是否逆填充 判斷是否是逆填充模式
*toggleInverseFillType 相反模式 切換相反的填充模式
*getFillType 填充模式 獲取Path的填充
*incReserve 提示方法 提示Path還有多少個點等待加入
*computeBounds 計算邊界 計算Path的路勁
*reset,rewind 重置路勁 清除Path中的內容(reset相當於new Path , rewind 會保留Path的數據結構)
*transform 矩陣操作 矩陣變換
*/
public class MyView2 extends View{
private Paint path_paint;//路徑繪制
private Paint paint; //網格繪圖
private Context mcontext;
private int width2,height2;
public MyView2(Context context) {
super(context);
this.mcontext =context;
WindowManager manager = (WindowManager) mcontext.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
width2 = outMetrics.widthPixels;
height2 = outMetrics.heightPixels;
path_paint = new Paint();
path_paint.setAntiAlias(true);
path_paint.setStyle(Paint.Style.FILL_AND_STROKE);
path_paint.setStrokeWidth(10);
path_paint.setColor(Color.parseColor("#FF0000"));
//paint.setStyle(Paint.Style.FILL);,設置畫筆為實心。一些線條將在畫布上看不見。
paint = new Paint();
paint.setColor(Color.parseColor("#A8A8A8"));
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(1);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#F5FFFA"));//畫布的背景
//網格線的繪制
final int width = width2;
final int height = height2;
final int space = 100; //長寬間隔
int vertz = 0;
int hortz = 0;
for(int i=0;i<100;i++){
canvas.drawLine(0, vertz, width, vertz, paint);
canvas.drawLine(hortz, 0, hortz, height, paint);
vertz+=space;
hortz+=space;
}
Path path = new Path();
//1.lineTo 連接直線 連接上一個點到當前點之間的直線
//path.lineTo(200,200);
//path.lineTo(400, 0);
//2.方法名 作用 是否影響之前的操作 是否影響之後的操作
//moveTo 移動下一次操作的起點位置 否 是
//setLastPoint 改變上一次操作點的位置 是 是
//當我們繪制線條之前,調用moveTo 和 setLastPoint效果是一樣的,
//都是對坐標原點(0,0)進行操作。setLastPoint是重置上一次操作的最後一點
//path.lineTo(200, 200);
//path.moveTo(300,300);
//path.lineTo(400, 0);
//path.lineTo(200, 200);
//path.setLastPoint(300,100);
//path.lineTo(400, 0);
//3.close方法連接最後一個點和最初一個點(如果兩個點不重合)形成一個閉合的圖形。
//close的作用的封閉路徑,如果連接最後一個點和最初一個點任然無法形成閉合的區域,那麼close什麼也不做。
//path.moveTo(100,100);
//path.lineTo(500,100);
//path.lineTo(300,400);
//path.close();
//4.二次貝塞爾曲線
//public void quadTo(float x1, float y1, float x2, float y2)
//path.moveTo(100, 400);
//path.quadTo(300, 100, 400, 400);
//5.三次貝塞爾曲線
//public void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)
//cubicTo方法比quadTo方法多了一個點坐標,那麼其中(x1,y1) 為控制點,(x2,y2)為控制點,(x3,y3) 為結束點。
//path.moveTo(100, 400);
//path.cubicTo(100, 400, 300, 100, 400, 400);
//6.1Path中添加基本圖形以及區分addArc和arcTo
//圓形
//addCircle(float x, float y, float radius, Path.Direction dir)
//橢圓
//addOval(RectF oval, Path.Direction dir)
//addOval(float left, float top, float right, float bottom, Path.Direction dir)
//矩形
//addRect(RectF rect, Path.Direction dir)
//addRect(float left, float top, float right, float bottom, Path.Direction dir)
//圓角矩形
//addRoundRect(RectF rect, float rx, float ry, Path.Direction dir)
//addRoundRect(float left, float top, float right, float bottom, float rx, float ry, Path.Direction dir)
//addRoundRect(RectF rect, float[] radii, Path.Direction dir)
//addRoundRect(float left, float top, float right, float bottom, float[] radii, Path.Direction dir)
//Direction的意思是方向,指導,趨勢。點進去跟一下你會發現Direction是一個枚舉類型(Enum)
// 分別有CW(順時針),CCW(逆時針)兩個常量。那麼它的作用主要有以下兩點:
//1:在添加圖形時確定閉合順序(各個點的記錄順序)
//:對自相交圖形的渲染結果有影響
//閉合的問題,相交問題與設置填充模式有關。
//path.addRect(100, 200, 500, 400, Path.Direction.CCW);
//path.setLastPoint(400,300);
//path.addCircle(300,300,200, Path.Direction.CW);
//6.2addPath路徑合並
//addPath方法就是將兩個路徑合並到一起。
//第二個方法的dx,dy指的是偏移量,第三個方法是添加到當前path之前先使用Matrix進行變換
//public void addPath(Path src)
//public void addPath(Path src, float dx, float dy)
//public void addPath(Path src, Matrix matrix)
//path.addRect(100,100,400,300, Path.Direction.CW);
//Path src=new Path();
//src.addCircle(300,300,100, Path.Direction.CW);
//path.addPath(src,0,100);
//6.3addArc與arcTo
//addArc(RectF oval, float startAngle, float sweepAngle)
//addArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle)
//arcTo(RectF oval, float startAngle, float sweepAngle)
//arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
//arcTo(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)
//區別
//名稱 作用 區別
//addArc 添加一個圓弧到Path 直接添加一個圓弧到path中,和上一次操作點無關
//arcTo 添加一個圓弧到Path 添加一個圓弧到path中,如果圓弧的起點和上次操作點坐標不同就連接兩個點
//startAngle表示開始圓弧度數(0度與X軸方向對齊,順時針移動,弧度增大)。
//注意:sweepAngle表示運動了多少弧度,並不是結束弧度。
//forceMoveTo表示“是否強制使用moveTo”,也就是說是否使用moveTo將上一次操作點移動到圓弧的起點坐標。
// 默認是false。
//true 將最後一個點移動到圓弧起點,即不連接最後一個點與圓弧起點
//false 不移動,而是連接最後一個點與圓弧起點(注意之前沒有操作的話,不會連接原點)
//path.lineTo(200, 200);
//RectF rectF = new RectF(100, 100, 400, 400);
//path.arcTo(rectF, 0, 270, true);
// path.addArc(rectF,0,270);和上面一句等價
//path.arcTo(rectF, 0, 270, false);
//6.4 isEmpty、 isRect、 set 和 offset
//6.4.1 isEmpty判斷path中是否包含內容。path.isEmpty()
//Log.e("-----", "----" + path.isEmpty());//-----: ----true
//path.lineTo(100,100);
//Log.e("-----","----"+path.isEmpty());//-----: ----false
//6.4.2 isRect 判斷path是否是一個矩形,如果是一個矩形的話,
// 會將矩形的信息存放進參數rect中。isRect(RectF rect)
//RectF rectF = new RectF();
//rectF.left = 100;
//rectF.top = 100;
//rectF.right = 400;
//rectF.bottom = 300;
//path.addRect(rectF, Path.Direction.CW);
//boolean isRect = path.isRect(rectF);
//Log.e("-----", "------" + isRect);//-----: ------true
//6.4.3 set public void set(Path src)將新的path賦值到現有path。
// 相當於運算符中的“=”,如a=b,把b賦值給a
//path.addRect(100,100,400,300, Path.Direction.CW);
//Path src=new Path();
//src.addCircle(300,200,100, Path.Direction.CW);
//path.set(src);
//6.4.4 offset平移
//public void offset(float dx, float dy)
//public void offset(float dx, float dy, Path dst)
//這個方法就是對Path進行一段平移,正方向和X軸,Y軸方向一致(如果dx為正數則向右平移,
//反之向左平移;如果dy為正則向下平移,反之向上平移)。我們看到第二個方法多了一個dst,
//這個又是一個什麼玩意呢,其實參數das是存儲平移後的path的。
//先看兩個參數的
//path.addCircle(300, 200, 100, Path.Direction.CW);
//path.offset(-100, 100);
//再看三個參數的
//從運行效果圖可以看出,雖然我們在dst中添加了一個圓形,但是並沒有表現出來,
//所以,當dst中存在內容時,dst中原有的內容會被清空,而存放平移後的path。
//也就是說dst=path;即dst.set(path)哎 然並卵的東西
//path.addCircle(300, 200, 100, Path.Direction.CW);
//Path dst = new Path();
//dst.addCircle(500, 200, 200, Path.Direction.CW);
//path.offset(-100, 100, dst);
//7 FillType 對兩個參數取交集 並集 補集
//public void setFillType(Path.FillType ft)
//public Path.FillType getFillType()
//setFillType方法中的參數Path.FillType為枚舉類型:
//FillType.WINDING 取path所有所在區域 默認值
//FillType.EVEN_ODD 取path所在並不相交區域
//FillType.INVERSE_WINDING 取path所有未占區域
//FillType.INVERSE_EVEN_ODD 取path未占或相交區域
//7.1 WINDING 並集
//path.addCircle(300,200,100, Path.Direction.CW);
//path.addCircle(200,200,100, Path.Direction.CW);
//path.setFillType(Path.FillType.WINDING);
//7.2 EVEN_ODD
//path.addCircle(300,200,100, Path.Direction.CW);
//path.addCircle(200,200,100, Path.Direction.CW);
//path.setFillType(Path.FillType.EVEN_ODD);
//7.3 INVERSE_WINDING 補集
//path.addCircle(300,200,100, Path.Direction.CW);
//path.addCircle(200,200,100, Path.Direction.CW);
//path.setFillType(Path.FillType.INVERSE_WINDING);
//7.4 INVERSE_EVEN_ODD 並集
path.addCircle(300,200,100, Path.Direction.CW);
path.addCircle(200,200,100, Path.Direction.CW);
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
path.toggleInverseFillType();
canvas.drawPath(path, path_paint);
}
}
3.文字設計
package com.longlian.paintdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
/**文字繪制
* Created by xuenan on 2016/7/15.
*/
/**
*text_paint.setAntiAlias(true); //指定是否使用抗鋸齒功能 如果使用會使繪圖速度變慢 默認false
*text_paint.setStyle(Paint.Style.FILL);//繪圖樣式 對於設文字和幾何圖形都有效
*text_paint.setTextAlign(Paint.Align.LEFT);//設置文字對齊方式 取值:align.CENTER、align.LEFT或align.RIGHT 默認align.LEFT
*text_paint.setTextSize(12);
*text_paint.setStrokeWidth(5);//設置畫筆寬度
*text_paint.setTextSize(80);//設置文字大小
*樣式設置
*text_paint.setFakeBoldText(true);//設置是否為粗體文字
*text_paint.setUnderlineText(true);//設置下劃線
*text_paint.setTextSkewX((float) -0.25);//設置字體水平傾斜度 普通斜體字是-0.25
*text_paint.setStrikeThruText(true);//設置帶有刪除線效果
*其它設置
*text_paint.setTextScaleX(2);//只會將水平方向拉伸 高度不會變
*
**/
public class MyView3 extends View{
private Paint text_paint;
private Paint paint; //網格繪圖
private Context mcontext;
private int width2,height2;
public MyView3(Context context) {
super(context);
this.mcontext =context;
WindowManager manager = (WindowManager) mcontext.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
width2 = outMetrics.widthPixels;
height2 = outMetrics.heightPixels;
text_paint = new Paint();
text_paint.setStrokeWidth(3);
text_paint.setTextSize(50);
text_paint.setColor(Color.RED);
paint = new Paint();
paint.setColor(Color.parseColor("#A8A8A8"));
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(1);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.parseColor("#F5FFFA"));//畫布的背景
//網格線的繪制
final int width = width2;
final int height = height2;
final int space = 100; //長寬間隔
int vertz = 0;
int hortz = 0;
for(int i=0;i<100;i++){
canvas.drawLine(0, vertz, width, vertz, paint);
canvas.drawLine(hortz, 0, hortz, height, paint);
vertz+=space;
hortz+=space;
}
//1、文本繪圖樣式
//設置繪圖樣式 為填充
//text_paint.setStyle(Paint.Style.FILL);
//canvas.drawText("我是一顆小小的石頭", 100, 100, text_paint);
//設置繪圖樣式 為描邊
//text_paint.setStyle(Paint.Style.STROKE);
//canvas.drawText("我是一顆小小的石頭", 100, 300, text_paint);
//設置繪圖樣式 為填充且描邊
//text_paint.setStyle(Paint.Style.FILL_AND_STROKE);
//canvas.drawText("我是一顆小小的石頭", 100,500, text_paint);
//2、setTextAlign(Paint.Align align) 文字的對齊方式
//text_paint.setStyle(Paint.Style.FILL);
//設置對齊方式 左對齊
//text_paint.setTextAlign(Paint.Align.LEFT);
//canvas.drawText("小小的石頭", 500,100, text_paint);//點(500,100)在文本的左邊
//設置對齊方式 中間對齊
//text_paint.setTextAlign(Paint.Align.CENTER);
//canvas.drawText("小小的石頭", 500, 200, text_paint);//點(500,100)在文本的中間
//設置對齊方式 右對齊
//text_paint.setTextAlign(Paint.Align.RIGHT);
//canvas.drawText("小小的石頭", 500,300, text_paint);//點(500,100)在文本的右邊
//3、文字樣式設置
//text_paint.setStyle(Paint.Style.FILL);
//text_paint.setFakeBoldText(true);//是否粗體文字
//text_paint.setUnderlineText(true);//設置下劃線
//text_paint.setStrikeThruText(true);//設置刪除線效果
//canvas.drawText("小小的石頭", 200, 200, text_paint);
//4、文字傾斜度設置
//可見普通斜體字是-0.25f,大於-0.25f 向左傾斜,小於 -0.25f 向右傾斜。
//text_paint.setStyle(Paint.Style.FILL);
//text_paint.setTextSkewX(-0.25f);
//canvas.drawText("小小的石頭", 100, 100, text_paint);
//text_paint.setTextSkewX(0.25f);
//canvas.drawText("小小的石頭", 100, 200, text_paint);
//text_paint.setTextSkewX(-0.5f);
//canvas.drawText("小小的石頭", 100, 300, text_paint);
//5、水平拉伸設置 僅是水平方向拉伸,高度並未改變。
//text_paint.setStyle(Paint.Style.FILL);
//text_paint.setTextScaleX(1);//不拉伸
//canvas.drawText("小小的石頭", 100, 100, text_paint);
//text_paint.setTextScaleX(2);//水平方向拉伸2倍
//canvas.drawText("小小的石頭", 100, 200, text_paint);
//text_paint.setTextScaleX(3);//水平方向拉伸3倍
//canvas.drawText("小小的石頭", 100, 300, text_paint);
//6.canvas繪制文字
//6.1、drawText
//drawText(String text, float x, float y, Paint paint)
//drawText(char[] text, int index, int count, float x, float y, Paint paint)
//drawText(CharSequence text, int start, int end, float x, float y, Paint paint)
//下邊兩個方法要求sdk>=23
//drawTextRun(char[] text, int index, int count, int contextIndex,
//int contextCount, float x, float y, boolean isRtl, Paint paint)
//drawTextRun(CharSequence text, int start, int end, int contextStart,
//int contextEnd, float x, float y, boolean isRtl, Paint paint)
//第一個構造函數 : 是最普通的。
//第二個構造函數 : text 字節數組;index 表示第一個要繪制的文字索引;count 需要繪制的文字個數。
//第三個構造函數 : text 表示字符 (注意與上面比較);start 開始截取字符的索引號;
//end 結束截取字符的索引號。(注意和上面的區別) [start , end ) 包含 start 但不包含 end
//第四個構造函數和第五個構造函數 : contextIndex 和 index 相同 ;
//contextCount 大於等於 count ; isRtl 表示排列順序,
//true 表示正序,false 表示倒序(這裡的倒是指第一個字符變到最後一個字符,
//最後一個字符變到第一個字符)。 注意了drawTextRun方法是在 skd23 才引入的方法。
//text_paint.setStyle(Paint.Style.FILL);
//canvas.drawText("我是一顆小小的石頭".toCharArray(), 1, 4, 100, 100, text_paint);
//canvas.drawText("我是一顆小小的石頭", 1, 4, 100, 200, text_paint);
//最小sdk23
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//倒序
// canvas.drawTextRun("我是一顆小小的石頭".toCharArray(), 1, 4, 1, 4, 100, 400, false, text_paint);
//正序
// canvas.drawTextRun("我是一顆小小的石頭".toCharArray(), 1, 4, 1, 4, 100, 300, true, text_paint);
// }
//6.2、drawPosText
//drawPosText(String text, float[] pos, Paint paint)
//drawPosText(char[] text, int index, int count, float[] pos, Paint paint)
//float[] pos = {100, 100, 200, 200, 300, 300, 400, 400, 500, 500, 600, 600};
//canvas.drawPosText("我是一顆小小", pos, text_paint);
//6.3、drawTextOnPath
//drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
//drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint)
//index,count : 和上面截取參數含義一樣,這裡不再累訴。
//hOffset : 與路徑起點的水平偏移量 ,正數向 X 軸正方向移動(右移);負數向 X 軸負方向移動(左移)
//如果是圓弧:正數是順時針的偏移量;反之是逆時針的偏移量
//vOffset : 與路徑中心的垂直偏移量,正數向 Y 軸正方向移動(下移);負數向Y 軸負方向移動(上移)
//如果是圓弧正數向 Y 軸負方向移動(上移);負數向Y 軸正方向移動(下移)
//Path mPath = new Path();
//Paint mpaint = new Paint();
//mpaint.setStrokeWidth(5);
//mpaint.setTextSize(80);
//mpaint.setColor(Color.GREEN);
//mpaint.setStyle(Paint.Style.STROKE);
//6.3.1
//mPath.moveTo(100, 100);
//mPath.lineTo(800, 100);
//canvas.drawPath(mPath, mpaint);
//canvas.drawTextOnPath("我是一顆小小的石頭", mPath,10, 100, text_paint);
//6.3.2
//mPath.addCircle(500, 500, 200, Path.Direction.CW);
//canvas.drawPath(mPath, mpaint);
//canvas.drawTextOnPath("我是一顆小小的石頭", mPath, 40,20, text_paint);
//6.4、Typeface(字體樣式設置)
//setTypeface(Typeface typeface)
//參數類型是枚舉類型,枚舉值如下:
//Typeface.NORMAL //正常體
//Typeface.BOLD //粗體
//Typeface.ITALIC //斜體
//Typeface.BOLD_ITALIC //粗斜體
//Typeface是用來設置字體樣式的,通過paint.setTypeface()來指定。
//可以指定系統中的字體樣式,也可以指定自定義的樣式文件中獲取。
//要構建Typeface時,可以指定所用樣式的正常體、斜體、粗體等,如果指定樣式中,
//沒有相關文字的樣式就會用系統默認的樣式來顯示,一般默認是宋體。
//Typeface typeface;
//typeface = Typeface.create("宋體", Typeface.NORMAL);
//text_paint.setTypeface(typeface);
//canvas.drawText("我是一顆小小的石頭", 100, 100, text_paint);
//設置楷體根本沒起作用,在系統的字體當中沒有找到楷體。
//typeface = Typeface.create("楷體", Typeface.NORMAL);
//mPaint.setTypeface(typeface);
//canvas.drawText("我是一顆小小的石頭", 100, 200, mPaint);
//----------------------------------------------------------
//自定義字體
//createFromAsset(AssetManager mgr, String path) //Asset中獲取
//createFromFile(File path) //文件路徑獲取
//createFromFile(String path) //外部路徑獲取
//首先在main下創建assets文件夾,然後在assets文件夾創建fonts文件夾,
//最後在fonts文件夾下放入font1.ttf
Typeface typeface;
typeface = Typeface.createFromAsset(mcontext.getAssets(), "fonts/font1.ttf");
//Typeface.createFromFile(mContext.getFilesDir()+"/font1.ttf")
text_paint.setTypeface(typeface);
canvas.drawText("我是一顆小小的石頭", 100, 100, text_paint);
typeface = Typeface.createFromAsset(mcontext.getAssets(), "fonts/font2.ttf");
text_paint.setTypeface(typeface);
canvas.drawText("我是一顆小小的石頭", 100, 200, text_paint);
}
}
先寫到這裡 周末了 下周再寫
問題說明:其實這個問題有可能是沒有問題需要多試幾次 解決辦法:重新用手機連接電腦,並且重新打開USB調試模式(部分ROM默認打開的,如果找不到),再次自動
RecyclerView 水平多行排列添加頭和尾import android.content.Context;import android.support.v7.widg
本菜開源的一個自己寫的Demo,希望能給Androider們有所幫助,水平有限,見諒見諒.. https://github.com/zhiaixinyang/MyFir
SimpleAdapter,跟名字一樣,一個簡單的適配器,既為簡單,就只是被設計來做簡單的應用的,比如靜態數據的綁定,不過仍然有自定義的空間,比如說在每一個ListIte