亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2018年09月13日 09:22:47   作者:uncochen  
這篇文章主要給大家介紹了關(guān)于Android中如何優(yōu)雅的處理重復點擊的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

問題

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

比如在客戶端中,一些按鈕一般是需要避免重復點擊的,比如:購買丶支付丶確定丶提交丶點贊丶收藏等等場景,這些場景短時間內(nèi)的重復點擊會引發(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(), "請勿重復點擊", 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) {

 }
}

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

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

或者(需提醒重復點擊)

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

            @Override
            protected void onAgain(View v) {

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

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

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

重復點擊的問題其實是如何動態(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
   }
  }));

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

當然還可以擴展一下,提供重復點擊的回調(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();//重復點擊
 }
}

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

可能我們使用一個自定義控件,他的內(nèi)部已經(jīng)消費了點擊事件,但是需要避免重復點擊,我們不可能去改內(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è)置該過濾器來處理重復點擊(包括butterknife等注解綁定的點擊事件)

最后

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

相關(guān)文章

最新評論