参考文章:http://blog.csdn.net/lee576/article/details/7870160
在他的基础上稍微补充了一点:
当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。
双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。双缓冲实现过程如下:
1、在内存中创建与画布一致的缓冲区
2、在缓冲区画图
3、将缓冲区位图拷贝到当前画布上
4、释放内存缓冲区
代码已经传到网上,下载地址为:
http://download.csdn.net/download/qizheguang/9434947
下面贴代码:
MainActivity.java
package com.example.doublebuffer;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.BlurMaskFilter;
import android.graphics.EmbossMaskFilter;
import android.graphics.Color;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity{
EmbossMaskFilter emboss;
BlurMaskFilter blur;
DrawView drawview; //调用另一个类
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
emboss = new EmbossMaskFilter(new float[]{1.5f,1.5f,1.5f},0.6f,6,4.2f);
blur = new BlurMaskFilter(8,BlurMaskFilter.Blur.NORMAL);
Button button = (Button)findViewById(R.id.Erase_Everything);
drawview = (DrawView)findViewById(R.id.draw);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
drawview.ReleaseDraw();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflator = new MenuInflater(this);
//状态R.menu.context对应菜单,并添加到中
inflator.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
// getMenuInflater().inflate(R.menu.main, menu);
// return true;
}
//菜单项被单击后的回调方法
@Override
public boolean onOptionsItemSelected(MenuItem mi)
{
DrawView dv = (DrawView)findViewById(R.id.draw);
//判断单击的是哪个菜单项,并有针对性地做出响应
switch(mi.getItemId())
{
case R.id.red:
dv.paint.setColor(Color.RED);
mi.setChecked(true);
break;
case R.id.green:
dv.paint.setColor(Color.GREEN);
mi.setChecked(true);
break;
case R.id.blue:
dv.paint.setColor(Color.BLUE);
mi.setChecked(true);
break;
case R.id.width_1:
dv.paint.setStrokeWidth(1);
mi.setChecked(true);
break;
case R.id.width_3:
dv.paint.setStrokeWidth(3);
mi.setChecked(true);
break;
case R.id.width_5:
dv.paint.setStrokeWidth(5);
mi.setChecked(true);
break;
case R.id.blur:
dv.paint.setMaskFilter(blur);
mi.setChecked(true);
break;
case R.id.emboss:
dv.paint.setMaskFilter(emboss);
mi.setChecked(true);
break;
}
return true;
}
}
DrawView.java
package com.example.doublebuffer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
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;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
public class DrawView extends View {
// public Button btnEraseAll;
// public LayoutParams params;
float preX;
float preY;
private Path path;
public Paint paint = null;
// final int VIEW_WIDTH = 320;
// final int VIEW_HEIGHT = 480;
//定义一个内存中的图片,该图片将作为缓冲区
Bitmap cacheBitmap = null;
//定义cacheBitmap上的canvas对象
Canvas cacheCanvas = null;
int width; //手机屏幕宽度
int height; //手机屏幕高度
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
//创建一个与该View相同大小的缓存区
// cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH,VIEW_HEIGHT,Config.ARGB_8888);
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
width = wm.getDefaultDisplay().getWidth(); //--表示函数很老
height = wm.getDefaultDisplay().getHeight();
// btnEraseAll = new Button(context);
// btnEraseAll.setText("Erase Everything!!");
// params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT); //动态构建布局
// btnEraseAll.setLayoutParams(params);
}
//释放
public void ReleaseDraw()
{
cacheBitmap = null;
cacheCanvas = null;
path.reset();
postInvalidate();
}
public 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 = y;
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;
}
public void onDraw(Canvas canvas)
{
if (cacheBitmap == null) {
cacheBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
cacheCanvas = new Canvas();
path = new Path();
//设置cacheCanvas将会绘制到内存中的cacheBitmap上
cacheCanvas.setBitmap(cacheBitmap);
//设置画笔的颜色
paint = new Paint(Paint.DITHER_FLAG);
paint.setColor(Color.RED);
//设置画笔的风格
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
//设置结合处的样子,MITER:结合处为锐角, ROUND:结合处为圆弧:BEVEL:结合处为直线。
paint.setStrokeJoin(Paint.Join.ROUND);
//反锯齿
paint.setAntiAlias(true);
paint.setDither(true);
}
Paint bmpPaint = new Paint();
//将cacheBitmap绘制到该View组件上
canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint);
//沿着path绘制
canvas.drawPath(path, paint);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.doublebuffer.DrawView
android:id="@+id/draw"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"
/>
<Button
android:id="@+id/Erase_Everything"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Erase Everything"
/>
<!-- View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#000000"/-->
</LinearLayout>
</LinearLayout>
main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="@string/action_settings"/-->
<item android:title="@string/color">
<menu>
<!-- 定义一组单选菜单项 -->
<group android:checkableBehavior="single">
<!-- 定义多个菜单项 -->
<item
android:id="@+id/red" android:title="@string/color_red"/>
<item
android:id="@+id/green" android:title="@string/color_green"/>
<item
android:id="@+id/blue" android:title="@string/color_blue"/>
</group>
</menu>
</item>
<item android:title="@string/width">
<menu>
<!-- 定义一组菜单项 -->
<group>
<!-- 定义3个菜单项 -->
<item
android:id="@+id/width_1" android:title="@string/width_1"/>
<item
android:id="@+id/width_3" android:title="@string/width_3"/>
<item
android:id="@+id/width_5" android:title="@string/width_5"/>
</group>
</menu>
</item>
<item
android:id="@+id/blur" android:title="@string/blur"/>
<item
android:id="@+id/emboss" android:title="@string/emboss"/>
</menu>
strings.xml
<string name="hello">Hello World, HandDraw!</string>
<string name="width_1">1像素</string>
<string name="width_3">3像素</string>
<string name="width_5">5像素</string>
<string name="color_red">红色</string>
<string name="color_green">绿色</string>
<string name="color_blue">蓝色</string>
<string name="color">画笔颜色</string>
<string name="width">画笔宽度</string>
<string name="blur">模糊效果</string>
<string name="emboss">浮雕效果</string>