自定义view,
1. 自定义一个Runnable线程touchEventCountThread, 用来统计500ms内的点击次数
2. 在MyVIEw中的 ontouchEvent 中调用 上面的线程
3. 自定义一个Handler,在touchEventHandler 中 处理 统计到的点击事件,单击,双击,三击,都可以处理
核心代码如下:
public class MyVIEw extends VIEw { ...... // 统计500ms内的点击次数 touchEventCountThread mIntouchEventCount = new touchEventCountThread(); // 根据touchEventCountThread统计到的点击次数,perform单击还是双击事件 touchEventHandler mtouchEventHandler = new touchEventHandler(); @OverrIDe public boolean ontouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (0 == mIntouchEventCount.touchCount) // 第一次按下时,开始统计 postDelayed(mIntouchEventCount,500); break; case MotionEvent.ACTION_UP: // 一次点击事件要有按下和抬起,有抬起必有按下,所以只需要在ACTION_UP中处理 mIntouchEventCount.touchCount++; // 如果是长按 *** 作,则Handler的消息,不能将touchCount置0,需要特殊处理 if(mIntouchEventCount.isLongClick) { mIntouchEventCount.touchCount = 0; mIntouchEventCount.isLongClick = false; } break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_CANCEL: break; default: break; } return super.ontouchEvent(event); } public class touchEventCountThread implements Runnable { public int touchCount = 0; public boolean isLongClick = false; @OverrIDe public voID run() { Message msg = new Message(); if(0 == touchCount){ // long click isLongClick = true; } else { msg.arg1 = touchCount; mtouchEventHandler.sendMessage(msg); touchCount = 0; } } } public class touchEventHandler extends Handler { @OverrIDe public voID handleMessage(Message msg) { Toast.makeText(mContext,"touch " + msg.arg1 + " time.",Toast.LENGTH_SHORT).show(); } } ......}
包装以后如下,这样就能在别的地方调用了:
public interface ondoubleclickListener{ voID ondoubleclick(VIEw v); } private ondoubleclickListener mondoubleclickListener; public voID setondoubleclickListener(MyVIEw.ondoubleclickListener l) { mondoubleclickListener = l; } public boolean performDoubleClick() { boolean result = false; if(mondoubleclickListener != null) { mondoubleclickListener.ondoubleclick(this); result = true; } return result; } public class touchEventHandler extends Handler { @OverrIDe public voID handleMessage(Message msg) { if(2 == msg.arg1) performDoubleClick(); } }
在Activity中使用:
myVIEw1.setondoubleclickListener(new MyVIEw.ondoubleclickListener() { @OverrIDe public voID ondoubleclick(VIEw v) { Toast.makeText(mContext,"double click",Toast.LENGTH_SHORT).show(); }});
全部代码
MyVIEw.java
package com.carloz.test.myapplication.vIEw;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.os.Handler;import androID.os.Message;import androID.util.AttributeSet;import androID.vIEw.MotionEvent;import androID.vIEw.VIEw;import androID.Widget.Toast;import com.carloz.test.myapplication.R;/** * Created by root on 15-11-9. */public class MyVIEw extends VIEw { private Paint mPaint = new Paint(); private boolean mNotDestroy = true; private int mCount = 0; private MyThread myThread; Bitmap bitmap; // attrs private String mText; private boolean mStartChange; Context mContext; public MyVIEw(Context context) { super(context); init(); } public MyVIEw(Context context,AttributeSet attrs) { super(context,attrs); TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyVIEw); mText = ta.getString(R.styleable.MyVIEw_text); mStartChange = ta.getBoolean(R.styleable.MyVIEw_startChange,false); // Log.d("ASDF","mText=" + mText + ",mStartChange=" + mStartChange); ta.recycle(); init(); } @OverrIDe protected voID onFinishInflate() { super.onFinishInflate(); } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); } @OverrIDe protected voID onLayout(boolean changed,int left,int top,int right,int bottom) { super.onLayout(changed,left,top,right,bottom); } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setTextSize(50); canvas.drawText(mText + mCount++,20f,100f,mPaint); canvas.save(); canvas.rotate(60,getWIDth() / 2,getHeight() / 2); canvas.drawBitmap(bitmap,50f,mPaint); canvas.restore(); if (null == myThread) { myThread = new MyThread(); myThread.start(); } } @OverrIDe public boolean dispatchtouchEvent(MotionEvent ev) { return super.dispatchtouchEvent(ev); } @OverrIDe protected voID onAttachedToWindow() { super.onAttachedToWindow(); mNotDestroy = true; } @OverrIDe protected voID onDetachedFromWindow() { mNotDestroy = false; super.onDetachedFromWindow(); } // 统计500ms内的点击次数 touchEventCountThread mIntouchEventCount = new touchEventCountThread(); // 根据touchEventCountThread统计到的点击次数,Toast.LENGTH_SHORT).show(); } } class MyThread extends Thread { @OverrIDe public voID run() { super.run(); while (mNotDestroy) { if (mStartChange) { postInvalIDate(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printstacktrace(); } } } } } public voID init() { mContext = getContext(); bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher); } public voID setText(String mText) { this.mText = mText; } public voID setStartChange(boolean mStartChange) { this.mStartChange = mStartChange; } public boolean getStartChange() { return this.mStartChange; }}
attrs.xml
<?xml version="1.0" enCoding="utf-8"?><resources> <declare-styleable name="MyVIEw"> <attr name="text" format="string"/> <attr name="startChange" format="boolean"/> </declare-styleable></resources>
postDelayed方法最终是靠 Handler 的 postDelayed 方法 实现原理如下
public final boolean postDelayed(Runnable r,long delayMillis) { return sendMessageDelayed(getPostMessage(r),delayMillis); } public final boolean sendMessageDelayed(Message msg,long delayMillis) { if (delayMillis < 0) { delayMillis = 0; } return sendMessageAtTime(msg,SystemClock.uptimeMillis() + delayMillis); } public boolean sendMessageAtTime(Message msg,long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper",e.getMessage(),e); return false; } return enqueueMessage(queue,msg,uptimeMillis); // 然后在MessageQueue中会比较时间顺序 }
以上就是小编为大家带来的AndroID 自定义view实现单击和双击事件的方法的全部内容了,希望对大家有所帮助,多多支持编程小技巧~
总结以上是内存溢出为你收集整理的Android 自定义View实现单击和双击事件的方法全部内容,希望文章能够帮你解决Android 自定义View实现单击和双击事件的方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)