如何在android中同时避免多个按钮点击?

Mur*_*san 42 android button onclicklistener

我正在使用两个按钮.同时单击两个按钮时,它将一次进入不同的活动.怎么避免这个?

我试过这样的,但它不起作用请保存....

public class MenuPricipalScreen extends Activity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.menu_principal_layout);


    findViewById(R.id.imageView2).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub

            disable(findViewById(R.id.imageView3));

            Intent intent = new Intent(MenuPricipalScreen.this,
                    SelectYourLanguageVideo.class);
            startActivity(intent);
        }
    });
    findViewById(R.id.imageView3).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub

            disable(findViewById(R.id.imageView2));

            Intent intent = new Intent(MenuPricipalScreen.this,
                    CategoryScreen.class);
            intent.putExtra("request", "false");
            startActivity(intent);
        }
    });

}

 @Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    ((ImageView) findViewById(R.id.imageView3)).setEnabled(true);
    ((ImageView) findViewById(R.id.imageView2)).setEnabled(true);
    ((ImageView) findViewById(R.id.imageView3)).setClickable(true);
    ((ImageView) findViewById(R.id.imageView2)).setClickable(true);
    ((ImageView) findViewById(R.id.imageView3)).setFocusable(true);
    ((ImageView) findViewById(R.id.imageView2)).setFocusable(true);
}

 private void disable(View v) {
    Log.d("TAG", "TAG" + v.getId());
    v.setEnabled(false);
    v.setClickable(false);
    v.setFocusable(false);
}
}
Run Code Online (Sandbox Code Playgroud)

谢谢,

Shi*_*rur 102

避免多次点击的标准方法是保存最后点击的时间,并避免在1秒(或任何时间跨度)内点击其他按钮.例:

// Make your activity class to implement View.OnClickListener
public class MenuPricipalScreen extends Activity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // setup listeners.
        findViewById(R.id.imageView2).setOnClickListener(MenuPricipalScreen.this);
        findViewById(R.id.imageView3).setOnClickListener(MenuPricipalScreen.this);
        ...
     }

    .
    .
    .

    // variable to track event time
    private long mLastClickTime = 0;

    // View.OnClickListener.onClick method defination

    @Override
    public void onClick(View v) {
        // Preventing multiple clicks, using threshold of 1 second
        if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) {
            return;
        }
        mLastClickTime = SystemClock.elapsedRealtime();

        // Handle button clicks
        if (v == R.id.imageView2) {
            // Do your stuff.
        } else if (v == R.id.imageView3) {
            // Do your stuff.
        }
        ...
    }

    .
    .
    .

 }
Run Code Online (Sandbox Code Playgroud)

  • 它根本不优雅,也不是很棒.这是一个非常肮脏的黑客. (44认同)
  • @MohammadZekrallah先生这里有什么难看的?如果您对Java有一些了解,甚至Reactive java内部使用相同的逻辑进行观察者模式.如果您有任何其他解决方案,为什么不能在这里分享?毕竟它是分享想法和帮助他人的平台. (9认同)
  • 你为什么不给?@iharob? (5认同)
  • 这怎么可能是辉煌的?这是一种hacky脏的不可重复使用的方式! (3认同)

小智 43

您可以使用此功能android:splitMotionEvents="false"android:windowEnableSplitTouch="false"在主题中禁用应用中的多点触控功能.

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    ...
    <item name="android:splitMotionEvents">false</item>
    <item name="android:windowEnableSplitTouch">false</item>
</style>
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用,我添加到我的应用程序样式和活动样式中,但仍然双击执行 (4认同)
  • 我们可以仅针对特定视图而不是应用级别执行此操作吗? (2认同)

Mar*_*ini 7

便宜的解决方案:

您没有正确的关注点分离(MVP或任何形式),因此您将代码放在“活动/片段”中

  • 如果您无法正确处理此问题,至少不要使用不确定性解决方案(例如计时器)。

  • 使用您已有的工具,说您有以下代码:


//Somewhere in your onCreate()
Button myButton = findViewById… 
myButton.setOnClickListener(this);

// Down below…
@Override
public void onClick(View view) {
     if (myButton.isEnabled()) {
        myButton.setEnabled(false);
        // Now do something like…
        startActivity(…);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在……在您的逻辑中一个完全不同的地方,例如……onCreate或onResume或您希望按钮再次起作用的任何地方……

 myButton.setEnabled(true);
Run Code Online (Sandbox Code Playgroud)

“更现代”的方法:

  1. 进行相同的操作,但是将逻辑放在Presenter中。
  2. 您的演示者将决定是否触发了“按钮”操作。
  3. 您的演示者将说出其“观点”:enableMyButton();disableMyButton()视情况而定。
  4. 您的视图将做正确的事。
  5. 你知道的……基本的关注点分离。

为什么“启用(正确/错误)”?

因为它是内置的。因为按钮将遵守其状态(并且如果您具有正确的状态列表,它将为您更改外观,并且因为它始终是您所期望的)。另外,由于测试演示者是否具有完整的模拟要比在代码中永久增长的完整活动要容易得多。

  • 这必须是一个可以接受的答案,因为在这里您只需单击一下,然后可以在onActivityResults中再次启用它,那么第一个被接受的答案的问题是您将永远不知道您的Activity是否会在1秒钟内执行,否则,您将能够再次单击该按钮,这可能会导致意外行为。此解决方案是解决此问题的最佳方法,因为您只需单击并触发一次事件即可。 (2认同)

Ran*_*mar 5

对于 Kotlin 用户

object AppUtil {

var mLastClickTime=0L

fun isOpenRecently():Boolean{
    if (SystemClock.elapsedRealtime() - mLastClickTime < 1000){
        return true
    }
    mLastClickTime = SystemClock.elapsedRealtime()
    return false
}
}
Run Code Online (Sandbox Code Playgroud)

在您的 Activity 或 Fragment 或任何地方

只需添加这一行条件

 if(isOpenRecently()) return
Run Code Online (Sandbox Code Playgroud)

例子:

fun startHomePage(activity: Activity){
     if(isOpenRecently()) return //this one line enough 
    val intent= Intent(activity,MainActivity::class.java)
    activity.startActivity(intent)

}
Run Code Online (Sandbox Code Playgroud)


Mir*_*aig 5

如果您使用的是 kotlin,则创建扩展 fun 如下:

fun View.clickWithDebounce(debounceTime: Long = 1200L, action: () -> Unit) {
    this.setOnClickListener(object : View.OnClickListener {
        private var lastClickTime: Long = 0
        override fun onClick(v: View) {
            if (SystemClock.elapsedRealtime() - lastClickTime < debounceTime) return
            else action()
            lastClickTime = SystemClock.elapsedRealtime()
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

现在在任何视图中只需调用:

view.clickWithDebounce{
...
}
Run Code Online (Sandbox Code Playgroud)