Подтвердить что ты не робот

Android: запретить несколько событий onClick на кнопке (которая была отключена)

Кнопка запускает действие, которое следует вызывать только один раз. Кнопка будет отключена и скрыта в обработчике 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, не исключено исключение старых устройств.

4b9b3361

Ответ 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

В интересах сохранения 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
            }
        });
    }
}

Ответ 3

Бит поздно, но это может кому-то помочь. В моем случае я называю это другой деятельностью;

Объявить логическое значение;

boolean clickable;

В прослушивателе кликов;

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

Включить, когда вызывается onResume;

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

Ответ 4

объявить перемену  и используйте его как

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


    }
});

этим вы предотвращаете несколько кликов на вашей кнопке

надеюсь, что это поможет