android 自定义view,绘制与onTouchEvent事件(一)

绘制

构造方法

自定义view需要继承View类,重写两个构造方法

	//用在代码new该view对象,初始化
	public MyView(Context context) {
		super(context);
		init();
	}

	//一般添加构造---》view放进布局,系统实例化
	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

Paint对象

绘制view需要使用Paint对象,相当于画笔。初始化需要给这个画笔设置一些属性。

对Paint实例化,注释写的很清楚了,有三个常用的初始化方法:

	private void init() {
		paint=new Paint();
		//设置画笔的颜色
		paint.setColor(Color.GREEN);
		//抗锯齿,画图质量提高
		paint.setAntiAlias(true);
		//设置画笔样式,空心
		paint.setStyle(Style.STROKE);
	}

重写onDraw()

常用图像绘制

要画图形,最起码要有三个对象:

1.颜色对象 Color

2.画笔对象 Paint

3.画布对象 Canvas

为了绘制自定义View,需要重写onDraw()方法,参数:(Canvas canvas)是个画布对象,就是在这个canvas绘制的。

以下展示了绘制矩形,圆形,文本,图片,直线,弧线的过程,其中弧线的绘制过程依赖于矩形,这个有点有别于其他的。

	//声明矩形对象(为了绘制弧线)
	private RectF rectF;
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		rectF=new RectF(10, 10, 70, 60);//实例化矩形
		//画矩形
<span style="white-space:pre">		</span>//canvas.drawRect(10, 10, 70, 60, paint);两种方式,如果第一句没有声明RecF,就要按多个参数的构造方法绘制。<span style="white-space:pre">			</span>
		canvas.drawRect(rectF, paint);

		//画弧线
		canvas.drawArc(rectF, 0, 290, true, paint);

		//画圆:参数1、2:圆心的坐标     参数3:半径
		canvas.drawCircle(100, 100, 30, paint);

		//画图片<span style="white-space:pre">			</span>图片资源<span style="white-space:pre">					</span>图片左上角的坐标(X,Y)
		canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher), 200, 200, paint);

		//画文本<span style="white-space:pre">	</span>文本左上角的坐标
		canvas.drawText("nihaohao", 200, 300, paint);

		//画线<span style="white-space:pre">	</span>起点坐标 重点坐标 paint对象
		canvas.drawLine(205, 305, 255, 355, paint);
	}

画<shape>对象

Shape对象的绘制

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <size android:width="60px"
        android:height="60px"></size>
    <stroke
        android:color="#ff0000"
        android:width="2px"></stroke>
    <gradient
        android:startColor="#ff0000"
        android:centerColor="#00ff00"
        android:endColor="#0000ff"></gradient>
</shape>

初始化方法初始drawable,这个get到的是一个Drawable对象

	private void init() {
		drawable = getResources().getDrawable(R.drawable.cir);
	}

ondraw()方法里,注释已经很清楚了

	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 设置 drawable bounds 指定 x,y

		Rect bounds = drawable.getBounds();
		bounds.left = (int)x;
		bounds.top = (int)y;
		bounds.right = bounds.left + 60;//只是保证离边界有一定距离
		bounds.bottom =bounds.top + 60;

		drawable.setBounds(bounds);
		//画到canvas上
		drawable.draw(canvas);
	}

画Bitmap对象

init()方法里

bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

onDraw()方法里,需要注意的是,drawBitmap()方法里传的参数,参数一:bitmap对象参数二:bitmap左上角x坐标
参数三:bitmap左上角y坐标。所以如果想要坐标指定在图片中间,需要x-bitmap.getWidth()/2, y-bitmap.getHeight()/2。这样做的好处是:在onTouchEvent()事件中,定义的x,y坐标可以定在图片中间,完成一定的手势动作。

canvas.drawBitmap(bitmap, x-bitmap.getWidth()/2, y-bitmap.getHeight()/2, paint);

还要注意:顺序不要反了。是在canvas(画布)上画,而不是这个canvas画别的对象。canvas都是处在一个被动的角度。

OnTouchEvent

这个方法响应了触摸屏幕发生的事件,包括按下、抬起、移动等等,都可以被监听到。

可以实现一定的拖动,绘图功能。通过event能get到这些动作和当前X,Y坐标等等。

public boolean onTouchEvent(MotionEvent event) {
//这个方法里往往需要重绘界面,使用这个方法可以自动调用onDraw()方法。(主线程)
	invalidate();
//非UI线程用
	postInvalidate();
	//使系统响应事件,返回true
	return true;
}

