Android实战简易教程-第三枪(实现简单绘图组件)

首先我们要了解触摸事件(OnTouchListener)指的是当用户接触到屏幕之后所产生的一种事件形式,而当用户在屏幕上划过时,可以使用触摸事件取得用户当前的坐标。

一、坐标显示

在实现画图功能之前,我们先利用触摸事件获得当前触摸的坐标。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

代码非常简单,只引入一个TextView控件,下面看一下MainActivity代码:

package org.yayun.demo;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class MainActivity extends Activity {
	private TextView textView;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState); // 生命周期方法
		super.setContentView(R.layout.main); // 设置要使用的布局管理器
	textView=(TextView)findViewById(R.id.text);
	textView.setOnTouchListener(new OnTouchListener() {//触摸事件

		public boolean onTouch(View v, MotionEvent event) {
			textView.setText("X="+event.getX()+",Y="+event.getY());//获取坐标
			return false;
		}
	});

	}
}

运行实例:

上面可以看到实时获得当前触摸的坐标。

二、实现画图功能

由于OnTouch事件是在View类中定义的,所以如果想要完成绘图的操作,首先应该定义一个属于自己的组件,该组件专门进行绘图板的功能实现,而且组件类一定要继承View类,同时要覆写View类的onDraw()绘图方法。

代码如下:

package org.yayun.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyPaintView extends View{

	private List<Point> allPoints=new ArrayList<Point>();//保存所有的坐标点
	public MyPaintView(Context context, AttributeSet attrs) {
		super(context, attrs);
		super.setBackgroundColor(Color.WHITE);
		super.setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View v, MotionEvent event) {
				Point point=new Point((int)event.getX(),(int)event.getY());
				if(event.getAction()==MotionEvent.ACTION_DOWN){//判断按下
					allPoints=new ArrayList<Point>();//开始新的记录
					allPoints.add(point);
				}else if(event.getAction()==MotionEvent.ACTION_UP){
					allPoints.add(point);
				}else if(event.getAction()==MotionEvent.ACTION_MOVE){
					allPoints.add(point);
					MyPaintView.this.postInvalidate();//重绘
				}
				return true;//表示下面的不再执行了
			}
		});
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Paint paint=new Paint();
		paint.setColor(Color.RED);
		if(allPoints.size()>1){
			Iterator<Point> iterator=allPoints.iterator();
			Point firstPoint=null;//开始点
			Point lastpPoint=null;//结束点
			while (iterator.hasNext()) {
				if(firstPoint==null){//找到开始点
					firstPoint=(Point)iterator.next();
				}else{
					if(lastpPoint!=null){
						firstPoint=lastpPoint;
					}
					lastpPoint=(Point)iterator.next();
					canvas.drawLine(firstPoint.x, firstPoint.y, lastpPoint.x, lastpPoint.y, paint);//画线
				}

			}
		}
		super.onDraw(canvas);
	}

}

修改main.xml,将新建布局引入:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <org.yayun.demo.MyPaintView
        android:id="@+id/paintView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </org.yayun.demo.MyPaintView>

</LinearLayout>

MainActivity不用加入任何东西:

package org.yayun.demo;

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class MainActivity extends Activity {

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState); // 生命周期方法
		super.setContentView(R.layout.main); // 设置要使用的布局管理器

	}
}

运行实例:

总结

1.触摸事件OnTouchListener及onTouch()方法;

2.event.getX()//利用MotionEvent获取坐标的方法getX()

3.onDraw()方法和如何使用Canvas进行绘图的操作,而本次绘制是一条线(canvas.drawLine())。

喜欢的朋友可以关注我!

时间: 2024-08-27 00:16:43

Android实战简易教程-第三枪(实现简单绘图组件)的相关文章

Android实战简易教程-第三十九枪(第三方短信验证平台Mob和验证码自动填入功能结合实例)

