java tableview 双击_Android 自定义View实现单击和双击事件的方法

本文介绍了如何在Android中通过自定义View来实现单击和双击事件。核心是创建TouchEventCountThread来统计500ms内的点击次数,并用Handler处理点击事件,展示了一个完整的MyView类和相关回调接口。
摘要由CSDN通过智能技术生成

自定义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, 20f, 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统计到的点击次数, 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();

}

}

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

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实现单击和双击事件的方法的全部内容了,希望对大家有所帮助,多多支持脚本之家~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值