要实现涂鸦这个功能,首先需要以下几步:
1、要实现一个DrawingView类,这个类继承View;
2、重写其父类的构造方法,并初始化涂鸦的画笔、画布的画笔和路径;
3、重写onDraw方法,在这个方法中主要进行涂鸦的绘制工作;
4、重写onTouchEvent事件,在这个方法计算当前的画笔的左边,规划画笔的路径,调用invalidate()方法不断调用onDraw方法进行绘制;
5、自定义setPattern方法设置画笔的描边效果;
6、在MainActivity以及其布局文件中引入自定义的DrawdingView对象;
代码如下:
public class DrawingView extends View {
private Path drawPath;
private Paint drawPaint;
private Paint canvasPaint;
private int paintColor = 0xFF000000;
private Bitmap canvasBitmap;
private Canvas drawCanvas;
public DrawingView(Context context) {
super(context,null);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
private void setupDrawing() {
drawPaint = new Paint();
drawPath = new Path();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(50);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap,0,0,canvasPaint);
canvas.drawPath(drawPath,drawPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:drawPath.moveTo(touchX,touchY);break;
case MotionEvent.ACTION_MOVE:drawPath.lineTo(touchX,touchY);break;
case MotionEvent.ACTION_UP:drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);
drawPath.reset();break;
default:return false;
}
invalidate();
return true;
}
public void setPattern(String newPattern){
invalidate();
int patternId = getResources().getIdentifier(newPattern,"drawable","com.example.lucky.drawapp");
Bitmap patternBMP = BitmapFactory.decodeResource(getResources(),patternId);
BitmapShader patternBMPshader = new BitmapShader(patternBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
drawPaint.setColor(0xFFFFFFFF);
drawPaint.setShader(patternBMPshader);
}
}
布局文件:
<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:background="#FFCCCCCC"
android:orientation="vertical"
tools:context=".MainActivity">
<com.example.lucky.drawapp.DrawingView
android:id="@+id/draw_view"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_marginBottom="3dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="3dp"
android:layout_weight="1"
android:background="#FFFFFFFF"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical" >
<!-- top row -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern1"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern1" />
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern2"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern2" />
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern3"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern3" />
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern4"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern4" />
</LinearLayout>
<!-- bottom row -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern5"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern5" />
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern6"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern6" />
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern7"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern7" />
<ImageButton
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_margin="2dp"
android:background="@drawable/pattern8"
android:contentDescription="pattern"
android:onClick="paintClicked"
android:tag="pattern8" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Activity中的代码:
public class MainActivity extends Activity {
private DrawingView drawView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawView = (DrawingView) findViewById(R.id.draw_view);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void paintClicked(View view) {
String pattern = view.getTag().toString();
drawView.setPattern(pattern);
}
}
效果图如下: