Android 中随机画线


       在刚收到这个任务是,我就想起了Bitmap Canvas Paint这些类。并且发现画线的长短,颜色都是随机的,这也说明了
每次画线时颜色和长短都要随机生成;而线的长短则是由坐标控制的,并且启始坐标是手机屏幕中心。所以我在onCreate()
中使用
        WindowManager wm = this.getWindowManager();
        int width = wm.getDefaultDisplay().getWidth();
        int height = wm.getDefaultDisplay().getHeight();
获取得到手机屏幕的宽和高,所以接下来随机长短就可以以创建Random对象调用nextInt(width)/nextInt(height)来确定线的长度

绘图所必须的3个类使用方法自己总结了一下:
             Bitmap :@1 创建mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 确定保存绘制内容的范围
                         @2  bitmap有保存绘制内容的作用

             Paint    :@1 主要就是创建一个画笔Paint mpaint = new Paint();
                          @2 设置paint的颜色setColor()    设置paint的宽度

             Canvas :@1 主要是绘制图画创建一个canvas = new Canvas(mBitmap);【这步作用:把绘制内容保存入mBitmap中】
                          @2 canvas调用drawLine(startX,startY,stopX,stopY,paint);来划线

但是在编写程序过程中还是遇到了很多问题:
   1、在oncreate()中进行操做:首先,在onCreate()中随机画一条先线,OK。于是在onCreate()中循环画10条线,问题出现,apk界面
显示UI需要等几秒中开始更新。因为没有无限循环所以,暂时没有出现问题,只是UI更新慢了点。
    于是在onCreate()中创建一个线程,实现循环,问题还是存在。
    
    2、使用SurfaceView: 上网查找问题,看到了surfaceView绘制动画,于是使用了一下发现当每次划线都会更新一次,不是想要的效果。

    3、自定义空间 :看了一下师傅做的,发现他是使用自定义控件,由于没有自定义过控件。自己试着自定义后,去使用发现总是报Binary xml file line # Error inflating class” 查找原因后是没有重写View构造函数的原因,具体在“Android运行时异常“Binary XML file line # : Error inflating class” “博客中有相关的介绍。调整之后发现可以使用,也可以成功。
    4、眼高手底: 在定义变量后,在画图中没有使用或者是在使用paint时忘了创建对象等等,导致NULLPointerException异常的出现
 
    5、子线程更新UI会发生android.view.ViewRoot$CalledFromWrongThreadException,这个问题是因为没有处理好耗时操作,所以我创建了Hander的子类在执行run()方法是发送一条消息,在子类中接收消息去调用画图方法。
                                                                                                                                                                                              _    _
在学习师傅方法的同时去改进自己的方法,我把好的他的思路和方法结合我的思路,通过实践完成了小组任务,感觉学到了很多。~(@.@)~
                                                                                                                                                                                                |    |
  

下面是使用两种方式做的画线apk

传不上资源库,直接貼代码:
【Draw是使用自定义控件画线】

控件类MyView 继承了View类
<span style="font-size:14px;">package com.example.view;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {
	private Bitmap bitmap ;				//保存绘制结果
	private Canvas tempCanvas;		//创建画布	
	private Paint paint = new Paint();
	private int width;	//画布的宽度
	private int height;	//画布的高度
	private int startX;		//画线的开始X坐标
	private int startY;		//画线的开始Y坐标
	private int stopX;		//画线结束的X坐标
	private int stopY;		//画线结束的Y坐标
	private int paintColor;		//画笔的颜色
	private Random paintRL = new Random();	//创建随机对象
	private int[] paintColors = new int[] { Color.RED, Color.BLUE,
			Color.YELLOW, Color.GREEN, Color.CYAN };

	/*
	 * 自定义控件必须实现的3个方法
	 * */
	public MyView(Context context) {
		super(context);
	}
	public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}
	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	//当线程调用时把bitmap清空
	public void clear(){
		bitmap = null;
	}
	@Override
	protected void onDraw(Canvas canvas) {
		//canvas.drawColor(Color.BLACK);
		width = canvas.getWidth();
		height = canvas.getHeight();
	
			paintColor = paintColors[paintRL.nextInt(5)];
			paint.setColor(paintColor);
			paint.setStrokeWidth(5);
			
			startX = width/2;
			startY = height/2;
			stopX = paintRL.nextInt(width);
			stopY = paintRL.nextInt(height);
			
			if(bitmap == null)//如果bitmap为空,重新创建新的Bitmap.
			{
				bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
				canvas.drawBitmap(bitmap, 0, 0, paint);
			}else
			{	//把线先存放到bitmap中
				tempCanvas = new Canvas(bitmap);
				tempCanvas.drawLine(startX, startY, stopX, stopY, paint);
				//把bitmap中所有的先重新绘制
				canvas.drawBitmap(bitmap, 0, 0, paint);
			}		
	}
}</span>

