How to Mask Repeated Clicks of View in Android Development Tutorial

  • 2021-10-15 11:34:38
  • OfStack

Preface

android to prevent repeated clicks is a very common requirement. Everyone has their own click event handling habits. Some like to use anonymous internal classes, while others inherit click events such as activity, fragment and custom View, and then implement their own View click events with switch according to id in onClick () method.

In development, we often need such requirements, such as a verification code send button. We only want it to respond to the first click event in 500 milliseconds. What should we do? You might say this is simple. Compare the current time with the last time in the click event, and if it is less than 500 milliseconds, return will drop. Yes, this can be solved, but what if all button-click events in the whole project now require such a requirement? It is impossible to add these lines of code to every click event.

Here, I first put a tool class written in response to the first click, which can realize two modes:

Type 1: No matter which View is clicked, it only responds to the first click Chapter 2: Only the first click is responded on the same View, and there is no influence between different View

public class ClickHelper {

 private static long DELAY = 500L;
 private static long lastTime = 0L;
 private static List<Integer> viewIds = null;
 private static final int SAME_VIEW_SIZE = 10;

 private ClickHelper() {
 }

 public static void setDelay(long delay) {
  ClickHelper.DELAY = delay;
 }

 public static long getDelay() {
  return DELAY;
 }

 public static void onlyFirstIgnoreView(final View target, @NonNull final Callback callback) {
  long nowTime = System.currentTimeMillis();
  if (nowTime - lastTime > DELAY) {
   callback.onClick(target);
   lastTime = nowTime;
  }
 }

 public static void onlyFirstSameView(final View target, @NonNull final Callback callback) {
  long nowTime = System.currentTimeMillis();
  int id = target.getId();
  if (viewIds == null) {
   viewIds = new ArrayList<>(SAME_VIEW_SIZE);
  }
  if (viewIds.contains(id)) {
   if (nowTime - lastTime > DELAY) {
    callback.onClick(target);
    lastTime = nowTime;
   }
  } else {
   if (viewIds.size() >= SAME_VIEW_SIZE) {
    viewIds.remove(0);
   }
   viewIds.add(id);
   callback.onClick(target);
   lastTime = nowTime;
  }
 }

 public interface Callback {
  void onClick(View view);
 }
}

So how can it be effective for all click events of the whole project? My solution is this.

Step 1: Inherit View. OnClickListener Call the tool class in the onClick method to call back to the abstract method. All click events in the project inherit this abstract class


public abstract class OnFirstClickListener implements View.OnClickListener {

 @Override
 public final void onClick(final View v) {
  ClickHelper.onlyFirstSameView(v, new ClickHelper.Callback() {
   @Override
   public void onClick(View view) {
    onFirstClick(view);
   }
  });
 }

 public abstract void onFirstClick(View v);
}

Step 2: Implement the View. OnClickListener interface in the BaseActivity of the project, call the tool class in the onClick method, call back the click event after shielding, and the subclass replicates the onClickWithoutLogin or onClickCheckLogin method. As for why there are two, just look at the name. One verifies the user's login status, only responds to events in the login status, and jumps to the login interface if it is not logged in, which encapsulates one layer more.


/**
 *  When you click an event with an annotation binding, bind the 
 */
@Override
public void onClick(final View v) {
  ClickHelper.onlyFirstSameView(v, new ClickHelper.Callback() {
    @Override
    public void onClick(View view) {
      if (!onClickWithoutLogin(view)) {
        if (UserUtils.doIfLogin(getContext())) {
          onClickCheckLogin(view);
        }
      }
    }
  });
}

/**
 *  Click events that do not require login 
 */
public boolean onClickWithoutLogin(View v) {
  return false;
}

/**
 *  Click events that must be logged in 
 *  If you have logged in, execute it directly. If you have not logged in, jump to the login interface 
 */
public void onClickCheckLogin(View v) {
}

The above is only used in personal development. If you have a better method, please leave a message for discussion.

Summarize


Related articles: