Android简易画板


动画其实就是不断的调用View组件的onDraw方法,每次在View组件上绘制的图形不同就形成了我们看到的动画。

为了让View组件上绘制的图形发生改变,就需要采用变量记住这些数据状态,如果需要用户操作,那么就需要创建事件监听器,如果是动画自己改变那么就需要使用定时器Timer。通知View重绘可调用invalidate(在UI线程中)和postInvalidate(在非UI线程中)。

现在要做一个画图板,其实我们看到的手绘是一种假象,实际上是利用Canvas的drawLine方法画直线,每条直线都是由多个拖动事件连接而成的,通过Path类可以很方便实

现。需要指出的是这里需要使用双缓冲技术,即先把图绘制在一个内存中的cacheBitmap中,等到内存中的Bitmap绘制好之后再一次性将cacheBitmap绘制在View上。


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 = 480;  //可以根据自己手机的分辨率调整大
	final int VIEW_HEIGHT = 800;
	// 定义一个内存中的图片,该图片将作为缓冲区
	Bitmap cacheBitmap = null;
	// 定义cacheBitmap上的Canvas对象
	Canvas cacheCanvas = null;

	public DrawView(Context context, AttributeSet set)
	{
		super(context, set);
		// 创建一个与该View相同大小的缓存区
		cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_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(1);
		// 反锯齿
		paint.setAntiAlias(true);
		paint.setDither(true);
	}

	@Override
	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;
	}

	@Override
	public void onDraw(Canvas canvas)
	{
		Paint bmpPaint = new Paint();   
		// 将cacheBitmap绘制到该View组件上
		canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); 
		// 沿着path绘制
		canvas.drawPath(path, paint);
	}
}

import android.app.Activity;
import android.graphics.BlurMaskFilter;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class HandDraw extends Activity
{  /* MaskFilter类可以为Paint分配边缘效果。对MaskFilter的扩展可以对一个Paint边缘的alpha通道应用转换。
   Android包含了下面几种MaskFilter:
   BlurMaskFilter   指定了一个模糊的样式和半径来处理Paint的边缘。
   EmbossMaskFilter  指定了光源的方向和环境光强度来添加浮雕效果。
   要应用一个MaskFilter,可以使用setMaskFilter方法,并传递给它一个MaskFilter对象。
*/
	EmbossMaskFilter emboss;
	BlurMaskFilter blur;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.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)
	{
		MenuInflater inflator = new MenuInflater(this);
		// 装载R.menu.my_menu对应的菜单,并添加到menu中
		inflator.inflate(R.menu.my_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@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);
				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;
	}
}

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<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>


Android简易画板,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。