android 快速点击两次出现两个重复界面

原地址:http://blog.csdn.net/a394268045/article/details/51548197
项目中遇到快速点击两次时,会出现两个相同界面,

解决办法:
在父类activity中重写事件分发的方法dispatchTouchEvent()
原理:
当在activity中快速点击某个控件,时间间隔不超过300ms,此时activity拦截click事件,这是点击的view将得不到响应,代码如下:

 
一.第一种解决方法
```java
 @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            if (isFastDoubleClick()) {
                return true;
            }
        }
        return super.dispatchTouchEvent(ev);
    }
 
 
    public boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        long timeD = time - lastClickTime;
        lastClickTime = time;
        return timeD <= 300;
    } ```

或者:

public  static final long DEFAULT_TIME = 300;
@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            if (isFastDoubleClick()) {
                return true;
            }
        }
        return super.dispatchTouchEvent(ev);
    }


    public boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        long timeD = time - lastClickTime;
        lastClickTime = time;
        return timeD <= DEFAULT_TIME;
    }

二.第二种解决方法
1.写一个工具类:

public class Utils {
/**
     * @param target      防止多次点击的View
     * @param defaultTime 超时时间
     * @return
     */
    public static boolean isInvalidClick(@NonNull View target, @IntRange(from = 0) long defaultTime) {
        long curTimeStamp = System.currentTimeMillis();
        long lastClickTimeStamp = 0;
        Object o = target.getTag(R.id.invalid_click);
        if (o == null) {
            target.setTag(R.id.invalid_click, curTimeStamp);
            return false;
        }
        lastClickTimeStamp = (Long) o;
        boolean isInvalid = curTimeStamp - lastClickTimeStamp < defaultTime;
        if (!isInvalid) {
            target.setTag(R.id.invalid_click, curTimeStamp);
        }
        return isInvalid;
    }
}

2.在values下,新建一个ids.xml:


```java
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="invalid_click" type="id" />
</resources>

3.在点击事件中调用:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Utils.isInvalidClick(v, 300))
                    return;

                Toast.makeText(MainActivity.this, "hello world!", Toast.LENGTH_SHORT).show();
            }
        });


## 关于android连续点击出现多个Activity界面的解决方法(另一种)

前言

开始始学习android,对android的启动模式没有什么了解,就使用了时间判断是否重复点击了两次按钮,启动另外的activity界面,这样的控制方法,有时候会失效,比如,两秒钟还未启动另外的activity,那么又可以重复点击。所以,就调整为android的启动模式来控制重复出现多个acitvity。
一、通过时间控制点击次数:

这种方式对应控制网络请求不错。

```java
public class NoDoubleClickUtil {   private static long lastClickTime;  private final static int SPACE_TIME =2000;
    public static void initLastClickTime() {
    lastClickTime = 0;   }
    public synchronized static boolean isDoubleClick() {
    long currentTime = System.currentTimeMillis();
    boolean isClickDouble;
    if (currentTime - lastClickTime >
        SPACE_TIME) {
      isClickDouble = false;
    } else {
      isClickDouble = true;
    }
    lastClickTime = currentTime;
    return isClickDouble;   } }

二、通过launchMode启动模式控制出现多个activity的方式:(重要)
这种方式真正意义上杜绝了同时出现相同的多个activity。

或者在代码中设置:
Intent intent = new Intent();
intent.setClass(getApplicationContext(), TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
三、android的四种启动模式:
1、standard模式:每次调用startActivity()启动时都会创建一个新的Activity放在栈顶(默认都是这个模式)

2、singleTop模式:启动Activity时,指定Activity不在栈顶就创建,如在栈顶,则不再创建(不会出现两个相同的Activity相邻)

3、singleTask模式:如果启动的Activity不存在就创建Activity,如果存在直接跳转到指定的Activity所在位置(在其上面的Activity会被移出栈,也就是一个栈中不能有重复的Activity)

4、singleInstance模式:如果启动的Activity不存在就创建一个Activity同时创建一个栈,如果存在就将指定的Activity存在的栈移动到栈顶(表示这个Activity只能存在于一个独立的任务栈中,同应用的其它Activity与其无关)
补充知识:Android中退出多个Activity的两个经典方法

一种把每个activity用集合记住,然后逐一干掉;另一种思路是使用广播。

方法一、用list保存activity实例,然后逐一干掉

创建一个外部类继承Application用来存放activity
public class MyActvity extends Application {
  //创建一个集合,用来存放activity的对象
  ArrayList<Activity>list=new ArrayList<>();
  //声明一个本类的对象
  private static MyActvity instance;
  public MyActvity() {
  }
  //创建一个方法,用来初始化MyActivity的对象,并且初始化的对像的返回
  public synchronized static MyActvity getInstance(){
    if (instance==null){
      instance=new MyActvity();
    }
    return instance;
  }
  //调用此方法用来向集合当中添加activity对象
  public void addActivity(Activity activity){
    list.add(activity);
  }
  //判断activity是否已经在集合当中
  public boolean isexitlist(Activity activity){
    if (list.contains(activity)){
      return true;
    }
    return false;
  }
  //当调用此方法的时候,关闭所有的activity
  public void exit(){
    for (Activity activity:list){
      activity.finish();
    }
    //退出当前的MyActivity
    System.exit(0);
  }
 
  @Override
  public void onLowMemory() {
    super.onLowMemory();
    //当系统的存储空间不够的时候,调用系统的垃圾回收期,清理里面的垃圾
    System.gc();
  }
}

Activity1代码:

public class MainActivity extends AppCompatActivity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //调用存放activity类
    MyActvity instance = MyActvity.getInstance();
    //判断存放activity类是否存放该activity,不存在加入类
    if (!instance.isexitlist(this)){
      instance.addActivity(this);
    }
    Intent intent = new Intent(this, Main2Activity.class);
    startActivity(intent);
  }
}

Activity2代码:

public class Main2Activity extends Activity {
 
  private MyActvity instance;
 
  /**
   * Called when the activity is first created.
   */
 
  @Override+
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sdfa);
    Button bt= (Button) findViewById(R.id.bt);
    instance = MyActvity.getInstance();
    if (!instance.isexitlist(this)){
      instance.addActivity(this);
    }
    bt.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
      //调用exit()方法销毁里面所有activity
        instance.exit();
      }
    });
 
  }
}

方法二、使用广播在activity里注册广播,销毁时启动广播
MainActivity里注册广播:

public class MainActivity extends AppCompatActivity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Intent intent = new Intent(this, Main2Activity.class);
    startActivity(intent);
    //注册广播
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(Define.PAHNAME);
    registerReceiver(new MyReceiver(),intentFilter);
  }
  class MyReceiver extends BroadcastReceiver{
 
    @Override
    public void onReceive(Context context, Intent intent) {
      unregisterReceiver(this);
      ((Activity)context).finish();
    }
  }
}

activity2:启动广播

public class Main2Activity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sdfa);
    Button bt= (Button) findViewById(R.id.bt);
    bt.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        Intent intent = new Intent(Define.PAHNAME);
        sendBroadcast(intent);
        finish();
      }
    });
 
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书中有颜如玉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值