Android Canvas 和Paint的用法 转自http://blog.csdn.net/u010947098/article/details/44574171

本文主要是介绍Android Canvas 和Paint的用法 转自http://blog.csdn.net/u010947098/article/details/44574171,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,介绍的是Canvas的基本方法

方法签名简要说明
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)绘制弧
drawBitmap(Bitmap bitmap, Rect src, Rect dst,Paint paint)在指定点绘制从源位图中"挖取"的一块
drawBitmap(Bitmap bitmap, float left, flost top, Paint paint)在指定点绘制位图
drawCircle(float cx, float cy, float radius, Paint paint)在指定点绘制一个圆形
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)绘制一条线
drawLines(float[] pts, int offset, int count, Paint paint)绘制多条线
drawOval(RectF oval, Paint paint)绘制椭圆
drawPath(Path path, Paint paint)沿着指定Path绘制任意形状
drawPoint(float x, float y, Paint paint)绘制一个点
drawPoints(float[] pts, int offset, int count, Paint paint)绘制多个点
drawRect(float left, float top, float right, float bottom, Paint paint)绘制矩形
drawRoundRect(RectF rect, float rx, float ry, Paint paint)绘制圆角矩形
drawText(String text, int start ,int end, Paint paint)绘制字符串
drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)沿着路径绘制字符串
clipRect(float left, float top, float right, float bottom)剪切一个矩形区域
clipRegion(Region region)剪切指定区域
除了上面所定义的各种方法之外,Canvas还提供了如下方法进行左边变换.

>rotate(float degress, float px, float py): 对Canvas执行旋转变换.

>scale(float sx, float sy, float px, float py): 对Canvas执行缩放变换.

>skew(float sx, float sy): 对Canvas执行倾斜变换.

>translate(float dx, float dy): 移动Canvas.向右移动dx距离(dx为负数即向左移动);向下移动dy距离(dy为负数即向上移动).



Paint代表了Canvas上的画笔,因此Paint类主要用于设置绘制风格,包括画笔颜色.画笔笔触粗细,填充风格等.

Paint提供了如下所示的方法:

方法签名简要说明
setARGB(int a, int r, int g, int b)/setColor(int color)设置颜色
setAlpha(int a )设置透明度
setAntiAlias(boolean aa)设置是否抗锯齿
setColor(int color)设置颜色
setPahtEffect(PathEffect cffect)设置绘制路径时的路径效果
setShader(Shader shader)设置画笔的填充效果
setShadowLayer(float radius, float dx, float dy, int color)设置阴影
setStrokeWidth(float width)设置画笔的笔触宽度
setStrokeJoin(Paint.Join join)设置画笔转弯处的连接风格
setStyle(Paint.Style style)设置Paint的填充风格
setTextAlign(Paint.Align align)设置绘制文本时的文字的对齐方式
setTextSize(float textSize)设置绘制文本时的文字大小
在Canvas提供的绘制方法中还用到了一个API:Path,Path代表任意多条直线连接而成的任意图形,当Canvas根据Path绘制时,它可以绘制出任意的形状.

下面的MyView重写了onDraw(Canvas)方法,绘制了基本的几何图形.

