“如何在手机上绘制2D圈形呢? "这是许多android游戏开发都是常提到的问题,在android SDK当中,并无JavaGraphics2D的函数可使用,而是使用android.graphics底下的类来绘制20向量图。这个package提供了许多在手机上绘制图形的类与方法其中Canvas上而Paint(Android graphics Paint)类则像是彩色铅笔,给予不一样的调协,便可绘制不一样颜色
不一样种类效果的向量图形。java
本例将运用Paint对象(绘笔)的设置值不一样,在Cavas(画布)上绘制空心、实心及渐变色的多种几何多形。android
自定义一个View类继承View,并重写onDraw方法web
package com.example.animateandview; 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.view.View; public class MyView extends View { public MyView(Context context) { super(context); } //会在主键加载时调用 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //设置画布颜色为白色 canvas.drawColor(Color.WHITE); Paint paint=new Paint();//建立画笔 //去锯齿 paint.setAntiAlias(true); //设置画笔颜色 paint.setColor(Color.RED); //设置画笔风格(空心、实心) STROKE:空心 paint.setStyle(Paint.Style.STROKE); //设置画笔宽度 paint.setStrokeWidth(3); //画一个空心圆 参数(圆心x,圆心y,半径r,paint) canvas.drawCircle(40,40,30,paint); //画一个空心正方形 参数(left,top,right,buttom,) canvas.drawRect(10,90,70,150,paint); //长方形 canvas.drawRect(10,170,70,200,paint); //椭圆形 RectF re=new RectF(10,220,70,250); canvas.drawOval(re,paint); //三角形 Path path=new Path(); path.moveTo(10,330); path.lineTo(70,330); path.lineTo(40,270); path.close(); canvas.drawPath(path,paint); //梯形 Path path1=new Path(); path1.moveTo(10,410); path1.lineTo(70,410); path1.lineTo(55,350); path1.lineTo(25,350); path1.close(); canvas.drawPath(path1,paint); //实心 paint.setStyle(Paint.Style.FILL); paint.setColor(Color.BLUE); //画一个实心圆 参数(圆心x,圆心y,半径r,paint) canvas.drawCircle(120,40,30,paint); //画一个实心正方形 参数(left,top,right,buttom,) canvas.drawRect(90,90,150,150,paint); //长方形 canvas.drawRect(90,170,150,200,paint); //椭圆形 RectF re1=new RectF(90,220,150,250); canvas.drawOval(re1,paint); //三角形 Path path2=new Path(); path2.moveTo(90,330); path2.lineTo(150,330); path2.lineTo(120,270); path2.close(); canvas.drawPath(path2,paint); //梯形 Path path3=new Path(); path3.moveTo(90,410); path3.lineTo(150,410); path3.lineTo(135,350); path3.lineTo(105,350); path3.close(); canvas.drawPath(path3,paint); //绘制渐变色 Shader shader=new LinearGradient(0,0,100,100,new int[]{ Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},null,Shader.TileMode.REPEAT); paint.setShader(shader); //画一个渐变圆 参数(圆心x,圆心y,半径r,paint) canvas.drawCircle(200,40,30,paint); //画一个渐变正方形 参数(left,top,right,buttom,) canvas.drawRect(170,90,230,150,paint); //长方形 canvas.drawRect(170,170,230,200,paint); //椭圆形 RectF re2=new RectF(170,220,230,250); canvas.drawOval(re2,paint); //三角形 Path path4=new Path(); path4.moveTo(170,330); path4.lineTo(230,330); path4.lineTo(200,270); path4.close(); canvas.drawPath(path4,paint); //梯形 Path path5=new Path(); path5.moveTo(170,410); path5.lineTo(230,410); path5.lineTo(215,350); path5.lineTo(185,350); path5.close(); canvas.drawPath(path5,paint); //文字 paint.setTextSize(24); canvas.drawText("圆形",240,50,paint); canvas.drawText("正方形",240,120,paint); canvas.drawText("长方形",240,190,paint); canvas.drawText("椭圆形",240,250,paint); canvas.drawText("三角形",240,320,paint); canvas.drawText("梯形",240,390,paint); } }
显示文件修改setContentViewcanvas
setContentView(new MyView(this));
问题:有个问题就是,渐变色只显示圆形和椭圆,多边形和文字不显示app
自定义一个View类继承View,并重写onDraw方法ide
package com.example.animateandview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.view.View; public class MyImageView extends View { public MyImageView(Context context) { super(context); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint=new Paint(); Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher); canvas.drawBitmap(bitmap,0,0,paint); } }
修改setContentViewsvg
setContentView(new MyView(this));
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你能够控制这个Surface的格式和尺寸SurfaceView控制这个Surface的绘制位置。能够直接从内存或者DMA等硬件接口取得图像数据,是个很是重要的绘图容器。函数
传统View及其派生类的更新只能在UI线程,然而UI线程还同时处理其余交互逻辑,这就没法保证view更新的速度和帧率了,而SurfaceView能够用独立的线程来进行绘制,所以能够提供更高的帧率。工具
例如游戏,摄像头取景等场景就比较适合用SurfaceView来实现。写入到Surface的内容能够被直接复制到显存从而显示出来,这使得显示速度会很是快。动画
package com.example.animateandview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder holder; private MyThread myThread; public MySurfaceView(Context context) { super(context); holder=this.getHolder(); holder.addCallback(this);//添加回调接口 } //线程内部类 class MyThread implements Runnable{ private SurfaceHolder holder; public boolean isRun; public MyThread(SurfaceHolder holder){ this.holder=holder; isRun=true; } @Override public void run() { int count=0; Canvas canvas=null; while (isRun){ try { synchronized (holder){//同步块 canvas=holder.lockCanvas();//锁定画布 canvas.drawColor(Color.WHITE); Paint paint=new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); paint.setAntiAlias(true); canvas.drawRect(10,10,100,100,paint); paint.setTextSize(24); canvas.drawText("当前是第"+(count++)+"秒",10,150,paint); Thread.sleep(1000);//休眠1秒 } } catch (InterruptedException e) { e.printStackTrace(); }finally { holder.unlockCanvasAndPost(canvas);//释放 } } } } @Override public void surfaceCreated(SurfaceHolder holder) { myThread=new MyThread(holder); myThread.isRun=true; new Thread(myThread).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { myThread.isRun=false; } }
修改setContentView
setContentView(new MySurfaceView(this));
package com.example.animateandview; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import java.io.IOException; public class Main5Activity extends AppCompatActivity implements SurfaceHolder.Callback { private SurfaceView surfaceView; private SurfaceHolder holder; private MediaPlayer player; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main5); surfaceView=findViewById(R.id.surfaceView); holder=surfaceView.getHolder(); holder.addCallback(this); holder.setFixedSize(320,220);//设置分辨率,不设置即为视频默认分辨率 } public void playClick(View view){ player.start(); } public void pauseClick(View view){ player.pause(); } public void stopClick(View view){ player.stop(); } @Override public void surfaceCreated(SurfaceHolder holder) { player=new MediaPlayer(); player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setDisplay(holder); String path= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)+"/2.mp4"; try { player.setDataSource(path);//设置播放视频源 player.prepare(); } catch (IOException e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (player!=null){ if (player.isPlaying()){ player.stop(); player.release(); } } } @Override protected void onDestroy() { super.onDestroy(); if (player!=null){ if (player.isPlaying()){ player.stop(); player.release(); } } } }
设置权限,以前忘记设置,致使找不到文件,视频没法播放
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
与传统的png格式图片相比,9.png 格式图片在图片四周有一圈一个像素点组成的边沿,该边沿用于对图片的可扩展区和内容显示区进行定义。这种格式的图片在android环境下具备自适应调节大小的能力。
运行android SDK中tools路径下的draw9patch工具:
给.9图片划线,指的是经过划线,决定图片的可拉伸区域和显示文本信息的区域。其中,上方和左 方的线是控制图片的可拉伸区域的,也就是说,上方的线控制图片横向可拉伸,左侧的线控制纵向可拉伸。下方的线和右侧的线控制图片的文本区域,也就是说,若是图片上有text,就会杷位置控制在下方和右侧的线围城的区域里。
若是想制除划线,按住shift+鼠标左键,删除划线。
如今由于draw9patch已经被普遍使用,已经在android studio里了。