12

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

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

这个问题我能做些什么?

我使用简单的 onClickListeners 和 Buttons

编辑:

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

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 当我像疯子一样点击时,历史堆栈上有多个活动,我必须多次退出。

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

4

8 回答 8

8

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

btn.setOnclickListener(new View.onClickListener(){

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

      }
});
于 2012-07-02T09:03:24.550 回答
5

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

public static void disableTemporarly(final View view) {

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

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

编辑:

上述解决方案将正常工作。但是当使用 Kotlin 的力量时它会变得更好

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)
    }
}

2)添加扩展功能使其适用于任何视图,这将创建一个新的 SafeClickListener 并将工作委托给它

fun View.setSafeOnClickListener(onSafeClick: (View) -> Unit) {

    val safeClickListener = SafeClickListener {
        onSafeClick(it)
    }
    setOnClickListener(safeClickListener)
}

3)现在很容易使用它

settingsButton.setSafeOnClickListener {
    showSettingsScreen()
}

快乐的科特林 ;)

于 2015-05-05T13:43:05.713 回答
4
 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
    }
 });  
于 2017-08-28T11:10:19.590 回答
2

嗯,这是预期的行为......

使用 SINGLE_TOP 标志启动您的新活动

或尝试android:launchMode="singleInstance"在您的 AndroidManifest.xml 中设置 Top20 活动

于 2012-07-02T09:03:38.287 回答
2

这样就解决了activity的多个Instances的问题,并且依然播放默认动画

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
于 2014-05-18T10:53:14.227 回答
0

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

@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!");
    }

}

我在其他帖子上看到了类似的答案,但似乎没有人喜欢这种方法。

于 2016-03-17T21:37:39.350 回答
0

Add the following code snipet to your Activity definition in Androidmanifest.xml

android:launchMode = "singleTask"
于 2016-10-07T11:06:28.767 回答
0

在类内使用frozen变量。Application

那是

public class App extends Application {
public static boolean frozen = false;
}

单击时某处:

//...
onClick() {
if (frozen) {
return;
}
frozen = true
}
//...

在某个地方发布,例如,当新的 Activity 启动时

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" >
于 2016-10-12T07:14:34.103 回答