三种事件的判断和处理方式:

	public boolean onTouchEvent(MotionEvent event) {

		//获取手指在屏幕上的坐标
		float x = event.getX();
		float y = event.getY();

		//获取手指的操作--》按下、移动、松开
		int action = event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN://按下
			Log.i(TAG, "ACTION_DOWN");
			break;

		case MotionEvent.ACTION_MOVE://移动
			Log.i(TAG, "ACTION_MOVE");
			break;
		case MotionEvent.ACTION_UP://松开
			Log.i(TAG, "ACTION_UP");
			break;
		}
		return true;
	}

并且通过X,Y坐标可以判断滑动的方向,从而做出一些判断,可以响应动画,ScrollView的滑动等等,可以做的事情非常多。但是一些复杂的手势操作,需要用Android的Gesturedetector。例如双击、fling等较为复杂的手势。这个类过两天再总结。在处理触摸事件时,activity首先会响应onTouchEvent()。

一个Demo:画板

public class WritePadView extends View{

	//视图放置在布局中,,,实例化
	public WritePadView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	//代码new控件
	public WritePadView(Context context) {
		super(context);

		init();
	}
	private void init() {
		linesX=new ArrayList<ArrayList<Float>>();
		linesY=new ArrayList<ArrayList<Float>>();

		paint=new Paint();

		//设置颜色
		paint.setColor(Color.GREEN);

		//设置抗锯齿
		paint.setAntiAlias(true);

		//设置画笔的样式
		paint.setStyle(Style.FILL);

	}
	//绘制视图
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		for(int j=0;j<linesX.size();j++){

			//连点成线    3
			for(int i=0;i<linesX.get(j).size()-1;i++){
				canvas.drawLine(linesX.get(j).get(i), linesY.get(j).get(i),linesX.get(j).get(i+1), linesY.get(j).get(i+1), paint);
			}
		}
	}
	/**两个集合--》记录手指的轨迹的点---》一个线段*/
	private ArrayList<Float> xs , ys;
	private Paint paint;

	//装所有线段的集合
	private List<ArrayList<Float>> linesX,linesY;

	//手指触摸屏幕
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		//获取手指的位置
		float x = event.getX();
		float y = event.getY();

		if(event.getAction()==MotionEvent.ACTION_DOWN){//按下--》一个新的线段开始了

			xs=new ArrayList<Float>();
			ys=new ArrayList<Float>();

			linesX.add(xs);
			linesY.add(ys);

		}

		//把手指的位置记录下来
		xs.add(x);
		ys.add(y);

		//通知视图重绘制、
		invalidate();
		return true;
	}
}

自定义View加载到视图

在布局xml里,使用自定义视图要用 包名.类名引用。

    <com.bless.myViewDemo.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

附Paint对象一些属性方法:

Paint:

void setARGB(int a, int r, int g, int b) 设置Paint对象颜色,参数一为alpha透明通道

void setAlpha(int a) 设置alpha不透明度,范围为0~255

void setAntiAlias(boolean aa) //是否抗锯齿

void setColor(int color) //设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义

void setFakeBoldText(boolean fakeBoldText) //设置伪粗体文本

void setLinearText(boolean linearText) //设置线性文本

PathEffect setPathEffect(PathEffect effect) //设置路径效果

Rasterizer setRasterizer(Rasterizer rasterizer) //设置光栅化

Shader setShader(Shader shader) //设置阴影

void setTextAlign(Paint.Align align) //设置文本对齐

void setTextScaleX(float scaleX) //设置文本缩放倍数,1.0f为原始

void setTextSize(float textSize) //设置字体大小

Typeface setTypeface(Typeface typeface) //设置字体,Typeface包含了字体的类型,粗细,还有倾斜、颜色等。

void setUnderlineText(boolean underlineText) //设置下划线

附Canvas属性

Canvas:

void drawRect(RectF rect, Paint paint) //绘制区域,参数一为RectF一个区域

void drawPath(Path path, Paint paint) //绘制一个路径,参数一为Path路径对象

void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //贴图,参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在 canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。

void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) //画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint画刷对象。

void drawPoint(float x, float y, Paint paint) //画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。

void drawText(String text, float x, float y, Paint paint) //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。

void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) //在路径上绘制文本,相对于上面第二个参数是Path路径对象

附录的原博地址:http://blog.csdn.net/listening_music/article/details/6859229

时间: 2024-10-09 13:18:19

android 自定义view,绘制与onTouchEvent事件(一)的相关文章

Android自定义View绘制闹钟

Android自定义View绘制闹钟 本文简单实现了一个闹钟,扩展View,Canvas绘制 效果如下: 代码如下: package com.gaofeng.mobile.clock_demo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.gr

