国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android中如何優(yōu)雅的處理重復(fù)點擊實例代碼

2019-10-21 21:38:42
字體:
供稿:網(wǎng)友

問題

有時候有些操作是防止用戶在一次響應(yīng)結(jié)束中再響應(yīng)下一個。但有些測試用戶就要猛點,狂點。像這種惡意就要進行防止。

比如在客戶端中,一些按鈕一般是需要避免重復(fù)點擊的,比如:購買丶支付丶確定丶提交丶點贊丶收藏等等場景,這些場景短時間內(nèi)的重復(fù)點擊會引發(fā)一些問題.

下面話不多說了,來一起看看詳細的介紹吧

以前的處理方式

可能是采用手動記錄最后的點擊時間,再通過計算時間間隔來判斷是否重復(fù)點擊

 private long mLastClickTime = 0; public static final int TIME_INTERVAL = 1000; private Button mButton; private void initView() { mButton.setOnClickListener(new View.OnClickListener() {  @Override  public void onClick(View v) {  if (System.currentTimeMillis() - mLastClickTime >= TIME_INTERVAL) {   //to do   mLastClickTime = System.currentTimeMillis();  } else {   Toast.makeText(getActivity(), "請勿重復(fù)點擊", Toast.LENGTH_LONG).show();  }  } }); }

或者封裝一下采用抽象處理

public abstract class IClickListener implements View.OnClickListener { private long mLastClickTime = 0; public static final int TIME_INTERVAL = 1000; @Override public final void onClick(View v) { if (System.currentTimeMillis() - mLastClickTime >= TIME_INTERVAL) {  onIClick(v);  mLastClickTime = System.currentTimeMillis(); } else {  onAgain(v); } } protected abstract void onIClick(View v); protected void onAgain(View v) { }}

使用(無需提醒重復(fù)點擊)

 mButton.setOnClickListener(new IClickListener() {  @Override  protected void onIClick(View v) {    } });

或者(需提醒重復(fù)點擊)

        mButton.setOnClickListener(new IClickListener() {
            @Override
            protected void onIClick(View v) {
                
            }

            @Override
            protected void onAgain(View v) {

            }
        });
可以看到經(jīng)過封裝之后,使用起來還是很方便的,但是有幾個缺點

  • 侵入性過大-OnClickListener全部替換為子類IClickListener
  • 不可逆-不能很方便的還原為OnClickListener,因為不是同個回調(diào)
  • 如果是第三方控件則無法處理重復(fù)點擊
  • 只能寫成內(nèi)部類方式-由于單繼承特性,我們只能內(nèi)部類回調(diào),代碼不美觀

優(yōu)雅的處理方式

重復(fù)點擊的問題其實是如何動態(tài)控制原有的點擊事件是否產(chǎn)生,而不是在原有的點擊事件上增強功能;結(jié)合設(shè)計模式可以知道,代理模式可以很好的處理這種問題,而不是繼承.

代理

public class ClickProxy implements View.OnClickListener { private View.OnClickListener origin; private long lastclick = 0; private long timems = 1000; public ClickProxy(View.OnClickListener origin) {  this.origin = origin; } @Override public void onClick(View v) {  if (System.currentTimeMillis() - lastclick >= timems) {   origin.onClick(v);   lastclick = System.currentTimeMillis();  } }}

原先的點擊事件

  mButton.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    //to do   }  });

代理使用

  mButton.setOnClickListener(new ClickProxy(new View.OnClickListener() {   @Override   public void onClick(View v) {    //to do   }  }));

可以看到,原有代碼邏輯沒有改動,只是添加了代理類,這樣大大減小了侵入性

當然還可以擴展一下,提供重復(fù)點擊的回調(diào)和自定義間隔時間,增加一個構(gòu)造函數(shù)

public class ClickProxy implements View.OnClickListener { private View.OnClickListener origin; private long lastclick = 0; private long timems = 1000; //ms private IAgain mIAgain; public ClickProxy(View.OnClickListener origin, long timems, IAgain again) {  this.origin = origin;  this.mIAgain = again;  this.timems = timems; } public ClickProxy(View.OnClickListener origin) {  this.origin = origin; } @Override public void onClick(View v) {  if (System.currentTimeMillis() - lastclick >= timems) {   origin.onClick(v);   lastclick = System.currentTimeMillis();  } else {   if (mIAgain != null) mIAgain.onAgain();  } } public interface IAgain {  void onAgain();//重復(fù)點擊 }}

如何處理第三方View內(nèi)部的點擊事件

可能我們使用一個自定義控件,他的內(nèi)部已經(jīng)消費了點擊事件,但是需要避免重復(fù)點擊,我們不可能去改內(nèi)部的代碼,也不能重新設(shè)置點擊事件,那樣會丟失內(nèi)部的處理邏輯;這時可以采用反射的處理方式,再結(jié)合代理來實現(xiàn)無縫替換

//提供一個靜態(tài)方法public class ClickFilter { public static void setFilter(View view) {  try {   Field field = View.class.getDeclaredField("mListenerInfo");   field.setAccessible(true);   Class listInfoType = field.getType();   Object listinfo = field.get(view);   Field onclickField = listInfoType.getField("mOnClickListener");   View.OnClickListener origin = (View.OnClickListener) onclickField.get(listinfo);   onclickField.set(listinfo, new ClickProxy(origin));  } catch (Exception e) {   e.printStackTrace();  } }}

使用:

 private StateButton mStateButton;//自定義控件 private void initView() {  ClickFilter.setFilter(mStateButton); }

這種動態(tài)替換的方式同樣適合普通場景,在設(shè)置點擊事件后,都可以通過設(shè)置該過濾器來處理重復(fù)點擊(包括butterknife等注解綁定的點擊事件)

最后

Ok.以上就是討論如何優(yōu)雅處理重復(fù)點擊的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網(wǎng)的支持。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 昭觉县| 桃园县| 镇坪县| 鄯善县| 玉屏| 合水县| 郎溪县| 达尔| 桂平市| 威海市| 南昌县| 若尔盖县| 榕江县| 蒲江县| 喀喇| 普兰店市| 合阳县| 漳州市| 仪征市| 油尖旺区| 财经| 本溪市| 宁南县| 噶尔县| 肥西县| 南投市| 隆回县| 德兴市| 筠连县| 东兰县| 常德市| 高青县| 屏东县| 巨野县| 巴里| 通化县| 瓦房店市| 库车县| 临沭县| 富裕县| 北流市|