MainActivity
<span style="font-size:14px;">package com.dewav.draw;

import com.example.view.MyView;

import android.app.Activity;
import android.os.Bundle;


public class MainActivity extends Activity {
	public MyView myView ;
	boolean closeActivity ;
	int  count=1;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		onDrawLine();
	}

	public void onDrawLine()
	{
		myView = (MyView) findViewById(R.id.myView);
		new Thread(){

			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
				while(true)
				{
					if(count>100){
						myView.clear();
						count = 1;
					}
					myView.postInvalidate();
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					count ++;
					if(closeActivity)
					{
						return ;
					}
				}
			}
			
		}.start();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		closeActivity = true;
	}
	
	
}</span>
main_layout:

<span style="font-size:14px;"><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:background="#000000"
    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="com.dewav.draw.MainActivity" >

   <com.example.view.MyView 
        android:id="@+id/myView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
       />

</RelativeLayout></span>

【archerDrewline使用的是控件imageView画线】

mainActivity:
package com.example.archerdrawline;

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.ImageView;


public class MainActivity extends Activity {
	 boolean isQuit = false;
	 boolean clearBitmap = false;
	 int width;
	 int height;
	 int paintColor;
	 int[] paintColors = new int[]{Color.RED,Color.BLUE,Color.YELLOW,Color.GREEN,Color.CYAN};
	 ImageView mImageView;
	 Paint paint;				//画笔
	 Bitmap mBitmap; //保存所有绘画
	 Canvas mCanvas;	//用于画线的画布
	 Random paintRL = new Random();
	 private Handler messageHandler;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mImageView = (ImageView) findViewById(R.id.imageV);
		WindowManager wm = this.getWindowManager();
		width = wm.getDefaultDisplay().getWidth();
		height = wm.getDefaultDisplay().getHeight();
		
		//得到当前线程的Looper实例,由于当前线程是UI线程也可以通过Looper.getMainLooper()得到
		Looper looper = Looper.myLooper();
		 //此处甚至可以不需要设置Looper,因为 Handler默认就使用当前线程的Looper
		messageHandler = new MessageHandler(looper);
		init();
	}
	
	public void init()
	{
		new Thread(){

			@Override
			public void run() {
				super.run();
				int count =0;
				while (true) {
					count++;
					if (count > 1000) {
						// 清屏重新画
						//mBitmap.isRecycled();
						clearBitmap = true;
						count = 0;
					}
					messageHandler.sendEmptyMessage(0);
					try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					//如果退出了 结束线程
					if (isQuit) {
						break;
					}
				}
			}
		}.start();
	}
	
	//创建画图
	public void doDraw(){

		if(clearBitmap)
		{
			mBitmap = null;
			clearBitmap= false;
		}
		//开始点在屏幕中心(get center coordinates)
				float startX = width/2;
				float startY = height/2;
				float stopX = paintRL.nextInt(width);
				float stopY = paintRL.nextInt(height);
		if(mBitmap ==null)
		{
			//创建一个位图用来存放		
			mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
			mImageView.setImageBitmap(mBitmap);
		}else{
			paint = new Paint();//由于没有创建画笔对象,总是报null object reference
			paintColor = paintColors[paintRL.nextInt(5)];
			paint.setColor(paintColor);
			paint.setStrokeWidth(5);
			
			//把线画到bitmap上
			mCanvas = new Canvas(mBitmap);
			mCanvas.drawLine(startX, startY, stopX, stopY, paint);
		}
		//再把bitmap画到canvas上
		mImageView.setImageBitmap(mBitmap);
		/*Message message = Message.obtain();
		message.obj = mBitmap;
		messageHandler.sendMessage(message);*/
	}

	class MessageHandler extends Handler{

		
		public MessageHandler(Looper looper) {
			super(looper);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void handleMessage(Message msg) {
			//mImageView.setImageBitmap((Bitmap)msg.obj);
			doDraw();
		}
		
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		isQuit = true;
	}

}

main_layout:
<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="com.example.archerdrawline.MainActivity" >

<ImageView
    android:id="@+id/imageV"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:background="@drawable/bg"
    />

</RelativeLayout>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值