android自定义View绘制圆形头像与椭圆头像

要实现这两种效果,需要自定义View,并且有两种实现方式. 第一种: public class BitmapShaders extends View { private  BitmapShader bitmapShader = null; private Bitmap bitmap = null; private Paint paint = null; private ShapeDrawable shapeDrawable = null; private int BitmapWidth  = 0

关于Android自定义View中的onTouchEvent(MotionEvent event)事件监听

今天做一个自定义ViewGroup,通过addView动态添加子控件,为了省事,直接在父控件里重写public boolean onTouchEvent(MotionEvent event){}方法来监听当前触碰是哪个按钮,遇到点问题,所以写下来. 首先是点击效果只有 MotionEvent.ACTION_DOWN,这个把返回改为return true;就行了 然后是 getX()和getRawX()的区别,这个这篇博文有写到 http://www.cnblogs.com/foura/artic

Android 自定义View——自定义点击事件

每个人手机上都有通讯录,这是毫无疑问的,我们通讯录上有一个控件,在通讯录的最左边有一列从"#"到"Z"的字母,我们通过滑动或点击指定的字母来确定联系人的位置,进而找到联系人.我们这一节就通过开发这个控件,来学如何自定义控件的点击事件. 通讯录列表查找控件界面绘制 首先我们需要先将控件的基本布局绘制出来,这里我们不在做详细的解释,在<Android 自定义View--自定义View控件 >博客中,我们已经详细讲解了如何绘制自定义控件的布局.通讯录列表查找控

【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五)Android事件分发机制(上)Touch三个重要方法的处理逻辑][下文简称(五),请先阅读完(五)再阅读本文],我们通过示例和log来分析了Android的事件分发机制.这些,我们只是看到了现象,如果要进一步了解事件分发机制,这是不够的,我们还需要透过现象看本质,去研究研究源码.本文将从源码(基

Android应用自定义View绘制方法手册

背景 这篇迟迟难产的文章算是对2015前半年的一个交代吧,那时候有一哥们要求来一发Android Canvas相关总结,这哥们还打赏了,实在不好意思,可是这事一放就给放忘了,最近群里小伙伴催着说没更新博客,坐等更新啥的,随先有这么一篇Android应用开发超级基础的文章诞生了(因为这种文章最好写哈,就是用熟了就行).不得不说下这么久为何一直没更新博客的原因了,首先遇上了过年,我个人崇尚过节就该放下一切好好陪陪亲人,珍惜在一起的时光:其次今年开年很是蛋疼,不是不顺当就是深深的觉得被坑,所以心情也就

Android自定义View【实战教程】5??---Canvas详解及代码绘制安卓机器人

友情链接: Canvas API Android自定义View[实战教程]3??--Paint类.Path类以及PathEffect类详解 神马是Canvas 基本概念 Canvas:可以理解为是一个为我们提供了各种工具的画布,我们可以在上面尽情的绘制(旋转,平移,缩放等等).可以理解为系统分配给我们一个一个内存空间,然后提供了一些对这个内存空间操作的方法(API), 实际存储是在下面的bitmap. 两种画布 这里canvas可以绘制两种类型的画图,分别是view和surfaceView. V

Android自定义view之绘制实用型的柱形图和折线图

概述: 前几天突然需要做两种图表--柱形图.折线图,于是第一反应是先看看网上有没有现成的,结果有是有,但都不是我想要的,而且大多数不是用纯android代码完成,HTML5似乎完成这类工作要容易得多,但是我本人并不会HTML5,只能黯然神伤,掩面流泪,最终只能自己敲代码了. **知识点:**android自定义view.图形图像.Fragment.MVC模式. Demo 界面是模仿红圈营销搭建的 折线图: 代码,注释很详细,直接看代码就行了: public class LineChartView

Android自定义View(CustomCalendar-定制日历控件)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeasure 4onDraw 绘制月份 绘制星期 绘制日期及任务 5事件处理 源码下载 ??应项目需求,需要做一个日历控件,效果图如下: ???? ??接到需求后,没有立即查找是否有相关开源日历控件可用.系统日历控件是否能满足 ,第一反应就是这个控件该怎么画?谁叫咱自定义控件技术牛逼呢O(∩_∩)O哈哈~

android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索

我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的Android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体上来说,左边是一个ListView,右边是一个自定义View,但是左边的ListView和我们平常使用的ListView还有一点点不同,就是在ListView中我对所有的联系人进行了分组,那么这种效果的实现最常见的就是两种思路: 1.使用ExpandableListView来实现这种分组效果 2.使