Android 实现防抖动(防快速点击)的最优雅做法

news/2025/2/7 4:43:59/

前言:

对于很多安卓开发者来说,防快速点击的实现,并不是一件难事。难的是,如何优雅的实现。现在,主流的做法,有自己在onClick方法的顶部加时间判断。也有通过,第三方注解框架去解决。但是,如果你既不想在onClick里面加,又不想用第三方框架,又想以最少的改动,来实现,咋办?干大事的人,都是直接上使用案例的,无Code,无JB。

Here is the code shows you How to use it:

 // 这是findView的代码,但请注意,这不是findViewById,这是findClickView。Button btnTest = findClickView(R.id.btn_test);// 这是Activity的onClick方法。public void onClick(View view) {switch (view.getId()) {case R.id.btn_test:// todobreak;}}

就是这么简单,findClickView方法,会帮你setOnClickListener,并做防抖实现。让我们一起来看看findClickView的内部实现。

    /*** Find出来的View,自带防抖功能*/public <T extends View> T findClickView(int id) {T view = (T) findViewById(id);view.setOnClickListener(new EventListener(this));return view;}

可以看到,这个方法,内部调用的,还是findViewById。不同的是,里面设置onClick的时候,传了一个EventListener的实例。而这个类,也是防抖的关键。废话不多说,直接看代码:

package com.laka.androidlib.listener;import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;import java.lang.reflect.Method;/*** 防抖事件* 用法setOnClickListener(new EventListener(obj));* obj类,必须得有clickMethod(View)方法。默认是onClick(View)方法。*/
public class EventListener implements OnClickListener,OnLongClickListener, OnItemClickListener, OnItemSelectedListener,OnItemLongClickListener {private Object handler;// 点击事件的方法,默认是onClickprivate String clickMethod = "onClick";private String longClickMethod;private String itemClickMethod;private String itemSelectMethod;private String nothingSelectedMethod;private String itemLongClickMethod;// 间隔时间private final static int INTERVAL_TIME = 1000;public EventListener(Object handler) {this.handler = handler;}public EventListener click(String method){this.clickMethod = method;return this;}public EventListener longClick(String method){this.longClickMethod = method;return this;}public EventListener itemLongClick(String method){this.itemLongClickMethod = method;return this;}public EventListener itemClick(String method){this.itemClickMethod = method;return this;}public EventListener select(String method){this.itemSelectMethod = method;return this;}public EventListener noSelect(String method){this.nothingSelectedMethod = method;return this;}public boolean onLongClick(View v) {return invokeLongClickMethod(handler,longClickMethod,v);}public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {return invokeItemLongClickMethod(handler, itemLongClickMethod,arg0,arg1,arg2,arg3);}public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {invokeItemSelectMethod(handler,itemSelectMethod,arg0,arg1,arg2,arg3);}public void onNothingSelected(AdapterView<?> arg0) {invokeNoSelectMethod(handler,nothingSelectedMethod,arg0);}public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {invokeItemClickMethod(handler,itemClickMethod,arg0,arg1,arg2,arg3);}public void onClick(View v) {invokeClickMethod(handler, clickMethod, v);}//上一次点击时间static long lastclicktime=0;/*** 点击事件* @param handler* @param methodName* @param params* @return*/private static Object invokeClickMethod(Object handler, String methodName, Object... params){if(handler == null)return null;Method method = null;try{if(System.currentTimeMillis()-lastclicktime > INTERVAL_TIME){method = handler.getClass().getDeclaredMethod(methodName,View.class);Object result = method.invoke(handler, params);lastclicktime = System.currentTimeMillis();return result;}}catch(Exception e1){handlerException(e1);}return null;}public static void handlerException(Exception e){}/*** 长按事件* @param handler* @param methodName* @param params* @return*/private static boolean invokeLongClickMethod(Object handler, String methodName, Object... params){if(handler == null) return false;Method method = null;try{   //public boolean onLongClick(View v)method = handler.getClass().getDeclaredMethod(methodName,View.class);if(method!=null){Object obj = method.invoke(handler, params);return obj==null?false: Boolean.valueOf(obj.toString());}else{method = handler.getClass().getDeclaredMethod(methodName);if(method!=null){Object obj = method.invoke(handler);return obj==null?false: Boolean.valueOf(obj.toString());}elsethrow new RuntimeException("no such method:"+methodName);}}catch(Exception e){e.printStackTrace();}return false;}private static Object invokeItemClickMethod(Object handler, String methodName, Object... params){if(handler == null) return null;Method method = null;try{   method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class,View.class,int.class,long.class);if(method!=null){if(System.currentTimeMillis()-lastclicktime > INTERVAL_TIME){Object result= method.invoke(handler, params);lastclicktime= System.currentTimeMillis();return result;}}else{method = handler.getClass().getDeclaredMethod(methodName,int.class,long.class);if(method!=null){Object result=  method.invoke(handler, params[2],params[3]);lastclicktime= System.currentTimeMillis();return result;}elsethrow new RuntimeException("no such method:"+methodName);}}catch(Exception e){e.printStackTrace();}return null;}private static boolean invokeItemLongClickMethod(Object handler, String methodName, Object... params){if(handler == null) throw new RuntimeException("invokeItemLongClickMethod: handler is null :");Method method = null;try{   ///onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,long arg3)method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class,View.class,int.class,long.class);if(method!=null){Object obj = method.invoke(handler, params);return Boolean.valueOf(obj==null?false: Boolean.valueOf(obj.toString()));}else{method = handler.getClass().getDeclaredMethod(methodName, int.class,long.class);if(method!=null){Object obj = method.invoke(handler,params[2],params[3]);return Boolean.valueOf(obj==null?false: Boolean.valueOf(obj.toString()));}elsethrow new RuntimeException("no such method:"+methodName);}}catch(Exception e){e.printStackTrace();}return false;}private static Object invokeItemSelectMethod(Object handler, String methodName, Object... params){if(handler == null) return null;Method method = null;try{   ///onItemSelected(AdapterView<?> arg0, View arg1, int arg2,long arg3)method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class,View.class,int.class,long.class);if(method!=null)return method.invoke(handler, params);  elsethrow new RuntimeException("no such method:"+methodName);}catch(Exception e){e.printStackTrace();}return null;}private static Object invokeNoSelectMethod(Object handler, String methodName, Object... params){if(handler == null) return null;Method method = null;try{   //onNothingSelected(AdapterView<?> arg0)method = handler.getClass().getDeclaredMethod(methodName,AdapterView.class);if(method!=null)return method.invoke(handler, params);  elsethrow new RuntimeException("no such method:"+methodName);}catch(Exception e){e.printStackTrace();}return null;}}

代码,复制粘贴,即可用。0 warnings, 0 errors。


好了,到此为止,我们已经讲解了,如何优雅的实现防抖。注意:如果某个View不需要点击事件或防抖,还是用原来的findViewById,不要调这个findClickView,因为findClickView会增加点击事件的监听。


http://www.ppmy.cn/news/826776.html

相关文章

原生JS实现防抖:

防抖&#xff1a;短时间内多次触发&#xff0c;且只执行一次 适用场景&#xff1a;短时间内&#xff0c;多次向服务器发请求&#xff0c;获取数据&#xff0c;如&#xff1a;搜索框、三级分类等 需要理解的知识&#xff1a; 1&#xff1a;函数的执行顺序 2&#xff1a;绑定一…

防抖的实现

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

Android Camera2相机预览画面放大缩小(数码变焦DigitalZoom)功能实现

一、前言 Android自定义相机开发中&#xff0c;常常会有通过手势放大或缩小相机预览画面的需求&#xff0c;即数码变焦DigitalZoom。 二、接口说明 1. 获取最大的放大倍数 float maxZoom mCameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_…

Android开发:控制镜头变焦

特别针对三星盖世相机&#xff1a;EK-GC100 EK-GC110 MainActivity.java package com.example.mytestcamera;import java.io.IOException;import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.os.Bund…

js防抖功能实现

大家好&#xff0c;今天来点有一点点难度的防抖原理实现&#xff0c;今天呢我们要实现的是一个豪华版的防抖&#xff0c;我想想奥&#xff0c;作为一个豪华版的防抖肯定不能只有防抖的功能&#xff0c;假如现在我们有一个输入框搜索的案例&#xff0c;我们使用防抖来进行约束&a…

【Camera】相机防抖

2019独角兽企业重金招聘Python工程师标准>>> 【防抖】 EIS防抖(电子防抖)和光学防抖 EIS(Electronic Image Stabilization)电子防抖主要指数码相机上采用强制提高CCD感光参数、同时加快快门并针对CCD上取得的图像进行分析,然后利用边缘图像进行补偿的防抖,电子…

JS中的防抖

防抖这里两个词可能对一些初入JavaScript的同学比较陌生,那这篇文章主要是针对这些同学们的,浅谈一下防抖 防抖: 1. "防抖"是什么 首先,先去解释一下什么叫做防抖, 在事件被触发n秒后再执行回调&#xff0c;如果在这n秒内又被触发&#xff0c;则重新计时。纯理论是…

关于Android 点击防抖动处理

我们使用app的时候&#xff0c;经常会因为某些原因出现双击的情况&#xff0c;比如点击一个按钮会弹出一个提示框&#xff0c;但是如果我们快速的点击按钮两次&#xff0c;这个时候会出现两个提示框。 双击跟抖动看似一样&#xff0c;其实不是&#xff0c;双击是一个完整的事件…