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

时间:2012-06-01 09:57:27

标签: java android user-interface

按钮会触发一次只能调用一次的操作。在执行操作之前,该按钮被禁用并隐藏在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设备的稀有性,不能选择排除旧设备。

5 个答案:

答案 0 :(得分:8)

单击按钮时可以将布尔变量设置为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)
}

答案 1 :(得分:5)

为了保留DRY

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

答案 2 :(得分:2)

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

声明一个布尔值;

boolean clickable;

在点击监听器中;

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

启用onResume时启用;

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

答案 3 :(得分:0)

您可以使用RxViewcom.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
})

Java

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

注意:您可以根据需要使用任何RxJava运算符,例如debounce, map, first等。

答案 4 :(得分:-1)

声明一个变量并将其用作

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


    }
});

这样可以防止多次点击按钮

希望有所帮助