吹毛求疵画图板
因为之前java的画图板只是实现了基础功能,所以我想在android上做一个功能完善的画图板。
我们首先要设计界面,现在主流的android 的界面主要是relative layout 和line layout 相互嵌套使用。
另外在android:onClick="cancel" 可以轻松绑定在主界面MainActivity写的方法,轻松快捷,超好用的有木有。组件一般都是先拖上去再在xml中修改代码。另外在布局中,熟练使用 android:layout_weight="1" 我一般先再xml中先写好,然后再在graphical_layout 拉界面调整比例。
然后今天我还知道了如何更改主界面的theme,在AndroidManifest中的application中选择system resours
这是我的界面图:(4寸一般手机是刚好可以铺开的)
布局格式:先是整体用相对布局然后中间嵌套竖直流布局(充满前面一个组件,既充满整个屏幕),然后再在中间加一个imageView横向充满屏幕,下面再加上一个横向线型布局,中间加上各种按钮组件(全部的权重都设为android:layout_weight="1")。下面是代码:
<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="@drawable/background" tools:context=".MainActivity" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="32.15" android:src="@drawable/backgrand" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal" > <!--onClick绑定点击方法 --> <Button android:id="@+id/line" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="setLine" android:layout_weight="1" android:text="line" /> <Button android:id="@+id/rectangle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="setRect" android:layout_weight="1" android:text="rect" /> <Button android:id="@+id/pen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="setPen" android:layout_weight="1" android:text="pen" /> <Button android:id="@+id/cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="cancel" android:text="cancel" /> <Button android:id="@+id/clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="clear" android:layout_weight="1" android:text="clear" /> </LinearLayout> </LinearLayout> </RelativeLayout>
具体画直线的歩奏这里就先省略。这里为了实现一般画图板的拖动效果,我们首先采用了双缓冲画图技术。就是采用两张Bitmap 用一张bitmap存本来的图,在MotionEvent.ACTION_MOVE:用另一张显示现在正在拖动的的图片。代码如下:
// 如果没有位图,就新建一个 if (bitmap == null) { bitmap = Bitmap.createBitmap(imageView.getWidth(), imageView.getHeight(), Config.ARGB_8888); // 宽,高,第一个alpha 是透明度 后面是3原色 // 实例化一个canvas对象,通过bitmap canvas = new Canvas(bitmap); paint.setStyle(Style.STROKE);//画一个空心的 paint.setColor(Color.RED); paint.setStrokeWidth(5.0f); canvas.drawRect(0, 0, imageView.getWidth(), imageView.getHeight(), paint);//画入新线 //将缓冲图输出 imageView.setImageBitmap(bitmap); } // 获取触控方式 int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: x1=event.getX(); y1=event.getY(); preX=x1; preY=y1; break; case MotionEvent.ACTION_UP: x2=event.getX(); y2=event.getY(); //设置画笔的属性 paint.setColor(Color.BLACK); paint.setStrokeWidth(5.0f); // paint.setStyle(Style.STROKE);//画一个空心的 // paint.setStyle(Style.FILL); //画线 canvas.drawLine(x1, y1, x2, y2, paint); //输出到位图,再镶嵌到线框 line line=new line(); line.setAttribute(1); line.setX1(x1); line.setX2(x2); line.setY1(y1); line.setY2(y2); list.add(line); imageView.setImageBitmap(bitmap); break; case MotionEvent.ACTION_MOVE: x2=event.getX(); y2=event.getY(); //设置一个缓冲位图 Bitmap buffer = Bitmap.createBitmap(imageView.getWidth(), imageView.getHeight(), Config.ARGB_8888); Canvas canvas2 = new Canvas(buffer); //新化一个缓冲图 canvas2.drawBitmap(bitmap, 0, 0, new Paint());//将以前画的全部写入缓冲区 paint.setColor(Color.BLACK); paint.setStrokeWidth(5.0f); canvas2.drawLine(x1, y1, x2, y2, paint);//画入新线 //将缓冲图输出 imageView.setImageBitmap(buffer); break; }
但是运用这种技术,我们发现手机上可能会有一些不流畅的感觉。但是我们只用一个bitmap将之前存在队列中的图形对象,在move行为结束,新的直线即将即将画出来的时候,先将队列中的图形全部画出。这样就不用每move一下就新建一个对象,减少了内存开销。仅提供思路,有时间再去尝试下。
有了画图板,我们还要做到撤销,要做到撤销为了实现撤销的效果我们每一次画的图都要保存在队列里撤销时,我们删除掉最近一个图形,然后再调用子类中的draw方法,将之前的图形画出来。为了实现这个效果,我们首先要有一个父类(用来做画图存储列表),各个图形对象继承这个父类,当每画一个图形,就把这个图形丢到这个队列中去,子类转换为父类。当点击撤销时,先将父类对象取出(不能直接取出子类),,这时因为在存储时子类转换为父类,所以在JAVA中,子类的方法被隐藏了。再强制转换为子类,就可以调用draw的方法,代码如下:
package com.example.drawboard; import android.graphics.Canvas; import android.graphics.Paint; /** * 所有图形的父类 * @author * */ public abstract class paintList { public int getAttribute() { return attribute; } public void setAttribute(int attribute) { this.attribute = attribute; } public float getX1() { return x1; } public void setX1(float x1) { this.x1 = x1; } public float getY1() { return y1; } public void setY1(float y1) { this.y1 = y1; } public float getX2() { return x2; } public void setX2(float x2) { this.x2 = x2; } public float getY2() { return y2; } public void setY2(float y2) { this.y2 = y2; } private int attribute;//属性,1代表1按钮 private float x1,y1,x2,y2; /** * 绘制的方法 * @param g */ public abstract void draw(Canvas canvas,Paint paint);
package com.example.drawboard; import android.graphics.Canvas; import android.graphics.Paint; /** * 直线类 * @author * */ public class line extends paintList{ public line(){ //构造时设置标志位 this.setAttribute(1); } public void draw(Canvas canvas,Paint paint){ canvas.drawLine(this.getX1(), this.getY1(), this.getX2(), this.getY2(), paint); } }
bitmap = Bitmap.createBitmap(imageView.getWidth(), imageView.getHeight(), Config.ARGB_8888); // 宽,高,第一个alpha 是透明度 后面是3原色 // 实例化一个canvas对象,通过bitmap canvas = new Canvas(bitmap); paint.setStyle(Style.STROKE);//画一个空心的 paint.setColor(Color.RED); paint.setStrokeWidth(5.0f); canvas.drawRect(0, 0, imageView.getWidth(), imageView.getHeight(), paint);//画入新线 //将缓冲图输出 if(list.size()!=0){ paint.setColor(Color.BLACK); list.remove(list.size()-1); int total=list.size(); //还原图片 for(int i=0;i<total;i++){ paintList T=list.get(i); //如果是直线的话 if(T.getAttribute()==1){ line line =(line)T; line.draw(canvas, paint); } if(T.getAttribute()==2){ rect rect =(rect)T; rect.draw(canvas, paint); } if(T.getAttribute()==3){ pen pen =(pen)T; System.out.println("hi"); pen.draw(canvas, paint); } } } imageView.setImageBitmap(bitmap);
最后我来讲一下,如何做到做到铅笔的效果,正所谓所见接虚,我们看到的一条曲线实际上也是由许多直线所构成。我们每画一个pen对象我们就在pen对象中加上直线队列。撤销时再一个个重画出来,就有我们想要的效果了。
package com.example.drawboard; import java.util.ArrayList; import android.graphics.Canvas; import android.graphics.Paint; /** * 铅笔类 * @author */ public class pen extends paintList{ public pen(){ //构造时设置标志位 this.setAttribute(3); } //应该有一个队列存储铅笔的轨迹 private ArrayList<line> list=new ArrayList<line>(); public ArrayList<line> getList() { return list; } public void setList(ArrayList<line> list) { this.list = list; } @Override public void draw(Canvas canvas, Paint paint) { // TODO Auto-generated method stub //如果是直线的话 int total=list.size(); for(int i=0;i<total;i++){ line line =list.get(i); line.draw(canvas, paint); } } }
感悟:
命名规则
类名首字母要大写,否则容易与对象名混淆。
另外在android工程中,我们要看到system.out 我们就要在logcat 中 saved filters 旁边的绿色加号按钮,选择要查看的内容的关键字。这点与java不同。
下一篇blog,我就来讲讲自定义组件,如何在画图板上输入文字,以及将这次代码再优化一下。
相关推荐
对发言者的批评应以建设性为主,不要吹毛求疵。最后,除非有紧急情况,否则不应在会议进行中离开,这体现了对团队和会议的尊重。 通过以上要领,我们可以优化会议流程,提升会议效率,创建一个更加专业、有序的会议...
- **关注实质而非细节**:面试官更关注求职者的实质能力,而不是对细节的过分吹毛求疵。过分纠结于小节可能会分散注意力,影响整体表现。 - **大胆自信**:面试时,即使面对抽象或困难的问题,求职者也应自信应对,...
使用 Pop,可以拍照添加触控区,转场方式选择图片,操作平台支持 iOS 和 Android。缺点是分享不便,动画有如侧滑、展开、消失,快现的摇一摇操作只可以单击,沒有控件,所有东西都靠照片。 2. 高保真度;自带控件;...
数据库系统,一个实用的方法提供了一个全面而简明的数据库...作者埃尔维斯·C·福斯特坚持简洁、全面报道和相关性的目标,其务实而有条不紊的讨论风格直指突出问题,避免了不必要的吹毛求疵以及对理论计算的过度渲染。
1.下列句子中,没有错别字且加点字的注音完全正确的一项是( ) A.黄昏,一缕轻烟从烟囱里轻盈地飘出来,地面还留一丝余热。黄昏不像正午那样闷(mèn)热,而是清爽的风中略带一丝暖意。 B.门口那两颗苍翠(cuì)...
1. 语文基础知识 - 词语拼音与字形 在题目中的选择题中,涉及到汉字的正确读音和书写。例如,“拮据(jié)”、“瘠薄(jí)”、“根深蒂固( dì )”、“咬文嚼(jiáo)字”,这些都属于汉语词汇的基础知识,包括汉字...
我在这里耽误了很久 写了很多段程序代码来完整地恢复了这些被打断的数据 (吹毛求疵吧 但我觉得如果在非常严格的数据观察里是有意义的) 程序有时还是有些不知道为什么的BUG 工科人 表达能力不行 分享一个小作品 ...
我在这里耽误了很久 写了很多段程序代码来完整地恢复了这些被打断的数据 (吹毛求疵吧 但我觉得如果在非常严格的数据观察里是有意义的) 程序有时还是有些不知道为什么的BUG 工科人 表达能力不行 分享一个小作品 ...
1. **汉字书写与发音**:此部分考察了学生的拼音识读和汉字书写能力,要求掌握“绚烂”、“喧嚣”、“镌”和“痕”的正确发音和书写。 2. **古诗文积累**:这部分要求学生熟记李白、杜甫等古代诗人的经典诗句,例如...
1. **沉默型客户**:这类客户不喜欢主动发言,因此销售人员需要更积极地引导对话,通过提出开放式问题来挖掘客户需求。 2. **唠叨型客户**:面对这类客户,销售人员应避免让他们主导整个对话,以免偏离销售主题。...
1. **汉字拼音与多音字**: - 在中文中,同一个汉字在不同的语境或词组中可能有不同的读音。题目中提到了“间”、“挨”、“劲”、“舍”四个多音字的例子,强调了在不同情境下正确辨析它们读音的重要性。 - “间...
磋商较量阶段,谈判者需要掌握讨价还价策略,如投石问路、吹毛求疵和暗度陈仓。投石问路是通过提问获取信息;吹毛求疵是通过批评对方来削弱其气势;暗度陈仓则是转移对方注意力以达成自己的目标。此外,让步策略也是...
1. 语文考试:此文档是一个中考语文模拟试卷,主要测试学生的语文基础知识,包括书法鉴赏、诗词默写、注音、文学常识和综合实践活动等方面。 2. 书法艺术:题目涉及到了对一幅书法作品的鉴赏,提到了颜真卿、柳公权...
3. 横挑鼻子竖挑眼——吹毛求疵,找别人的毛病。 4. 好虎架不住群狼——寡不敌众,数量少的一方难以抵挡众多对手。 5. 躲过了风暴又遭雨——祸不单行,不幸的事情接踵而至。 6. 此地无银三百两——欲盖弥彰,试图...
1. 唠叨型客户:这类客户善于表达,可能会占据对话主导权,导致偏离销售主题。应对技巧包括: - 不要给予过多的发言机会,适时引导话题回到产品或服务上。 - 在他们的讲述中寻找插入产品信息的时机,巧妙地将销售...
1. 语文试卷格式:此文档是一份九年级语文期中试题,遵循特定的考试规范,包括分值、时间限制以及答题要求,如使用2B铅笔填涂选择题,用0.5毫米黑色墨水签字笔书写主观题等。 2. 语文基础知识:试题涵盖词语读音、...
1. **审核定义与类型** - 审核定义:为获取审核证据并进行客观评价,以评估是否满足审核准则的系统、独立且形成文件的过程。 - 审核类型分为内部审核(第一方审核)、外部审核(第二方和第三方审核)。内部审核由...
"吹毛求疵"在此为贬义,不适合形容认真负责的态度。 3. 通过师生互动,鼓励学生分享学习心得,共同总结词语运用的规律和误区。 4. 课后布置作业,以同步导练等形式强化词语理解和运用的训练,使学生在实践中不断巩固...
1. 试题中涉及到的基础知识: - 注音:试题检验了学生对汉字读音的掌握,如"晕圈"的"晕"读"yùn","迸溅"的"迸"读"bèng"等,这些都是汉语拼音的基本应用。 - 标点符号使用:考察了学生对标点符号的理解和运用,如...