[java] view plain copy
print ?
  1. package com.example.canvastest.view;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.content.Context;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;  
  7. import android.graphics.LinearGradient;  
  8. import android.graphics.Paint;  
  9. import android.graphics.Path;  
  10. import android.graphics.RectF;  
  11. import android.graphics.Shader;  
  12. import android.util.AttributeSet;  
  13. import android.view.View;  
  14.   
  15. public class MyView extends View {  
  16.   
  17.     public MyView(Context context, AttributeSet attrs, int defStyleAttr,  
  18.             int defStyleRes) {  
  19.         super(context, attrs, defStyleAttr, defStyleRes);  
  20.     }  
  21.   
  22.     public MyView(Context context, AttributeSet attrs, int defStyleAttr) {  
  23.         super(context, attrs, defStyleAttr);  
  24.     }  
  25.   
  26.     public MyView(Context context, AttributeSet attrs) {  
  27.         super(context, attrs);  
  28.     }  
  29.   
  30.     public MyView(Context context) {  
  31.         super(context);  
  32.     }  
  33.   
  34.     /** 
  35.      * 重写该方法,进行绘图 
  36.      */  
  37.     @SuppressLint("DrawAllocation")  
  38.     @Override  
  39.     protected void onDraw(Canvas canvas) {  
  40.         super.onDraw(canvas);  
  41.         // 把整张画布绘制成白色  
  42.         canvas.drawColor(Color.WHITE);  
  43.         // 创建画笔  
  44.         Paint paint = new Paint();  
  45.         // 去锯齿  
  46.         paint.setAntiAlias(true);  
  47.         // 设置画笔颜色  
  48.         paint.setColor(Color.BLUE);  
  49.         // 设置画笔样式  
  50.         paint.setStyle(Paint.Style.STROKE);  
  51.         // 设置画笔的宽度  
  52.         paint.setStrokeWidth(3);  
  53.         // 绘制圆形  
  54.         canvas.drawCircle(404030, paint);  
  55.         // 绘制正方形  
  56.         canvas.drawRect(108070140, paint);  
  57.         // 绘制矩形  
  58.         canvas.drawRect(1015070190, paint);  
  59.         //  
  60.         RectF rectF1 = new RectF(1020070230);  
  61.         // 绘制圆角矩形  
  62.         canvas.drawRoundRect(rectF1, 1515, paint);  
  63.         //  
  64.         RectF rectF2 = new RectF(1024070270);  
  65.         // 绘制椭圆  
  66.         canvas.drawOval(rectF2, paint);  
  67.   
  68.         // 定义一个Path对象,封闭成一个三角形  
  69.         Path path1 = new Path();  
  70.         // 设置起点  
  71.         path1.moveTo(10340);  
  72.         // 线路1  
  73.         path1.lineTo(70340);  
  74.         // 线路2  
  75.         path1.lineTo(40290);  
  76.         path1.close();  
  77.         // 根据Path进行绘制,绘制三角形  
  78.         canvas.drawPath(path1, paint);  
  79.         // 定义一个Path对象,绘制一个五角形  
  80.         Path path2 = new Path();  
  81.         path2.moveTo(26360);  
  82.         path2.lineTo(54360);  
  83.         path2.lineTo(70392);  
  84.         path2.lineTo(40420);  
  85.         path2.lineTo(10392);  
  86.         path2.close();  
  87.         // 根据Path进行绘制,绘制三角形  
  88.         canvas.drawPath(path2, paint);  
  89.   
  90.         // -------------设置填充风格后绘制---------------------------  
  91.         paint.setStyle(Paint.Style.FILL);  
  92.         paint.setColor(Color.RED);  
  93.         // 绘制圆形  
  94.         canvas.drawCircle(1204030, paint);  
  95.         // 绘制正方形  
  96.         canvas.drawRect(9080150140, paint);  
  97.         // 绘制矩形  
  98.         canvas.drawRect(90200150190, paint);  
  99.         // 绘制圆角矩形  
  100.         RectF rectF3 = new RectF(90200150230);  
  101.         canvas.drawRoundRect(rectF3, 1515, paint);  
  102.         // 绘制椭圆  
  103.         RectF rectF4 = new RectF(90240150270);  
  104.         canvas.drawOval(rectF4, paint);  
  105.         // 绘制三角形  
  106.         Path path3 = new Path();  
  107.         path3.moveTo(90340);  
  108.         path3.lineTo(150340);  
  109.         path3.lineTo(120290);  
  110.         path3.close();  
  111.         canvas.drawPath(path3, paint);  
  112.         // 绘制五角形  
  113.         Path path4 = new Path();  
  114.         path4.moveTo(106360);  
  115.         path4.lineTo(134360);  
  116.         path4.lineTo(150392);  
  117.         path4.lineTo(120420);  
  118.         path4.lineTo(90392);  
  119.         path4.close();  
  120.         canvas.drawPath(path4, paint);  
  121.   
  122.         // -------------设置渐变器后绘制------------------  
  123.         // 为paint设置渐变器  
  124.         Shader mShader = new LinearGradient(004060new int[] {  
  125.                 Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW }, null,  
  126.                 Shader.TileMode.REPEAT);  
  127.         paint.setShader(mShader);  
  128.         //设置阴影  
  129.         paint.setShadowLayer(451010, Color.GRAY);  
  130.         // 绘制圆形  
  131.         canvas.drawCircle(2004030, paint);  
  132.         // 绘制正方形  
  133.         canvas.drawRect(17080230140, paint);  
  134.         // 绘制矩形  
  135.         canvas.drawRect(170150230190, paint);  
  136.         // 绘制圆角矩形  
  137.         RectF rectF5 = new RectF(170200230230);  
  138.         canvas.drawRoundRect(rectF5, 1515, paint);  
  139.         // 绘制椭圆  
  140.         RectF rectF6 = new RectF(170240230270);  
  141.         canvas.drawOval(rectF6, paint);  
  142.         // 绘制三角形  
  143.         Path path6 = new Path();  
  144.         path6.moveTo(170340);  
  145.         path6.lineTo(230340);  
  146.         path6.lineTo(200290);  
  147.         path6.close();  
  148.         canvas.drawPath(path6, paint);  
  149.         // 绘制五角形  
  150.         Path path5 = new Path();  
  151.         path5.moveTo(186360);  
  152.         path5.lineTo(214360);  
  153.         path5.lineTo(230392);  
  154.         path5.lineTo(200420);  
  155.         path5.lineTo(170392);  
  156.         path5.close();  
  157.         canvas.drawPath(path5, paint);  
  158.           
  159.         //----------设置字符大小后绘制-----------------  
  160.         paint.setTextSize(24);  
  161.         paint.setShader(null);  
  162.         //绘制7个字符串  
  163.         canvas.drawText("圆形"24050, paint);  
  164.         canvas.drawText("正方形"240120, paint);  
  165.         canvas.drawText("矩形"240175, paint);  
  166.         canvas.drawText("圆角矩形"240220, paint);  
  167.         canvas.drawText("椭圆形"240260, paint);  
  168.         canvas.drawText("三角形"240325, paint);  
  169.         canvas.drawText("五角形"240390, paint);  
  170.     }  
  171.   
  172. }  
