Android 图形用户界面 之 绘图(一)
2015-11-02 14:35
417 查看
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* http://wallage.blog.163.com/blog/static/173896242010101232220959/
* @author emmet1988.iteye.com
*
*/
public class SurfaceViewDraw extends SurfaceView implements Runnable,SurfaceHolder.Callback {
private Bitmap backgroundBitmap;
private Bitmap rotateBitmap;
SurfaceHolder surfaceHolder;
public SurfaceViewDraw(Context context) {
super(context);
backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_surfaceview);
rotateBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rotate_surfaceview);
surfaceHolder = this.getHolder();
surfaceHolder.addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
new Thread(this).start();
Log.d("surfaceview", "surfaceCreated");
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d("surfaceview", "surfaceChanged");
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d("surfaceview", "surfaceDestroyed");
}
@Override
public void run() {
Log.d("surfaceview", "run");
Canvas canvas = null;
int rotateValue = 0;//旋转角度
int frameCount = 0;//帧计数器
while (!Thread.currentThread().isInterrupted()) {
try {
// canvas = surfaceHolder.lockCanvas();//获取画布对象(获取整个屏幕的画布)
canvas = surfaceHolder.lockCanvas(new Rect(10, 10, 240, 250));//获取某个区域的画布
Paint paint = new Paint();
Log.d("surfaceview", "rotateValue " +rotateValue+"|frameCount "+frameCount);
if (frameCount++ < 2) {//仅在第一次绘制时绘制背景
/*
* 这里为什么设置成<2,而不是1,是由于SurfaceView本身的双缓冲技术。
覆盖刷新其实就是将每次的新的图形绘制到上一帧去,
所以如果图像是半透明的,就要考虑重复叠加导致的问题了,
而如果是完全不透明的图形则不会有任何问题。
背景会在背景图和黑色背景之间来回闪。
这个问题其实是源于SurfaceView的双缓冲机制,我理解就是它会缓冲
前两帧的图像交替传递给后面的帧用作覆盖,这样由于我们仅在第一帧
绘制了背景,第二帧就是无背景状态了,且通过双缓冲机制一直保持下
来,解决办法就是改为在前两帧都进行背景绘制。
*/
canvas.drawBitmap(backgroundBitmap, 0, 0, paint);//绘制背景
}
//创建矩阵以控制图片的旋转和平移
Matrix matrix = new Matrix();
rotateValue += 40;
matrix.setRotate(rotateValue, rotateBitmap.getWidth()/2, rotateBitmap.getHeight()/2);
// matrix.postRotate(rotateValue, rotateBitmap.getWidth()/2, rotateBitmap.getHeight()/2);
// matrix.setTranslate(100, rotateValue);
if (rotateValue == 360) {
rotateValue = 0;
}
matrix.setTranslate(80,50);//设置左边距和上边距
//绘制问号
Log.d("surfaceview", "canvas "+canvas);
Log.d("surfaceview", "rotateBitmap "+rotateBitmap);
Log.d("surfaceview", "matrix "+matrix);
Log.d("surfaceview", "paint "+paint);
if (canvas != null) {
canvas.drawBitmap(rotateBitmap, matrix, paint);
//解锁画布,提交画好的图像
surfaceHolder.unlockCanvasAndPost(canvas);
}
Thread.sleep(30);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Log.d("surfaceview", "InterruptedException");
} finally {
Log.d("surfaceview", "finally");
}
}
}
}
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
/**
* http://wallage.blog.163.com/blog/static/173896242010101232220959/
* @author emmet1988.iteye.com
*
*/
public class SurfaceViewDraw extends SurfaceView implements Runnable,SurfaceHolder.Callback {
private Bitmap backgroundBitmap;
private Bitmap rotateBitmap;
SurfaceHolder surfaceHolder;
public SurfaceViewDraw(Context context) {
super(context);
backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_surfaceview);
rotateBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rotate_surfaceview);
surfaceHolder = this.getHolder();
surfaceHolder.addCallback(this);
}
public void surfaceCreated(SurfaceHolder holder) {
new Thread(this).start();
Log.d("surfaceview", "surfaceCreated");
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d("surfaceview", "surfaceChanged");
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d("surfaceview", "surfaceDestroyed");
}
@Override
public void run() {
Log.d("surfaceview", "run");
Canvas canvas = null;
int rotateValue = 0;//旋转角度
int frameCount = 0;//帧计数器
while (!Thread.currentThread().isInterrupted()) {
try {
// canvas = surfaceHolder.lockCanvas();//获取画布对象(获取整个屏幕的画布)
canvas = surfaceHolder.lockCanvas(new Rect(10, 10, 240, 250));//获取某个区域的画布
Paint paint = new Paint();
Log.d("surfaceview", "rotateValue " +rotateValue+"|frameCount "+frameCount);
if (frameCount++ < 2) {//仅在第一次绘制时绘制背景
/*
* 这里为什么设置成<2,而不是1,是由于SurfaceView本身的双缓冲技术。
覆盖刷新其实就是将每次的新的图形绘制到上一帧去,
所以如果图像是半透明的,就要考虑重复叠加导致的问题了,
而如果是完全不透明的图形则不会有任何问题。
背景会在背景图和黑色背景之间来回闪。
这个问题其实是源于SurfaceView的双缓冲机制,我理解就是它会缓冲
前两帧的图像交替传递给后面的帧用作覆盖,这样由于我们仅在第一帧
绘制了背景,第二帧就是无背景状态了,且通过双缓冲机制一直保持下
来,解决办法就是改为在前两帧都进行背景绘制。
*/
canvas.drawBitmap(backgroundBitmap, 0, 0, paint);//绘制背景
}
//创建矩阵以控制图片的旋转和平移
Matrix matrix = new Matrix();
rotateValue += 40;
matrix.setRotate(rotateValue, rotateBitmap.getWidth()/2, rotateBitmap.getHeight()/2);
// matrix.postRotate(rotateValue, rotateBitmap.getWidth()/2, rotateBitmap.getHeight()/2);
// matrix.setTranslate(100, rotateValue);
if (rotateValue == 360) {
rotateValue = 0;
}
matrix.setTranslate(80,50);//设置左边距和上边距
//绘制问号
Log.d("surfaceview", "canvas "+canvas);
Log.d("surfaceview", "rotateBitmap "+rotateBitmap);
Log.d("surfaceview", "matrix "+matrix);
Log.d("surfaceview", "paint "+paint);
if (canvas != null) {
canvas.drawBitmap(rotateBitmap, matrix, paint);
//解锁画布,提交画好的图像
surfaceHolder.unlockCanvasAndPost(canvas);
}
Thread.sleep(30);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
Log.d("surfaceview", "InterruptedException");
} finally {
Log.d("surfaceview", "finally");
}
}
}
}
相关文章推荐
- Android画布(cavas)
- Android图片添加标签:Android-PictureTagView
- Android中使用Handler造成内存泄露的原因和解决方法
- Android Rect和RectF的区别
- android viewpager轮播图无限循环
- Android 笔记-Fragment 与 Activity之间传递数据
- Android Matrix类以及ColorMatri
- (转)【Android】Paint的效果研究
- Android开发之AIDL的使用一--跨应用启动Service
- Android studio自动安装releaseAPK
- android listview左划删除与点击事件及item样式扩展
- android编程之下拉刷新实现方法分析
- android是用一个服务好还是开一个线程好
- Android~Handler机制自我理解
- Android EditText的设置
- 2015-11-02-Android Apk签名总结
- Android JS 与本地代码交互---JSBridge使用注意事项
- 学习网址记录
- 安卓开发中EditText的焦点改变处理(获取焦点和失去焦点交互变化)
- Android onTouchEvent和setOnTouchListener中onTouch的区别