采用单缓冲与双缓冲机制分别实现。
一、单缓冲机制
1.1自定义View,重写ondraw函数
public class Brush extends View
{
private Paint brush = new Paint();
private Path path = new Path();
int j = 0, n = 0;
// xml创建view时调用的构造函数
public Brush(Context context,AttributeSet attrs)
{
super(context,attrs);
brush.setAntiAlias(true);
brush.setColor(Color.BLACK);
brush.setStyle(Paint.Style.STROKE);// stroke轮廓,fill填充
brush.setStrokeJoin(Paint.Join.ROUND);// 设置绘制时各图形的结合方式,如平滑效果等
// brush.setStrokeCap(Cap.ROUND);//当style不是fill时,图形样式
brush.setStrokeWidth(2f);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float pointX = event.getX();
float pointY = event.getY();
<span style="white-space:pre"> </span><pre name="code" class="java"> <span style="white-space:pre"> </span>setDrawingCacheEnabled(true);//开启该View的缓冲机制,将此操作放在1.1中
switch (event.getAction()){case MotionEvent.ACTION_DOWN:path.moveTo(pointX, pointY);break;case MotionEvent.ACTION_MOVE:path.lineTo(pointX, pointY);break;}// Force a view to draw again//postInvalidate();invalidate();return true;}@Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(cachebBitmap, 0, 0, null); canvas.drawPath(path, brush);}
1.2 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:id="@+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save" />
<com.example.move.Brush
android:id="@+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
1.3主Activity
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Brush picture = (Brush) findViewById(R.id.picture);
Button btnSave = (Button) findViewById(R.id.save);
btnSave.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Bitmap bm=Bitmap.createBitmap(picture.getDrawingCache());
picture.setDrawingCacheEnabled(false);
try
{
FileOutputStream stream=new FileOutputStream(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"hello.png"));<span style="white-space: pre;"> </span><pre name="code" class="java"><span style="white-space:pre"> </span>bm.compress(CompressFormat.PNG, 80, stream);//将bm数据压缩为png图片格式stream.close();<pre name="code" class="java"><span style="white-space:pre"> </span> } catch (Exception e1){e1.printStackTrace();} <pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>}</span>
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>});</span><pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>}</span><pre name="code" class="java"><span style="font-family: Arial, Helvetica, sans-serif;">}</span>
二 双缓冲机制
2.1自定义View,重载ondraw函数
public class Brush extends View
{
private Paint brush = new Paint();
private Path path = new Path();
private Canvas cacheCanvas;
private Bitmap cachebBitmap;
// C1是代码创建view时,C2是xml创建view时
public Brush(Context context,AttributeSet attrs)
{
super(context,attrs);
brush.setAntiAlias(true);
brush.setColor(Color.BLACK);
brush.setStyle(Paint.Style.STROKE);// stroke轮廓,fill填充
brush.setStrokeJoin(Paint.Join.ROUND);// 设置绘制时各图形的结合方式,如平滑效果等
// brush.setStrokeCap(Cap.ROUND);//当style不是fill时,图形样式
brush.setStrokeWidth(2f);
<span style="white-space:pre"> </span>//注意下面,用来存图像
cachebBitmap = Bitmap.createBitmap(1000, 1600, Config.ARGB_8888);
cacheCanvas = new Canvas(cachebBitmap);
cacheCanvas.drawColor(Color.WHITE);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
float pointX = event.getX();
float pointY = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX, pointY);
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX, pointY);
break;
case MotionEvent.ACTION_UP:
cacheCanvas.drawPath(path, brush);//抬起时,才画线
//path.reset();//对画布以外的部分有影响
break;
}
// Force a view to draw again
//postInvalidate();
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(cachebBitmap, 0, 0, null);
canvas.drawPath(path, brush);
}
}
2.2 XML布局文件
同1.2;
2.3 主Activity
只需要将1.3中bitmap信息,即bm修改为cachbBitmap即可以。