在刚收到这个任务是,我就想起了Bitmap Canvas Paint这些类。并且发现画线的长短,颜色都是随机的,这也说明了
每次画线时颜色和长短都要随机生成;而线的长短则是由坐标控制的,并且启始坐标是手机屏幕中心。所以我在onCreate()
中使用
WindowManager wm = this.getWindowManager();
int width = wm.getDefaultDisplay().getWidth();
绘图所必须的3个类使用方法自己总结了一下:
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类
MainActivity
【archerDrewline使用的是控件imageView画线】
mainActivity:
main_layout:
传不上资源库,直接貼代码:
【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>