如何通过在Android中快速点击两次按钮来防止双重代码运行

如何通过在Android中快速点击两次按钮来防止双重代码运行,android,android-button,Android,Android Button,如果我在Android应用程序中快速点击我的按钮,它背后的代码似乎会运行两次。 如果我两次单击菜单按钮,则必须在单击时启动的活动只会启动两次,我必须退出两次 这真的很烦人,因为如果我点击菜单按钮太快,我可以在后台加载一大堆活动,我必须一个接一个地退出,所以这显然是我的应用程序的一个错误状态,我想解决这个问题 我能对这个问题做些什么 我使用简单的onclick监听器和按钮 编辑: 关于答案和评论,我的菜单按钮如下所示: top20Button.setOnClickListener(new OnCl

如果我在Android应用程序中快速点击我的按钮,它背后的代码似乎会运行两次。 如果我两次单击菜单按钮,则必须在单击时启动的活动只会启动两次,我必须退出两次

这真的很烦人,因为如果我点击菜单按钮太快,我可以在后台加载一大堆活动,我必须一个接一个地退出,所以这显然是我的应用程序的一个错误状态,我想解决这个问题

我能对这个问题做些什么

我使用简单的onclick监听器和按钮

编辑:

关于答案和评论,我的菜单按钮如下所示:

top20Button.setOnClickListener(new OnClickListener()
{
    public void onClick(View v)
    {
        favButton.setClickable(false);
        nearButton.setClickable(false);
        highlightedButton.setClickable(false);
        top20Button.setClickable(false);

        Intent i = new Intent();
        i.putExtra("showDialog", false);
        i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        i.setClass(Search.this, Top20.class);
        startActivity(i);
        finish();

    }
});
经过所有这些修正后,它仍然是一样的:S 当我像疯子一样点击时,历史堆栈上有多个活动,我必须多次退出


有什么建议吗?我做错了什么?

您可以使用以下代码:btn.setEnabled(false)

btn.setOnclickListener(new View.onClickListener(){

      public void onClick(View v) {
            btn.setEnabled(false);

      }
});

嗯,这是预期的行为

使用单_顶旗启动您的新Acvity


或者尝试为AndroidManifest.xml中的Top20活动设置
android:launchMode=“singleInstance”
,这解决了多个活动实例的问题,并且仍然播放默认动画

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
android:launchMode = "singleTask"

您可以像这样暂时禁用视图

public static void disableTemporarly(final View view) {

        view.setEnabled(false);
        view.post(new Runnable() {
            @Override
            public void run() {

                view.setEnabled(true);
            }
        });
    }

编辑:

上述解决方案将很好地工作。 但使用科特林的力量会变得更好

1) 创建SafeClikc侦听器

class SafeClickListener(
        private var defaultInterval: Int = 1000,
        private val onSafeCLick: (View) -> Unit
) : View.OnClickListener {

    private var lastTimeClicked: Long = 0

    override fun onClick(v: View) {
        if (SystemClock.elapsedRealtime() - lastTimeClicked < defaultInterval) {
            return
        }
        lastTimeClicked = SystemClock.elapsedRealtime()
        onSafeCLick(v)
    }
}
3) 现在它很容易使用

settingsButton.setSafeOnClickListener {
    showSettingsScreen()
}

快乐的科特林;)

此解决方案更符合我的要求。而是使用启用/禁用视图功能。我使用时间,首先,创建一个变量来存储用户上次按下视图的时间*然后当用户按下视图时,捕获变量中的时间,以便比较当前时刻和用户上次按下视图的时间,如果时间之间的差太小,这意味着速度太快,或者非常快,忽略它,就这样。但是如果这对你来说是一个合理的时间,用当前时间设置最后一个时间变量,然后做你想做的任何事情

@Override
public void onListItemClick(ListView list, View item, int position, long id) {

    Long now = System.currentTimeMillis();
    if((now - lastTimeSelected) > 500){
        lastTimeSelected = now;
        // your code goes here
    } else {
        Log.i(TAG, "Too fast!");
    }

}

我在另一篇文章中看到了类似的内容,但似乎没有人喜欢这种方法。

在Androidmanifest.xml中向您的活动定义添加以下代码snipet

android:launchMode = "singleTask"

应用程序
类中使用
冻结
变量

就是

public class App extends Application {
public static boolean frozen = false;
}
在某处单击:

//...
onClick() {
if (frozen) {
return;
}
frozen = true
}
//...
例如,当新活动启动时,发布的地方

onCreate (...) {
super.onCreate(...);
frozen = false;
}
AndroidManifest.xml
中:

<application
        android:allowBackup="true"
        android:largeHeap="true"
        android:name="com.example.App"
        android:icon="@drawable/icon"
        android:label="@string/app_alias"
        android:theme="@style/AppTheme" >


尝试单击禁用按钮。所以,当它第一次被点击时,它将被禁用,并且不会捕获任何未来的点击,我猜。堆栈上仍然有多个活动,即使只有一个顶部?检查我的更新答案…如果我添加此语句,活动更改时会出现一个奇怪的动画:布局向左移动,出现一个空白屏幕,然后显示我的新活动。由于某些原因,此设置将跳过当前处于以下状态的所有“我的活动”动画:overridePendingTransition(0,0);如果您能告诉我如何禁用此空白屏幕动画,我可以选择您的答案作为问题的答案,因为现在我没有重复的活动。=)在启动活动时尝试添加NO_动画标志:),但它将禁用进一步单击其他,然后如何再次启用?@Miguel:在上面的示例中,在OnClickListener中编写的代码将启动一个活动,因此当用户返回到上一个活动时,它将自动启用。但在其他情况下,如在onClickListener中启动任何异步任务,则onPostExecute()将是再次启用按钮的最佳位置。没有其他方法的复杂性的高效和有效的答案。这应该被接受为答案
 Button.setOnClickListener(new View.OnClickListener {  
   @Override
   public void onClick(final View v) {
        v.setEnabled(false);
        v.postDelayed(new Runnable() {
         @Override
         public void run() {
            v.setEnabled(true);
         }
        },150); //150 is in milliseconds
    }
 });