Android:阻止在按钮上显示多个 onClick 事件(已禁用)

2022-09-02 10:45:09

按钮触发只应调用一次的操作。在执行操作之前,该按钮将被禁用并隐藏在 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”事件。(即 被调用多次)。似乎 onClick 事件在实际禁用按钮之前已排队。performTaskOnce

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

问题发生在Android 2.3.6上,我无法在Android 4.0.3上重现它。但考虑到4.x设备的稀有性,排除旧设备不是一种选择。


答案 1

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

答案 2

为了保持干燥

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

推荐