package com.example.canvastest.view;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;public class MyView extends View {public MyView(Context context, AttributeSet attrs, int defStyleAttr,int defStyleRes) {super(context, attrs, defStyleAttr, defStyleRes);}public MyView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public MyView(Context context, AttributeSet attrs) {super(context, attrs);}public MyView(Context context) {super(context);}/*** 重写该方法,进行绘图*/@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 把整张画布绘制成白色canvas.drawColor(Color.WHITE);// 创建画笔Paint paint = new Paint();// 去锯齿paint.setAntiAlias(true);// 设置画笔颜色paint.setColor(Color.BLUE);// 设置画笔样式paint.setStyle(Paint.Style.STROKE);// 设置画笔的宽度paint.setStrokeWidth(3);// 绘制圆形canvas.drawCircle(40, 40, 30, paint);// 绘制正方形canvas.drawRect(10, 80, 70, 140, paint);// 绘制矩形canvas.drawRect(10, 150, 70, 190, paint);//RectF rectF1 = new RectF(10, 200, 70, 230);// 绘制圆角矩形canvas.drawRoundRect(rectF1, 15, 15, paint);//RectF rectF2 = new RectF(10, 240, 70, 270);// 绘制椭圆canvas.drawOval(rectF2, paint);// 定义一个Path对象,封闭成一个三角形Path path1 = new Path();// 设置起点path1.moveTo(10, 340);// 线路1path1.lineTo(70, 340);// 线路2path1.lineTo(40, 290);path1.close();// 根据Path进行绘制,绘制三角形canvas.drawPath(path1, paint);// 定义一个Path对象,绘制一个五角形Path path2 = new Path();path2.moveTo(26, 360);path2.lineTo(54, 360);path2.lineTo(70, 392);path2.lineTo(40, 420);path2.lineTo(10, 392);path2.close();// 根据Path进行绘制,绘制三角形canvas.drawPath(path2, paint);// -------------设置填充风格后绘制---------------------------paint.setStyle(Paint.Style.FILL);paint.setColor(Color.RED);// 绘制圆形canvas.drawCircle(120, 40, 30, paint);// 绘制正方形canvas.drawRect(90, 80, 150, 140, paint);// 绘制矩形canvas.drawRect(90, 200, 150, 190, paint);// 绘制圆角矩形RectF rectF3 = new RectF(90, 200, 150, 230);canvas.drawRoundRect(rectF3, 15, 15, paint);// 绘制椭圆RectF rectF4 = new RectF(90, 240, 150, 270);canvas.drawOval(rectF4, paint);// 绘制三角形Path path3 = new Path();path3.moveTo(90, 340);path3.lineTo(150, 340);path3.lineTo(120, 290);path3.close();canvas.drawPath(path3, paint);// 绘制五角形Path path4 = new Path();path4.moveTo(106, 360);path4.lineTo(134, 360);path4.lineTo(150, 392);path4.lineTo(120, 420);path4.lineTo(90, 392);path4.close();canvas.drawPath(path4, paint);// -------------设置渐变器后绘制------------------// 为paint设置渐变器Shader mShader = new LinearGradient(0, 0, 40, 60, new int[] {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW }, null,Shader.TileMode.REPEAT);paint.setShader(mShader);//设置阴影paint.setShadowLayer(45, 10, 10, Color.GRAY);// 绘制圆形canvas.drawCircle(200, 40, 30, paint);// 绘制正方形canvas.drawRect(170, 80, 230, 140, paint);// 绘制矩形canvas.drawRect(170, 150, 230, 190, paint);// 绘制圆角矩形RectF rectF5 = new RectF(170, 200, 230, 230);canvas.drawRoundRect(rectF5, 15, 15, paint);// 绘制椭圆RectF rectF6 = new RectF(170, 240, 230, 270);canvas.drawOval(rectF6, paint);// 绘制三角形Path path6 = new Path();path6.moveTo(170, 340);path6.lineTo(230, 340);path6.lineTo(200, 290);path6.close();canvas.drawPath(path6, paint);// 绘制五角形Path path5 = new Path();path5.moveTo(186, 360);path5.lineTo(214, 360);path5.lineTo(230, 392);path5.lineTo(200, 420);path5.lineTo(170, 392);path5.close();canvas.drawPath(path5, paint);//----------设置字符大小后绘制-----------------paint.setTextSize(24);paint.setShader(null);//绘制7个字符串canvas.drawText("圆形", 240, 50, paint);canvas.drawText("正方形", 240, 120, paint);canvas.drawText("矩形", 240, 175, paint);canvas.drawText("圆角矩形", 240, 220, paint);canvas.drawText("椭圆形", 240, 260, paint);canvas.drawText("三角形", 240, 325, paint);canvas.drawText("五角形", 240, 390, paint);}}

Path类: Android提供的Path是一个非常有用的类,它可以预先在View上将N个点连成一条"路径",然后调用Canvas的drawPath(Path path, Paint paint)即可沿着路径绘制图形.实际上Android还为路径绘制提供了PathEffect来定义绘制效果,PathEffect包含了如下子类(每个子类代表一种绘制效果):

Corner PathEffect
Discrete PathEffect
Dash PathEffect
Path Dash PathEffect
Compose PathEffect
Sum PathEffect

这些绘制效果使用语言来表述总显得有些空洞,下面通过一个程序来了解一下绘制效果.接下来的程序绘制7条路径,分别示范了不适用效果和使用上面6种效果的示意.

[java] view plain copy
print ?
  1. package com.example.canvastest.view;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.ComposePathEffect;  
  7. import android.graphics.CornerPathEffect;  
  8. import android.graphics.DashPathEffect;  
  9. import android.graphics.DiscretePathEffect;  
  10. import android.graphics.Paint;  
  11. import android.graphics.Path;  
  12. import android.graphics.PathDashPathEffect;  
  13. import android.graphics.PathEffect;  
  14. import android.graphics.SumPathEffect;  
  15. import android.util.AttributeSet;  
  16. import android.view.View;  
  17.   
  18. /** 
  19.  * 使用Path绘制路径 
  20.  * @author Administrator 
  21.  * 
  22.  */  
  23. public class MyPathView extends View {  
  24.     private float phase;  
  25.     private PathEffect[] pathEffects = new PathEffect[7];  
  26.     private int[] colors;  
  27.     private Path path;  
  28.     private Paint paint;  
  29.   
  30.     public MyPathView(Context context) {  
  31.         this(context, null);  
  32.     }  
  33.   
  34.     public MyPathView(Context context, AttributeSet attrs) {  
  35.         this(context, attrs, 0);  
  36.     }  
  37.   
  38.     public MyPathView(Context context, AttributeSet attrs, int defStyleAttr) {  
  39.         super(context, attrs, defStyleAttr);  
  40.         paint = new Paint();  
  41.         paint.setStyle(Paint.Style.STROKE);  
  42.         paint.setStrokeWidth(4);  
  43.   
  44.         // 创建并初始化Path  
  45.         path = new Path();  
  46.         path.moveTo(00);  
  47.         for (int i = 0; i < 15; i++) {  
  48.             // 生成15个点,随机生成他们的Y坐标,并将它们练成一条Path  
  49.             path.lineTo(i * 20, (float) Math.random() * 60);  
  50.         }  
  51.         // 初始化7个颜色  
  52.         colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN,  
  53.                 Color.MAGENTA, Color.RED, Color.YELLOW };  
  54.     }  
  55.   
  56.       
  57.     @Override  
  58.     protected void onDraw(Canvas canvas) {  
  59.         super.onDraw(canvas);  
  60.         ///将背景填充为白色  
  61.         canvas.drawColor(Color.WHITE);  
  62.         //-------下面开始初始化7种路径效果--------  
  63.         //不使用路径效果  
  64.         pathEffects[0] = null;  
  65.         //使用CornerPathEffect路径效果//角路径效应  
  66.         pathEffects[1] = new CornerPathEffect(10);  
  67.         //使用DiscretePathEffect路径效果//离散路径效应  
  68.         pathEffects[2] = new DiscretePathEffect(3.0f, 5.0f);  
  69.         //DashPathEffect//短跑路径效应  
  70.         pathEffects[3] = new DashPathEffect(new float[]{2010510}, phase);  
  71.         //PathDashPathEffect//短跑的路径路径效应  
  72.         Path p = new Path();  
  73.         p.addRect(0088, Path.Direction.CCW);  
  74.         pathEffects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE);  
  75.         //ComposePathEffect//组成的路径效应  
  76.         pathEffects[5] = new ComposePathEffect(pathEffects[2], pathEffects[4]);  
  77.         //SumPathEffect//总和路径效应  
  78.         pathEffects[6] = new SumPathEffect(pathEffects[4], pathEffects[3]);  
  79.           
  80.         //将画布移动到(8,8)出绘制  
  81.         canvas.translate(88);  
  82.         //依次使用7种不同路径效果,7种颜色来绘制路径  
  83.         for (int i = 0; i < pathEffects.length; i++) {  
  84.             paint.setPathEffect(pathEffects[i]);  
  85.             paint.setColor(colors[i]);  
  86.             canvas.drawPath(path, paint);  
  87.             canvas.translate(060);  
  88.         }  
  89.         //改变phase值,形成动画效果  
  90.         phase += 1;  
  91.         invalidate();  
  92.     }  
  93.   
  94. }  
package com.example.canvastest.view;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposePathEffect;
import android.graphics.CornerPathEffect;
import android.graphics.DashPathEffect;
import android.graphics.DiscretePathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathDashPathEffect;
import android.graphics.PathEffect;
import android.graphics.SumPathEffect;
import android.util.AttributeSet;
import android.view.View;/*** 使用Path绘制路径* @author Administrator**/
public class MyPathView extends View {private float phase;private PathEffect[] pathEffects = new PathEffect[7];private int[] colors;private Path path;private Paint paint;public MyPathView(Context context) {this(context, null);}public MyPathView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyPathView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(4);// 创建并初始化Pathpath = new Path();path.moveTo(0, 0);for (int i = 0; i < 15; i++) {// 生成15个点,随机生成他们的Y坐标,并将它们练成一条Pathpath.lineTo(i * 20, (float) Math.random() * 60);}// 初始化7个颜色colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN,Color.MAGENTA, Color.RED, Color.YELLOW };}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);///将背景填充为白色canvas.drawColor(Color.WHITE);//-------下面开始初始化7种路径效果--------//不使用路径效果pathEffects[0] = null;//使用CornerPathEffect路径效果//角路径效应pathEffects[1] = new CornerPathEffect(10);//使用DiscretePathEffect路径效果//离散路径效应pathEffects[2] = new DiscretePathEffect(3.0f, 5.0f);//DashPathEffect//短跑路径效应pathEffects[3] = new DashPathEffect(new float[]{20, 10, 5, 10}, phase);//PathDashPathEffect//短跑的路径路径效应Path p = new Path();p.addRect(0, 0, 8, 8, Path.Direction.CCW);pathEffects[4] = new PathDashPathEffect(p, 12, phase, PathDashPathEffect.Style.ROTATE);//ComposePathEffect//组成的路径效应pathEffects[5] = new ComposePathEffect(pathEffects[2], pathEffects[4]);//SumPathEffect//总和路径效应pathEffects[6] = new SumPathEffect(pathEffects[4], pathEffects[3]);//将画布移动到(8,8)出绘制canvas.translate(8, 8);//依次使用7种不同路径效果,7种颜色来绘制路径for (int i = 0; i < pathEffects.length; i++) {paint.setPathEffect(pathEffects[i]);paint.setColor(colors[i]);canvas.drawPath(path, paint);canvas.translate(0, 60);}//改变phase值,形成动画效果phase += 1;invalidate();}}

除此之外,Android的Canvas还提供了一个DrawTextOnPath(String text,Path path, float hOffset, float vOffset, Paint paint)方法,该方法可以沿着Path绘制文本,其中hOffset参数指定水平偏移,vOffset参数指定垂直偏移.

[java] view plain copy
print ?
  1. package com.example.canvastest.view;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.graphics.Paint.Align;  
  8. import android.graphics.Path;  
  9. import android.graphics.RectF;  
  10. import android.util.AttributeSet;  
  11. import android.view.View;  
  12.   
  13. /** 
  14.  * 使用drawTextOnPaht,沿着Path(路径)绘制文本 
  15.  *  
  16.  * @author Administrator 
  17.  */  
  18. public class MyPathTextView extends View {  
  19.     final String DRAW_STR = "绘制文本";  
  20.     private Path[] paths = new Path[3];  
  21.     Paint paint;  
  22.   
  23.     public MyPathTextView(Context context) {  
  24.         this(context, null);  
  25.     }  
  26.   
  27.     public MyPathTextView(Context context, AttributeSet attrs) {  
  28.         this(context, attrs, 0);  
  29.     }  
  30.   
  31.     public MyPathTextView(Context context, AttributeSet attrs, int defStyleAttr) {  
  32.         super(context, attrs, defStyleAttr);  
  33.         paths[0] = new Path();  
  34.         paths[0].moveTo(00);  
  35.         for (int i = 0; i < 7; i++) {  
  36.             // 生成7个点,随机生成它们的y坐标,并将它们连成一条path  
  37.             paths[0].lineTo(1 * 30, (float) Math.random() * 30);  
  38.         }  
  39.         paths[1] = new Path();  
  40.         RectF rectf = new RectF(00200120);  
  41.         paths[1].addOval(rectf, Path.Direction.CCW);  
  42.         paths[2] = new Path();  
  43.         paths[2].addArc(rectf, 60180);  
  44.         // 初始化画笔  
  45.         paint = new Paint();  
  46.         paint.setAntiAlias(true);  
  47.         paint.setColor(Color.CYAN);  
  48.         paint.setStrokeWidth(1);  
  49.   
  50.     }  
  51.   
  52.     @Override  
  53.     protected void onDraw(Canvas canvas) {  
  54.         super.onDraw(canvas);  
  55.   
  56.         canvas.drawColor(Color.WHITE);  
  57.         canvas.translate(4040);  
  58.         // 设置从右边开始绘制(右对齐)  
  59.         paint.setTextAlign(Paint.Align.RIGHT);  
  60.         paint.setTextSize(20);  
  61.         // 绘制路径  
  62.         paint.setStyle(Paint.Style.STROKE);  
  63.         canvas.drawPath(paths[0], paint);  
  64.         // 沿着路径绘制一段文本  
  65.         paint.setStyle(Paint.Style.FILL);  
  66.         canvas.drawTextOnPath(DRAW_STR, paths[0], -820, paint);  
  67.         // 对canvas进行坐标变换:画布下移60  
  68.         canvas.translate(060);  
  69.         // 绘制路径  
  70.         paint.setStyle(Paint.Style.STROKE);  
  71.         canvas.drawPath(paths[1], paint);  
  72.         // 沿着路径绘制一段文本  
  73.         paint.setStyle(Paint.Style.FILL);  
  74.         canvas.drawTextOnPath(DRAW_STR, paths[1], -2020, paint);  
  75.         // 对canvas进行坐标变换:画布下移120  
  76.         canvas.translate(0120);  
  77.         // 绘制路径  
  78.         paint.setStyle(Paint.Style.STROKE);  
  79.         canvas.drawPath(paths[2], paint);  
  80.         // 沿着路径绘制一段文本  
  81.         paint.setStyle(Paint.Style.FILL);  
  82.         canvas.drawTextOnPath(DRAW_STR, paths[2], -1020, paint);  
  83.     }  
  84.   
  85. }  
package com.example.canvastest.view;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;/*** 使用drawTextOnPaht,沿着Path(路径)绘制文本* * @author Administrator*/
public class MyPathTextView extends View {final String DRAW_STR = "绘制文本";private Path[] paths = new Path[3];Paint paint;public MyPathTextView(Context context) {this(context, null);}public MyPathTextView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public MyPathTextView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);paths[0] = new Path();paths[0].moveTo(0, 0);for (int i = 0; i < 7; i++) {// 生成7个点,随机生成它们的y坐标,并将它们连成一条pathpaths[0].lineTo(1 * 30, (float) Math.random() * 30);}paths[1] = new Path();RectF rectf = new RectF(0, 0, 200, 120);paths[1].addOval(rectf, Path.Direction.CCW);paths[2] = new Path();paths[2].addArc(rectf, 60, 180);// 初始化画笔paint = new Paint();paint.setAntiAlias(true);paint.setColor(Color.CYAN);paint.setStrokeWidth(1);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.WHITE);canvas.translate(40, 40);// 设置从右边开始绘制(右对齐)paint.setTextAlign(Paint.Align.RIGHT);paint.setTextSize(20);// 绘制路径paint.setStyle(Paint.Style.STROKE);canvas.drawPath(paths[0], paint);// 沿着路径绘制一段文本paint.setStyle(Paint.Style.FILL);canvas.drawTextOnPath(DRAW_STR, paths[0], -8, 20, paint);// 对canvas进行坐标变换:画布下移60canvas.translate(0, 60);// 绘制路径paint.setStyle(Paint.Style.STROKE);canvas.drawPath(paths[1], paint);// 沿着路径绘制一段文本paint.setStyle(Paint.Style.FILL);canvas.drawTextOnPath(DRAW_STR, paths[1], -20, 20, paint);// 对canvas进行坐标变换:画布下移120canvas.translate(0, 120);// 绘制路径paint.setStyle(Paint.Style.STROKE);canvas.drawPath(paths[2], paint);// 沿着路径绘制一段文本paint.setStyle(Paint.Style.FILL);canvas.drawTextOnPath(DRAW_STR, paths[2], -10, 20, paint);}}

下面是一个使用双缓冲机制实现的画面板例子

[java] view plain copy
print ?
  1. package com.example.canvastest.view;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Bitmap;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;  
  7. import android.graphics.Paint;  
  8. import android.graphics.Path;  
  9. import android.util.AttributeSet;  
  10. import android.view.MotionEvent;  
  11. import android.view.View;  
  12.   
  13. public class DrawView extends View {  
  14.     float preX;  
  15.     float preY;  
  16.     private Paint paint = null;  
  17.     final int VIEW_WIDTH = 320;  
  18.     final int VIEW_HEIGHT = 480;  
  19.     // 定义一个内存中的图片,该图片将作为缓冲区  
  20.     Bitmap cacheBitmap = null;  
  21.     // 定义cachebitmap上的canvas对象  
  22.     Canvas cacheCanvas = null;  
  23.     Path path = null;  
  24.   
  25.     public DrawView(Context context) {  
  26.         this(context, null);  
  27.     }  
  28.     public DrawView(Context context, AttributeSet attrs) {  
  29.         this(context, attrs, 0);  
  30.     }  
  31.   
  32.     public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {  
  33.         super(context, attrs, defStyleAttr);  
  34.         // 设置画笔的颜色  
  35.         paint = new Paint(Paint.DITHER_FLAG);  
  36.         paint.setColor(Color.RED);  
  37.         // 设置画笔的风格  
  38.         paint.setStyle(Paint.Style.STROKE);  
  39.         paint.setStrokeWidth(1);  
  40.         // 抗锯齿  
  41.         paint.setAntiAlias(true);  
  42.         paint.setDither(true);  
  43.         // 创建一个与该View相同大小的缓冲区  
  44.         cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT,  
  45.                 Bitmap.Config.ARGB_8888);  
  46.         // 设置cacheCanvas将会绘制到内存中的cacheBitmap上  
  47.         cacheCanvas = new Canvas();  
  48.         path = new Path();  
  49.         cacheCanvas.setBitmap(cacheBitmap);  
  50.     }  
  51.   
  52.     @Override  
  53.     public boolean onTouchEvent(MotionEvent event) {  
  54.         float x = event.getX();  
  55.         float y = event.getY();  
  56.   
  57.         switch (event.getAction()) {  
  58.         case MotionEvent.ACTION_DOWN:  
  59.             path.moveTo(x, y);  
  60.             preX = x;  
  61.             preY = x;  
  62.             break;  
  63.         case MotionEvent.ACTION_MOVE:  
  64.             path.quadTo(preX, preY, x, y);  
  65.             preX = x;  
  66.             preY = y;  
  67.             break;  
  68.         case MotionEvent.ACTION_UP:  
  69.             cacheCanvas.drawPath(path, paint);  
  70.             path.reset();  
  71.             break;  
  72.         }  
  73.         invalidate();  
  74.   
  75.         // 返回true表明处理方法已经处理该事件  
  76.         return true;  
  77.     }  
  78.   
  79.     @Override  
  80.     protected void onDraw(Canvas canvas) {  
  81.         super.onDraw(canvas);  
  82.         Paint paint = new Paint();  
  83.         // 将该bitmap绘制到该View组件上  
  84.         canvas.drawBitmap(cacheBitmap, 00, paint);  
  85.         // 沿着path绘制  
  86.         canvas.drawPath(path, paint);  
  87.   
  88.     }  
  89.   
  90. }  
package com.example.canvastest.view;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class DrawView extends View {float preX;float preY;private Paint paint = null;final int VIEW_WIDTH = 320;final int VIEW_HEIGHT = 480;// 定义一个内存中的图片,该图片将作为缓冲区Bitmap cacheBitmap = null;// 定义cachebitmap上的canvas对象Canvas cacheCanvas = null;Path path = null;public DrawView(Context context) {this(context, null);}public DrawView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// 设置画笔的颜色paint = new Paint(Paint.DITHER_FLAG);paint.setColor(Color.RED);// 设置画笔的风格paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(1);// 抗锯齿paint.setAntiAlias(true);paint.setDither(true);// 创建一个与该View相同大小的缓冲区cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT,Bitmap.Config.ARGB_8888);// 设置cacheCanvas将会绘制到内存中的cacheBitmap上cacheCanvas = new Canvas();path = new Path();cacheCanvas.setBitmap(cacheBitmap);}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:path.moveTo(x, y);preX = x;preY = x;break;case MotionEvent.ACTION_MOVE:path.quadTo(preX, preY, x, y);preX = x;preY = y;break;case MotionEvent.ACTION_UP:cacheCanvas.drawPath(path, paint);path.reset();break;}invalidate();// 返回true表明处理方法已经处理该事件return true;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();// 将该bitmap绘制到该View组件上canvas.drawBitmap(cacheBitmap, 0, 0, paint);// 沿着path绘制canvas.drawPath(path, paint);}}

一个弹球游戏例子

[java] view plain copy
print ?
  1. package com.example.canvastest;  
  2.   
  3. import java.util.Random;  
  4. import java.util.Timer;  
  5. import java.util.TimerTask;  
  6.   
  7. import android.app.Activity;  
  8. import android.content.Context;  
  9. import android.graphics.Canvas;  
  10. import android.graphics.Color;  
  11. import android.graphics.Paint;  
  12. import android.os.Bundle;  
  13. import android.os.Handler;  
  14. import android.util.AttributeSet;  
  15. import android.util.DisplayMetrics;  
  16. import android.view.Display;  
  17. import android.view.KeyEvent;  
  18. import android.view.View;  
  19. import android.view.View.OnKeyListener;  
  20. import android.view.Window;  
  21. import android.view.WindowManager;  
  22.   
  23. public class PinBallActivity extends Activity {  
  24.     /** 桌面的宽度 */  
  25.     private int tableWidth;  
  26.     /** 桌面的高度 */  
  27.     private int tableHeight;  
  28.   
  29.     /** 随机数生成器 **/  
  30.     private Random random = new Random();  
  31.   
  32.     /** 球拍的垂直位置 */  
  33.     private int racketY;  
  34.     /** 球拍的水平位置 */  
  35.     private int racketX = random.nextInt(200);  
  36.     /** 球拍的宽度 */  
  37.     private final int RACKET_WIDTH = 70;  
  38.     /** 球拍的高度 */  
  39.     private final int RACKET_HEIGHT = 20;  
  40.   
  41.     /** 小球的大小 */  
  42.     private int BALL_SIZE = 12;  
  43.     /** 小球的X坐标 */  
  44.     private int ballX = random.nextInt(200) + 20;  
  45.     /** 小球的Y坐标 */  
  46.     private int ballY = random.nextInt(10) + 20;  
  47.       
  48.     /**返回一个-0.5~0.5的比率,用于控制小球的运行方向*/  
  49.     private double xyRate = random.nextDouble()- 0.5;  
  50.     /**小球的纵向运行速度*/  
  51.     private int ySpeed = 10;  
  52.     /**小球的横向运行速度*/  
  53.     private int xSpeed = (int) (ySpeed * xyRate * 2);     
  54.   
  55.     /*** 游戏是否结束的游标 */  
  56.     private boolean isLose = false;  
  57.   
  58.     @Override  
  59.     protected void onCreate(Bundle savedInstanceState) {  
  60.         super.onCreate(savedInstanceState);  
  61.         // 去掉窗口标题  
  62.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  63.         // 全屏显示  
  64.         getWindow().setFlags(WindowManager.LayoutParams.MATCH_PARENT,  
  65.                 WindowManager.LayoutParams.MATCH_PARENT);  
  66.         // 创建FameView组件  
  67.         final GameView gameView = new GameView(this);  
  68.         setContentView(gameView);  
  69.         // 获取窗口管理器  
  70.         WindowManager manager = getWindowManager();  
  71.         // 获取密度  
  72.         Display display = manager.getDefaultDisplay();  
  73.         DisplayMetrics displayMetrics = new DisplayMetrics();  
  74.         display.getMetrics(displayMetrics);  
  75.         // 获得屏幕的宽和高  
  76.         tableWidth = displayMetrics.widthPixels;  
  77.         tableHeight = displayMetrics.heightPixels;  
  78.         // 初始化球拍的垂直位置  
  79.         racketY = tableHeight - 80;  
  80.         final Handler handler = new Handler() {  
  81.             public void handleMessage(android.os.Message msg) {  
  82.                 if (msg.what == 0x123) {  
  83.                     gameView.invalidate();  
  84.                 }  
  85.             };  
  86.         };  
  87.   
  88.         gameView.setOnKeyListener(new OnKeyListener() {  
  89.             @Override  
  90.             public boolean onKey(View v, int keyCode, KeyEvent event) {  
  91.                 // 获取由那个键触发的事件  
  92.                 switch (event.getAction()) {  
  93.                 // 控制挡板左移  
  94.                 case KeyEvent.KEYCODE_A:  
  95.                     if (racketX > 0)  
  96.                         racketX -= 10;  
  97.                     break;  
  98.                 // 控制挡板右移  
  99.                 case KeyEvent.KEYCODE_D:  
  100.                     if (racketX < tableWidth - tableWidth)  
  101.                         racketX += 10;  
  102.                     break;  
  103.                 }  
  104.                 // 通知GameView重绘  
  105.                 gameView.invalidate();  
  106.                 return true;  
  107.             }  
  108.         });  
  109.         final Timer timer = new Timer();  
  110.         timer.schedule(new TimerTask() {  
  111.             @Override  
  112.             public void run() {  
  113.                 //如果小球碰到左边边框  
  114.                 if(ballX <= 0  || ballX >= tableWidth - BALL_SIZE){  
  115.                     xSpeed = -xSpeed;  
  116.                 }  
  117.                 //如果小球高度超出了球拍的位置,且横向不在球拍的范围之内,游戏结束  
  118.                 if(ballY >= racketY - BALL_SIZE && (ballX  < racketX || ballX > racketX + RACKET_WIDTH)){  
  119.                     timer.cancel();  
  120.                     //设置游戏是否结束的旗标为true  
  121.                     isLose = true;  
  122.                 }  
  123.                 //如果小球位于球拍之内,且到达球拍位置,小球反弹  
  124.                 else if(ballY <= 0 || (ballY >= racketY - BALL_SIZE && ballX >racketX && ballX <= racketX + RACKET_WIDTH)){  
  125.                     ySpeed = -ySpeed;  
  126.                 }  
  127.                 //小球的坐标增加  
  128.                 ballX += xSpeed;  
  129.                 ballY += ySpeed;  
  130.                 //发送消息,通知系统重绘组件  
  131.                 handler.sendEmptyMessage(0x123);  
  132.             }  
  133.         }, 0100);  
  134.     }  
  135.   
  136.     class GameView extends View {  
  137.         Paint paint = new Paint();  
  138.   
  139.         public GameView(Context context) {  
  140.             this(context, null);  
  141.         }  
  142.   
  143.         public GameView(Context context, AttributeSet attrs) {  
  144.             this(context, attrs, 0);  
  145.         }  
  146.   
  147.         public GameView(Context context, AttributeSet attrs, int defStyleAttr) {  
  148.             super(context, attrs, defStyleAttr);  
  149.             // 接收焦点  
  150.             setFocusable(true);  
  151.         }  
  152.   
  153.         @Override  
  154.         protected void onDraw(Canvas canvas) {  
  155.             super.onDraw(canvas);  
  156.             // 设置样式  
  157.             paint.setStyle(Paint.Style.FILL);  
  158.             // 抗锯齿  
  159.             paint.setAntiAlias(true);  
  160.             // 如果游戏已经结束  
  161.             if (isLose) {  
  162.                 // 颜色  
  163.                 paint.setColor(Color.RED);  
  164.                 ;  
  165.                 // 字体大小  
  166.                 paint.setTextSize(40);  
  167.                 canvas.drawText("游戏结束"50200, paint);  
  168.             }  
  169.             // 如果游戏还没有结束  
  170.             else {  
  171.                 // 设置颜色,绘制小球  
  172.                 paint.setColor(Color.rgb(24024080));  
  173.                 canvas.drawCircle(ballX, ballY, BALL_SIZE, paint);  
  174.                 // 设置颜色,绘制球拍  
  175.                 paint.setColor(Color.rgb(8080200));  
  176.                 canvas.drawRect(racketX, racketY, racketX + RACKET_WIDTH,  
  177.                         racketY + RACKET_HEIGHT, paint);  
  178.             }  
  179.   
  180.         }  
  181.   
  182.     }  
  183.   
  184. }  
package com.example.canvastest;import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.Window;
import android.view.WindowManager;public class PinBallActivity extends Activity {/** 桌面的宽度 */private int tableWidth;/** 桌面的高度 */private int tableHeight;/** 随机数生成器 **/private Random random = new Random();/** 球拍的垂直位置 */private int racketY;/** 球拍的水平位置 */private int racketX = random.nextInt(200);/** 球拍的宽度 */private final int RACKET_WIDTH = 70;/** 球拍的高度 */private final int RACKET_HEIGHT = 20;/** 小球的大小 */private int BALL_SIZE = 12;/** 小球的X坐标 */private int ballX = random.nextInt(200) + 20;/** 小球的Y坐标 */private int ballY = random.nextInt(10) + 20;/**返回一个-0.5~0.5的比率,用于控制小球的运行方向*/private double xyRate = random.nextDouble()- 0.5;/**小球的纵向运行速度*/private int ySpeed = 10;/**小球的横向运行速度*/private int xSpeed = (int) (ySpeed * xyRate * 2);   /*** 游戏是否结束的游标 */private boolean isLose = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 去掉窗口标题requestWindowFeature(Window.FEATURE_NO_TITLE);// 全屏显示getWindow().setFlags(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT);// 创建FameView组件final GameView gameView = new GameView(this);setContentView(gameView);// 获取窗口管理器WindowManager manager = getWindowManager();// 获取密度Display display = manager.getDefaultDisplay();DisplayMetrics displayMetrics = new DisplayMetrics();display.getMetrics(displayMetrics);// 获得屏幕的宽和高tableWidth = displayMetrics.widthPixels;tableHeight = displayMetrics.heightPixels;// 初始化球拍的垂直位置racketY = tableHeight - 80;final Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {if (msg.what == 0x123) {gameView.invalidate();}};};gameView.setOnKeyListener(new OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {// 获取由那个键触发的事件switch (event.getAction()) {// 控制挡板左移case KeyEvent.KEYCODE_A:if (racketX > 0)racketX -= 10;break;// 控制挡板右移case KeyEvent.KEYCODE_D:if (racketX < tableWidth - tableWidth)racketX += 10;break;}// 通知GameView重绘gameView.invalidate();return true;}});final Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {//如果小球碰到左边边框if(ballX <= 0  || ballX >= tableWidth - BALL_SIZE){xSpeed = -xSpeed;}//如果小球高度超出了球拍的位置,且横向不在球拍的范围之内,游戏结束if(ballY >= racketY - BALL_SIZE && (ballX  < racketX || ballX > racketX + RACKET_WIDTH)){timer.cancel();//设置游戏是否结束的旗标为trueisLose = true;}//如果小球位于球拍之内,且到达球拍位置,小球反弹else if(ballY <= 0 || (ballY >= racketY - BALL_SIZE && ballX >racketX && ballX <= racketX + RACKET_WIDTH)){ySpeed = -ySpeed;}//小球的坐标增加ballX += xSpeed;ballY += ySpeed;//发送消息,通知系统重绘组件handler.sendEmptyMessage(0x123);}}, 0, 100);}class GameView extends View {Paint paint = new Paint();public GameView(Context context) {this(context, null);}public GameView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public GameView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);// 接收焦点setFocusable(true);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 设置样式paint.setStyle(Paint.Style.FILL);// 抗锯齿paint.setAntiAlias(true);// 如果游戏已经结束if (isLose) {// 颜色paint.setColor(Color.RED);;// 字体大小paint.setTextSize(40);canvas.drawText("游戏结束", 50, 200, paint);}// 如果游戏还没有结束else {// 设置颜色,绘制小球paint.setColor(Color.rgb(240, 240, 80));canvas.drawCircle(ballX, ballY, BALL_SIZE, paint);// 设置颜色,绘制球拍paint.setColor(Color.rgb(80, 80, 200));canvas.drawRect(racketX, racketY, racketX + RACKET_WIDTH,racketY + RACKET_HEIGHT, paint);}}}}



这篇关于Android Canvas 和Paint的用法 转自http://blog.csdn.net/u010947098/article/details/44574171的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118282

相关文章

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

bytes.split的用法和注意事项

当然,我很乐意详细介绍 bytes.Split 的用法和注意事项。这个函数是 Go 标准库中 bytes 包的一个重要组成部分,用于分割字节切片。 基本用法 bytes.Split 的函数签名如下: func Split(s, sep []byte) [][]byte s 是要分割的字节切片sep 是用作分隔符的字节切片返回值是一个二维字节切片,包含分割后的结果 基本使用示例: pa

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动