`

吹毛求疵android画图板(1)

阅读更多

吹毛求疵画图板

 因为之前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,我就来讲讲自定义组件,如何在画图板上输入文字,以及将这次代码再优化一下。

 

 

  • 大小: 11.4 KB
分享到:
评论

相关推荐

    公司常用表格模板系列-会议管理要领.doc

    对发言者的批评应以建设性为主,不要吹毛求疵。最后,除非有紧急情况,否则不应在会议进行中离开,这体现了对团队和会议的尊重。 通过以上要领,我们可以优化会议流程,提升会议效率,创建一个更加专业、有序的会议...

    湖北省麻城市张家畈镇中学2020届九年级语文上学期第三次月考试题(无答案) 新人教版.doc

    此外,成语“吹毛求疵”在这里用于错误情境,因为“吹毛求疵”常用于贬义,形容过分挑剔,而非赞美做事认真。 3. 成语和文学常识: 试卷中涉及到成语“不二法门”,表示唯一正确的途径或方法。同时,还提及了《水浒...

    带交互的产品原型可以用什么软件制作?.doc

    使用 Pop,可以拍照添加触控区,转场方式选择图片,操作平台支持 iOS 和 Android。缺点是分享不便,动画有如侧滑、展开、消失,快现的摇一摇操作只可以单击,沒有控件,所有东西都靠照片。 2. 高保真度;自带控件;...

    2020中考语文复习专题二语段综合含解析

    1. 语文基础知识:此部分内容涉及的是中学语文的基础知识,包括汉字的注音和书写。例如,“忠”的注音是“zhōng”,“旁骛”的注音是“páng wù”,“矫揉造作”的注音是“jiǎo róu zào zuò”,“附庸风雅”的...

    Database.Systems_DATABASESYSTEMS_

    数据库系统,一个实用的方法提供了一个全面而简明的数据库...作者埃尔维斯·C·福斯特坚持简洁、全面报道和相关性的目标,其务实而有条不紊的讨论风格直指突出问题,避免了不必要的吹毛求疵以及对理论计算的过度渲染。

    2020中考语文模拟试卷(八).doc

    1.下列句子中,没有错别字且加点字的注音完全正确的一项是( ) A.黄昏,一缕轻烟从烟囱里轻盈地飘出来,地面还留一丝余热。黄昏不像正午那样闷(mèn)热,而是清爽的风中略带一丝暖意。 B.门口那两颗苍翠(cuì)...

    山东省章丘市枣园中学2015届九年级语文上学期期末考试试题 鲁教版

    1. 语文基础知识 - 词语拼音与字形 在题目中的选择题中,涉及到汉字的正确读音和书写。例如,“拮据(jié)”、“瘠薄(jí)”、“根深蒂固( dì )”、“咬文嚼(jiáo)字”,这些都属于汉语词汇的基础知识,包括汉字...

    商务谈判的磋商战略.pptx

    吹毛求疵则是通过挑毛病来获取更好的交易条件;价格诱惑利用价格上涨的预期促使对方快速决策;目标分解是将总目标拆解为各个部分进行逐一议价;润滑策略则是通过人际交往中的小礼物来增进关系,促进谈判顺利进行。 ...

    分享自己的串口接收GUI可实时观察数据图像-(STM32)ADC DMA USART(仅必须的C文件不含工程).rar

    我在这里耽误了很久 写了很多段程序代码来完整地恢复了这些被打断的数据 (吹毛求疵吧 但我觉得如果在非常严格的数据观察里是有意义的) 程序有时还是有些不知道为什么的BUG 工科人 表达能力不行 分享一个小作品 ...

    分享自己的串口接收GUI可实时观察数据图像-MyScomTest可实时显示数据.rar

    我在这里耽误了很久 写了很多段程序代码来完整地恢复了这些被打断的数据 (吹毛求疵吧 但我觉得如果在非常严格的数据观察里是有意义的) 程序有时还是有些不知道为什么的BUG 工科人 表达能力不行 分享一个小作品 ...

    江苏省连云港市灌云县西片九年级语文下学期第一次月考试题-人教版初中九年级全册语文试题.pdf

    1. **汉字书写与发音**:此部分考察了学生的拼音识读和汉字书写能力,要求掌握“绚烂”、“喧嚣”、“镌”和“痕”的正确发音和书写。 2. **古诗文积累**:这部分要求学生熟记李白、杜甫等古代诗人的经典诗句,例如...

    销售技巧销售技巧:怎样抓住客户心理.doc

    1. **沉默型客户**:这类客户不喜欢主动发言,因此销售人员需要更积极地引导对话,通过提出开放式问题来挖掘客户需求。 2. **唠叨型客户**:面对这类客户,销售人员应避免让他们主导整个对话,以免偏离销售主题。...

    高一语文上册第三单元同步检测六[精选].doc

    1. **汉字拼音与多音字**: - 在中文中,同一个汉字在不同的语境或词组中可能有不同的读音。题目中提到了“间”、“挨”、“劲”、“舍”四个多音字的例子,强调了在不同情境下正确辨析它们读音的重要性。 - “间...

    商务谈判磋商策略教材.pptx

    其次,讨价还价阶段的策略运用多样,包括故布疑阵、投石问路、抛砖引玉、吹毛求疵、价格诱惑和目标分解等。故布疑阵是通过提供误导信息影响对方决策;投石问路则是通过试探性的话题探查对方立场;抛砖引玉是通过举例...

    寻找阿托卡之旅:国内量化投资人的生存环境和理想.doc.pdf

    1. **数据准确性**:在资本博弈中,模糊的准确可能导致模糊的不准确,量化投资人需要对数据有近乎吹毛求疵的要求,以避免潜在的错误和误差。 2. **时间投入与回报**:长时间专注于数据处理和校验,能提升团队竞争力...

    (新人教版)九年级语文下册第二单元8热爱生命节选习题课件.ppt

    2. 词语解释:测试学生对词汇的理解,如“巉岩”(chán yán,指陡峭的岩石)、“海市蜃楼”(虚幻的事物)、“吹毛求疵”(刻意找缺点)、“蜿蜒”(wān yán,形容曲折延伸)。 3. 句子修改:第1句是关于语病修正,正确...

    商务谈判的策略课件.pptx

    磋商较量阶段,谈判者需要掌握讨价还价策略,如投石问路、吹毛求疵和暗度陈仓。投石问路是通过提问获取信息;吹毛求疵是通过批评对方来削弱其气势;暗度陈仓则是转移对方注意力以达成自己的目标。此外,让步策略也是...

    江苏省南京市联合体中考语文一模试卷决战中考2021系列.doc

    1. 语文考试:此文档是一个中考语文模拟试卷,主要测试学生的语文基础知识,包括书法鉴赏、诗词默写、注音、文学常识和综合实践活动等方面。 2. 书法艺术:题目涉及到了对一幅书法作品的鉴赏,提到了颜真卿、柳公权...

    ISO内审员培训1(ppt 42).pptx

    他们需要避免吹毛求疵、过于傲慢或冲突,保持公正客观。此外,内审员的工作计划应相对稳定。 内审的有效进行需要领导的重视,管理者代表的参与,建立合格的内审员团队,编制内审程序,并在建立质量体系时考虑到内审...

Global site tag (gtag.js) - Google Analytics