今天学习了Android的画板的设计,涉及的内容有Android的Touch事件、Spinner组件的应用,当然还有画板的画布,画笔等相关的知识,下面来说说我的设计过程。
本文的设计主要参照另外一个博主的代码,在他的基础上进行了修改,链接:http://429899791.iteye.com/blog/2196928。
由于原来的博主的代码比较详细,我主要讲的是自己增加或者更改的东西。
更改一:
原来的画板只能在画板上绘制一条线,即提笔之后再次下笔原来的内容就会消失,更改之后可以重复绘制多个线条。
如下代码:
public boolean onTouch(View v, MotionEvent e) { // TODO Auto-generated method stub Point p=new Point((int)e.getX(),(int)e.getY()); if(e.getAction()==e.ACTION_DOWN){ //当按下 pointall=new ArrayList<Point>(); //这里每次按下屏幕便会重新新建一个数组,便会把原来的数组的东西消失 pointall.add(p); }
问题找到了,就此更改,我们把这个的语句去掉,仅仅去掉还不行,我们还要在第二次按下的时候设置一个断点来判定是第二次落笔,如此便能多次绘制线条。主要更改是:
- 去掉pointall=new ArrayList<Point>();
- 新建断点 p=new Point(0,0);
- 新增 if(first.x==0||last.x==0) //判定为断点,用continue语句跳出连接下一个点的语句。
Touch类更改如下:
private class Touch implements OnTouchListener{ @Override public boolean onTouch(View v, MotionEvent e) { // TODO Auto-generated method stub Point p=new Point((int)e.getX(),(int)e.getY()); if(e.getAction()==e.ACTION_DOWN){ //当按下 p=new Point(0,0);//设置断点,来绘制新的线条 pointall.add(p); } else if(e.getAction()==e.ACTION_UP){//当抬起 pointall.add(p); paintview.this.postInvalidate(); //重绘 } else if(e.getAction()==e.ACTION_MOVE){ pointall.add(p); //移动时候 paintview.this.postInvalidate(); //重绘 } return true; } } protected void onDraw(Canvas canvas){ Paint p=new Paint(); //定义画笔 p.setColor(Color.RED); //定义颜色 if(pointall.size()>1){ Iterator<Point> iter=pointall.iterator();// 现在有坐标点保存的时候可以开始进行绘图 Point first=null; Point last=null; while(iter.hasNext()){ if(first==null){ first=(Point)iter.next(); } else{ if(last!=null){ first=last; //将下一个坐标点赋给上面的 } last=(Point)iter.next(); //不停下指 if(first.x==0||last.x==0) //判定为断点,用continue语句跳出连接下一个点的语句 continue; canvas.drawLine(first.x, first.y, last.x, last.y,p); } } } }
更改二:新增画笔颜色和画笔粗细的功能
首先讲一下Spinning下拉框的使用(因为学习的时候上网查这个,感觉很多是混合着其他东西的,看起来比较复杂):
1.设计页面用Spinning标签:
<Spinner android:id="@+id/colortext" android:layout_width="97dp" android:layout_height="match_parent" android:entries="@array/data" android:spinnerMode="dialog" />
2.在res包的values里面新建一个xml文件来存放下拉框内容的数组,data是颜色的内容,data1是笔大小的内容,代码如下:
<?xml version="1.0" encoding="UTF-8"?> <resources> <string-array name="data"> <item>红色</item> <item>蓝色</item> <item>黑色</item> </string-array> <string-array name="data1"> <item>细</item> <item>中</item> <item>粗</item> </string-array> </resources>
3.新建监听事件:
color=(Spinner)findViewById(R.id.colortext); color.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub color1= (String) color.getSelectedItem(); if(color1.equals("红色")) paintview.color1=-1; else if(color1.equals("黑色")) paintview.color1=0; else if(color1.equals("蓝色")) paintview.color1=-2; } @Override public void onNothingSelected(AdapterView<?> parent) { // TODO Auto-generated method stub } });
弄完了相关准备工作,然后就是在原理的代码里面要把颜色和笔大小的属性进行设置,考虑到每次更换笔颜色和大小都会停笔更改,所以把这些属性赋值给断点这里处理,因为前面设置了x坐标来判定是否断点,所以我们利用y坐标来判定设置了什么颜色和大小。
新设置断点信息:
if(e.getAction()==e.ACTION_DOWN){ //当按下 p=new Point(0,color1);//color1是下拉框选择的颜色的值 pointall.add(p); p=new Point(0,pen);//pen是画笔大小的值 pointall.add(p); // pointall =new ArrayList<Point>(); }
增加判断笔颜色和设置大小:
//判断笔的颜色 if(first.y==0)p.setColor(Color.BLACK);//设置为黑色 else if(first.y==-1)p.setColor(Color.RED);//设置为红色 else if(first.y==-2)p.setColor(Color.BLUE);//设置为蓝色 //判断笔大小 if(first.y==-10)p.setStrokeWidth(10);//设置笔大小为10 else if(first.y==-20)p.setStrokeWidth(20);//设置笔大小为20 else if(first.y==-30)p.setStrokeWidth(30);//设置笔大小为30
最终paintview代码如下:
public class paintview extends View{ private List<Point> pointall=new ArrayList<Point>(); static int color1=-1; static int pen=-10; public paintview(Context context, AttributeSet attrs) { super(context, attrs); super.setBackgroundColor(Color.WHITE); super.setOnTouchListener(new Touch()); } private class Touch implements OnTouchListener{ @Override public boolean onTouch(View v, MotionEvent e) { // TODO Auto-generated method stub Point p=new Point((int)e.getX(),(int)e.getY()); if(e.getAction()==e.ACTION_DOWN){ //当按下 p=new Point(0,color1);//color1是下拉框选择的颜色的值 pointall.add(p); p=new Point(0,pen);//pen是画笔大小的值 pointall.add(p); // pointall =new ArrayList<Point>(); } else if(e.getAction()==e.ACTION_UP){//当抬起 pointall.add(p); paintview.this.postInvalidate(); //重绘 } else if(e.getAction()==e.ACTION_MOVE){ pointall.add(p); //移动时候 paintview.this.postInvalidate(); //重绘 } return true; } } protected void onDraw(Canvas canvas){ Paint p=new Paint(); //定义画笔 //定义颜色 if(pointall.size()>1){ Iterator<Point> iter=pointall.iterator();// 现在有坐标点保存的时候可以开始进行绘图 Point first=null; Point last=null; while(iter.hasNext()){ if(first==null){ first=(Point)iter.next(); } else{ if(last!=null){ first=last; //将下一个坐标点赋给上面的 } last=(Point)iter.next(); //不停下指 //判断笔的颜色 if(first.y==0)p.setColor(Color.BLACK);//设置为黑色 else if(first.y==-1)p.setColor(Color.RED);//设置为红色 else if(first.y==-2)p.setColor(Color.BLUE);//设置为蓝色 //判断笔大小 if(first.y==-10)p.setStrokeWidth(10);//设置笔大小为10 else if(first.y==-20)p.setStrokeWidth(20);//设置笔大小为20 else if(first.y==-30)p.setStrokeWidth(30);//设置笔大小为30 if(first.x==0||last.x==0) continue; // p.setStrokeWidth(10); canvas.drawLine(first.x, first.y, last.x, last.y,p); } } } } }
MainActivity代码如下:
public class MainActivity extends Activity { private Spinner color; private Spinner pen; public String color1="红色"; private String pen1="细"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //监听得到画笔的颜色 color=(Spinner)findViewById(R.id.colortext); color.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub color1= (String) color.getSelectedItem(); if(color1.equals("红色")) paintview.color1=-1; else if(color1.equals("黑色")) paintview.color1=0; else if(color1.equals("蓝色")) paintview.color1=-2; } @Override public void onNothingSelected(AdapterView<?> parent) { } }); //监听得到画笔的大小 pen=(Spinner)findViewById(R.id.pentext); pen.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // TODO Auto-generated method stub pen1= (String) pen.getSelectedItem(); if(pen1.equals("细")) paintview.pen=-10; else if(pen1.equals("中")) paintview.pen=-20; else if(pen1.equals("粗")) paintview.pen=-30; } @Override public void onNothingSelected(AdapterView<?> parent) { // TODO Auto-generated method stub } });}
最终效果如下:
最后提一下这次新学的一个知识,就是paintview的类可以直接嵌入MainActivity里面,这样画板会填充到主页面里面,这样不需要这个类新建一个xml文件来做页面,只要在activity_main加上如下声明:
<com.example.paint.paintview android:id="@+id/paintview" android:layout_width="fill_parent" android:layout_height="fill_parent" />