用户注册或者找回密码时一般会用到短信验证功能,这里我们使用第三方的短信平台进行验证实例. 我们用到第三方短信验证平台是Mob,地址为:http://mob.com/ 一.注册用户.获取SDK 大家可以自行注册,得到APPKEY和APPSECRET,然后下载SDK,包的导入方式如截图: 二.主要代码 SMSSendForRegisterActivity.java:(获取验证码页) package com.qiandaobao.activity; import java.util.regex.Mat

Android实战简易教程-第三十枪(实例解析Application的用法)

一.Application类 Application和Activity,Service一样是Android框架的一个系统组件,当Android程序启动时系统会创建一个Application对象,用来存储系统的一些信息. Android系统自动会为每个程序运行时创建一个Application类的对象且只创建一个,所以Application可以说是单例(singleton)模式的一个类. 通常我们是不需要指定一个Application的,系统会自动帮我们创建,如果需要创建自己的Application

Android实战简易教程-第三十六枪(监听短信)

一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听手机短信. 一.获取短信全部内容 1.新建一个SMSBroadcastReceiver: <code class="hljs java has-numbering"><span class="hljs-keyword">package</s

Android实战简易教程-第三十七枪(ListView中点击button跳转到拨号界面实例)

最近讨论了一个项目需求,在ListView的Item中放置了一个类似电话的图标,点击图标可以将号码调到拨号界面.实现起来很是容易,原理也易懂,较为实用,项目中有需要的可以直接引入. 我模拟了一个简单的demo.代码如下: 1.ListAdapter.java: package com.example.listviewphone; import java.util.List; import android.content.Context; import android.content.Intent

Android实战简易教程-第三十五枪(将二维码扫描和生成Demo引入项目实例)

网上有很多关于二维码扫码和二维码生成的Demo,你可能不想透彻的了解它是如何实现的,但是你必须要知道如何引入到你的项目之中,我们研究一下如何将这些Demo引入到自己的项目之中. 我也写了一个Demo,看一下它的目录结构. 这些打红色箭头的部分都是必须要复制到你的项目之中的.引入到你的项目之后会有一些报错,你可以根据错误提示进行修改. strings里面有一个字段要加入到你的项目之中 colors.xml中有一些你也要复制过去,还好他们都会报错提醒你. 下面我们看一下Demo的代码: 1.Main

Android实战简易教程-第三十六枪(监听短信-实现短信验证码自动填入)

一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听手机短信. 一.获取短信全部内容 1.新建一个SMSBroadcastReceiver: package com.example.messagecut; import java.text.SimpleDateFormat; import java.util.Date; import android.

Android实战简易教程-第三十八枪(模仿腾讯QQ的网络状态提示和设置功能实现)

项目里要用到一个网络状态判断的功能,想到了QQ的网络状态判断和设置功能,决定模仿一下.实现起来也很是容易,界面较丑,还望原谅. 1.MainActivity.java: package com.example.networktest; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; im

Android实战简易教程-第十三枪(五大布局研究)

我们知道Android系统应用程序一般是由多个Activity组成,而这些Activity以视图的形式展现在我们面前, 视图都是由一个一个的组件构成的.组件就是我们常见的Button.TextEdit等等.那么我们平时看到的Android手机中那些漂亮的界面是怎么显示出来的呢?这就要用到Android的布局管理器了,网上有人比喻的很好:布局好比是建筑里的框架,组件按照布局的要求依次排列,就组成了用于看见的漂亮界面了. 在分析布局之前,我们首先看看控件:Android中任何可视化的控件都是从and

Android实战简易教程-第三十二枪(自定义View登录注册界面EditText-实现一键清空)

自定义View实现登录注册页面的EditText一键清空功能,效果如下: 输入框输入文字后自动出现一键清空键,输入框文字为空时,一键清空键隐藏,下面我们看一下如何通过自定义View实现这一效果. 看一下DeletableEditText.java: package com.example.testview; import android.content.Context; import android.graphics.drawable.Drawable; import android.text.