Double buffering technique is mainly used in the drawing, animation. The principle is: the resource is first loaded into the buffer, and then the entire buffer is loaded into the View to the top.
Double buffering technique can effectively prevent flicker. Improve display quality.
DrawView.java:
package com.example.handdraw;
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;
public class DrawView extends View{
float preX;
float preY;
private Path path;
public Paint paint = null;
final int VIEW_WIDTH = 720;
final int VIEW_HEIGHT = 800;
// define an in-memory image, it will serve as a buffer
Bitmap cacheBitmap = null;
// Canvas object on the definition of cacheBitmap
Canvas cacheCanvas = null ;
public DrawView(Context context ,AttributeSet set) {
super(context, set);
// TODO Auto-generated constructor stub
// Create a similar size of the buffer View
cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT, Config.ARGB_8888);
cacheCanvas = new Canvas ();
path = new Path();
// set cacheCanvas will be drawn to the cacheBitmap memory
cacheCanvas .setBitmap ( cacheBitmap );
// set the pen color
paint = new Paint(Paint.DITHER_FLAG);
paint.setColor(Color.RED);
// set the pen style
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
// anti-aliasing
paint.setAntiAlias(true);
paint.setDither(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Get drag event location
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();
// show processing methods have changed event processing
return true;
}
@Override
protected void onDraw(Canvas canvas) {
Paint bmpPaint = new Paint();
// The cacheBitmap drawn onto the component View
canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint);
// Draw along the path
canvas.drawPath(path, paint);
}
}
my_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:title="@string/color">
<menu>
<! - Defines a group of radio menu item ->
<group >
<-! Define multiple menu items ->
<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 >
<! - Defines a set of menu items ->
<group >
<! - defines three menu items ->
<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>
Activity.java:package com.example.handdraw;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.BlurMaskFilter;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public class MainActivity extends Activity {
EmbossMaskFilter emboss;
BlurMaskFilter blur;
@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);
}
@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);
inflator.inflate(R.menu.my_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
DrawView dv = (DrawView)findViewById(R.id.draw);
switch(item.getItemId())
{
case R.id.red:
dv.paint.setColor(Color.RED);
item.setChecked(true);
break;
case R.id.green:
dv.paint.setColor(Color.GREEN);
item.setChecked(true);
break;
case R.id.blue:
dv.paint.setColor(Color.BLUE);
item.setChecked(true);
break;
case R.id.width_1:
dv.paint.setStrokeWidth(1);
break;
case R.id.width_3:
dv.paint.setStrokeWidth(3);
break;
case R.id.width_5:
dv.paint.setStrokeWidth(5);
break;
case R.id.blur:
dv.paint.setMaskFilter(blur);
break;
case R.id.emboss:
dv.paint.setMaskFilter(emboss);
break;
}
return true;
}
}
main.xml
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.example.handdraw.DrawView
android:id="@+id/draw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>