繁体   English   中英

Android:防止按钮上的多个 onClick 事件(已禁用)

[英]Android: Prevent multiple onClick events on a button (that has been disabled)

一个按钮触发一个应该只调用一次的动作。 在执行操作之前,按钮被禁用并隐藏在 onClick 处理程序中:

someButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        someButton.setEnabled(false);
        someButton.setClickable(false);
        someButton.setVisibility(View.GONE);
        performTaskOnce();
        }
    });

private void performTaskOnce() {
    Log.i("myapp", "Performing task");
    //Do something nontrivial that takes a few ms (like changing the view hierarchy)
}

即使按钮立即被禁用,仍然可以通过非常快速地多次点击来触发多个“onClick”事件。 (即performTaskOnce被多次调用)。 似乎 onClick 事件在按钮实际禁用之前排队。

我可以通过检查每个 onClick 句柄是否已禁用相应的按钮来解决这个问题,但这似乎是一个黑客。 有没有更好的方法来避免这个问题?

问题出现在 Android 2.3.6 上,我无法在 Android 4.0.3 上重现它。 但鉴于 4.x 设备的稀有性,不能排除旧设备。

您可以在单击按钮时将布尔变量设置为 true,并在完成单击处理后将其设置为 false。

通过这种方式,您可以忽略多次点击,而不必禁用按钮,这可能会避免令人讨厌的按钮闪烁。

boolean processClick=true;
someButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        if(processClick)
         {
        someButton.setEnabled(false);
        someButton.setClickable(false);
        someButton.setVisibility(View.GONE);
        performTaskOnce();
         }
        processClick=false; 
        }
    });

private void performTaskOnce() {
    Log.i("myapp", "Performing task");
    //Do something nontrivial that takes a few ms (like changing the view hierarchy)
}

为了保持干燥

// Implementation
public abstract class OneShotClickListener implements View.OnClickListener {
    private boolean hasClicked;

    @Override public final void onClick(View v) {
        if (!hasClicked) {
            onClicked(v);
            hasClicked = true;
        }
    }

    public abstract void onClicked(View v);
}

// Usage example
public class MyActivity extends Activity {
    private View myView;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        myView.setOnClickListener(new OneShotClickListener() {
            @Override public void onClicked(View v) {
                // do clicky stuff
            }
        });
    }
}

有点晚了,但这可能对某人有用。 就我而言,我正在调用另一个活动;

声明一个布尔值;

boolean clickable;

在点击监听器中;

if(clickable){
   // Launch other activity
   clickable = false;
}

调用 onResume 时启用;

@Override
public void onResume() {
    Log.e(TAG, "onResume");
    super.onResume();
    clickable = true;
}

您可以使用RxView ( com.jakewharton.rxbinding2.view.RxView ) 是由 Jake Wharton 创建的围绕 RxJava 的扩展。

要将其集成到项目中,您应该使用implementation 'com.jakewharton.rxbinding3:rxbinding:3.1.0'

简单的Java用法:

RxView.clicks(yourButton)
    .sample(500, TimeUnit.MILLISECONDS)
    .subscribe { action() }

Kotlin您可以创建扩展函数来处理您的点击:

View.singleClick(action: () -> Any) {
    RxView.clicks(this)
        .sample(500, TimeUnit.MILLISECONDS)
        .subscribe { action() }
}

样本:

科特林

yourButton.singleClick({
    //do some stuff here
})

爪哇

SingleClickListenerKt.singleClick(yourButton, () -> {
    doSomeStuff();
    return null;
    });

注意:如果您愿意,您可以使用任何 RxJava 运算符,例如 debounce debounce, map, first等。

声明一个变量并将其用作

 boolean boo = false;
 someButton.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) {
 if(boo==false){
    someButton.setEnabled(false);
    someButton.setClickable(false);
    someButton.setVisibility(View.GONE);
    boo = true;
 }


    }
});

通过这种方式,您可以防止多次点击您的按钮

希望它有帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM