博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
开关按钮(自定义属性)
阅读量:2397 次
发布时间:2019-05-10

本文共 5685 字,大约阅读时间需要 18 分钟。

onclick 事件在View.onTouchEvent 中被解析。

系统对onclick 事件的解析,过于简陋,只要有down 事件  up 事件,系统即认为 发生了click 事件,所以如果做一些需要触摸到屏幕的操作,要先对click事件进行处理

package com.itheima.togglebtn28;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;public class MyToggleButton extends View implements OnClickListener{	/**	 * 做为背景的图片	 */	private Bitmap backgroundBitmap;	/**	 * 可以滑动的图片	 */	private Bitmap slideBtn;	private Paint paint;	/**	 * 滑动按钮的左边届	 */	private float slideBtn_left;	/**	 * 背景图的资源ID	 */	private int backgroundId;	/**	 * 滑动图片的资源ID	 */	private int slideBtnId;	/**	 * 在代码里面创建对象的时候,使用此构造方法	 */	public MyToggleButton(Context context) {		super(context);		// TODO Auto-generated constructor stub	}	/**	 * 在布局文件中声名的view,创建时由系统自动调用。	 * @param context	上下文对象	 * @param attrs		属性集	 */	public MyToggleButton(Context context, AttributeSet attrs) {		super(context, attrs);				//无命名空间测试		//这种写法应该没有格式区别  都是字符串		//使用资源文件后去的不是id  还是字符串				//使用命名空间其实也是字符串的,只不过通过命名空间能找到,所以就解析		//这个没有命名空间就不解析,就直接显示字符串		String testAttrs = attrs.getAttributeValue(null, "testAttrs");				System.out.println("testAttrs===:"+testAttrs);//@drawable/ic_launcher						//获得自定义的属性		TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyToggleBtn);				int N = ta.getIndexCount();		for (int i = 0; i < N; i++) {			/*			 * 获得某个属性的ID值			 */			int itemId = ta.getIndex(i);			switch (itemId) {			case R.styleable.MyToggleBtn_curr_state:				currState = ta.getBoolean(itemId, false);								break;			case R.styleable.MyToggleBtn_my_background:				backgroundId = ta.getResourceId(itemId, -1);				if(backgroundId == -1){					throw new RuntimeException("请设置背景图片");				}				backgroundBitmap = BitmapFactory.decodeResource(getResources(), backgroundId);								break;			case R.styleable.MyToggleBtn_my_slide_btn:				slideBtnId = ta.getResourceId(itemId, -1);				slideBtn = BitmapFactory.decodeResource(getResources(), slideBtnId);								break;			default:				break;			}					}						initView();	}		/**	 * 初始化	 */	private void initView() {		//通过自定义属性获取了  这里就注释掉了,不需要了		//初始化图片//		backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);//		slideBtn = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button);						//初始化 画笔		paint = new Paint();		paint.setAntiAlias(true); // 打开抗矩齿						//添加onclick事件监听		setOnClickListener(this);				//新增加的 必须刷新 因为获取自定义属性后状态值currState已经发生改变了		flushState();	}	/*	 * view 对象显示的屏幕上,有几个重要步骤:	 * 1、构造方法 创建 对象。	 * 2、测量view的大小。	onMeasure(int,int);	 * 3、确定view的位置 ,view自身有一些建议权,决定权在 父view手中。  onLayout();	 * 4、绘制 view 的内容 。 onDraw(Canvas)	 */		@Override	/**	 * 测量尺寸时的回调方法 	 */	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//		super.onMeasure(widthMeasureSpec, heightMeasureSpec);				/**		 * 设置当前view的大小		 * width  :view的宽度		 * height :view的高度   (单位:像素)		 */		setMeasuredDimension(backgroundBitmap.getWidth(),backgroundBitmap.getHeight());	}	//确定位置的时候调用此方法	//自定义view的时候,作用不大//	@Override//	protected void onLayout(boolean changed, int left, int top, int right,//			int bottom) {//		super.onLayout(changed, left, top, right, bottom);//	}		/**	 * 当前开关的状态	 *  true 为开	 */	private boolean currState = false;		@Override	/**	 * 绘制当前view的内容	 */	protected void onDraw(Canvas canvas) {//		super.onDraw(canvas);				// 绘制 背景		/*		 * backgroundBitmap	要绘制的图片		 * left	图片的左边届		 * top	图片的上边届		 * paint 绘制图片要使用的画笔		 */		canvas.drawBitmap(backgroundBitmap, 0, 0, paint);				//绘制 可滑动的按钮		canvas.drawBitmap(slideBtn, slideBtn_left, 0, paint);	}	/**	 * 判断是否发生拖动,	 * 如果拖动了,就不再响应 onclick 事件	 * 	 */	private boolean isDrag = false;	@Override	/**	 * onclick 事件在View.onTouchEvent 中被解析。	 * 系统对onclick 事件的解析,过于简陋,只要有down 事件  up 事件,系统即认为 发生了click 事件	 * 	 */	public void onClick(View v) {		/*		 * 如果没有拖动,才执行改变状态的动作		 */		if(!isDrag){			currState = !currState;			flushState();		}	}		/**	 * down 事件时的x值	 */	private int firstX;	/**	 * touch 事件的上一个x值	 */	private int lastX;		@Override	public boolean onTouchEvent(MotionEvent event) {		super.onTouchEvent(event);				switch (event.getAction()) {		case MotionEvent.ACTION_DOWN:			firstX = lastX =(int) event.getX();			isDrag = false;						break;		case MotionEvent.ACTION_MOVE:						//判断是否发生拖动			if(Math.abs(event.getX()-firstX)>5){				isDrag = true;			}						//计算 手指在屏幕上移动的距离			int dis = (int) (event.getX() - lastX);						//将本次的位置 设置给lastX			lastX = (int) event.getX();						//根据手指移动的距离,改变slideBtn_left 的值			slideBtn_left = slideBtn_left+dis;			break;		case MotionEvent.ACTION_UP:						//在发生拖动的情况下,根据最后的位置,判断当前开关的状态			if (isDrag) {				int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth(); // slideBtn																					// 左边届最大值				/*				 * 根据 slideBtn_left 判断,当前应是什么状态				 */				if (slideBtn_left > maxLeft / 2) { // 此时应为 打开的状态					currState = true;				} else {					currState = false;				}				flushState();			}			break;		}				flushView();				return true; 	}	/**	 * 刷新当前状态	 */	private void flushState() {		if(currState){			slideBtn_left = backgroundBitmap.getWidth()-slideBtn.getWidth();		}else{			slideBtn_left = 0;		}				flushView(); 	}		/**	 * 刷新当前视力	 */	private void flushView() {		/*		 * 对 slideBtn_left  的值进行判断 ,确保其在合理的位置 即       0<=slideBtn_left <=  maxLeft		 * 		 */				int maxLeft = backgroundBitmap.getWidth()-slideBtn.getWidth();	//	slideBtn 左边届最大值				//确保 slideBtn_left >= 0		slideBtn_left = (slideBtn_left>0)?slideBtn_left:0;				//确保 slideBtn_left <=maxLeft		slideBtn_left = (slideBtn_left

转载于:https://my.oschina.net/u/2356176/blog/422509

你可能感兴趣的文章
今天试vi遇到的“Sorry,the command is not available in this version : syntax on”
查看>>
今天又搞到个libDTL.so is not an ELF file - it has the wrong magic bytes at the start.
查看>>
MinGW和vc6中编译DTL的过程
查看>>
Fedora13下为postgresql添加ODBC驱动过程
查看>>
Bridge模式学习
查看>>
Virtual的一些总结
查看>>
Fedora13上折腾了下ACE
查看>>
tomcat keepAliveTimeout=0问题
查看>>
JDK1.6在SUSE11下问题跳变定时任务失效问题记录
查看>>
400 Bad request 一例
查看>>
linux文件锁定
查看>>
fedora4上安装gcc2.9,编译安装rainbow过程
查看>>
求质数算法的N种境界 (N > 10)
查看>>
一个简单的linux下原生socket的tcp程序及其修改
查看>>
JSP的入门简介
查看>>
JSP中的基本语法和3指令,6动作,9内置对象
查看>>
JSP的6个动作
查看>>
JAVA中的数据类型和方法重载
查看>>
常见面试题——斐波纳挈数列
查看>>
我的第一篇hibernate框架博客
查看>>