बटन कई रैपिड क्लिक से बचें


86

मुझे अपने ऐप में समस्या है कि यदि उपयोगकर्ता बटन को कई बार जल्दी से क्लिक करता है, तो बटन डायल करने से पहले ही कई ईवेंट उत्पन्न हो जाते हैं, बटन गायब हो जाता है

मुझे पता है कि बटन के क्लिक करते ही बूलियन वैरिएबल को एक झंडे के रूप में सेट किया जाता है ताकि डायलॉग बंद होने तक भविष्य के क्लिक को रोका जा सके। हालाँकि, मेरे पास कई बटन हैं और हर बटन के लिए हर बार ऐसा करना एक ओवरकिल लगता है। क्या केवल बटन पर क्लिक करने से केवल ईवेंट कार्रवाई उत्पन्न करने की अनुमति देने का कोई दूसरा तरीका नहीं है?

इससे भी बुरी बात यह है कि पहली कार्रवाई को संभालने से पहले कई त्वरित क्लिक कई इवेंट एक्शन उत्पन्न करते हैं, इसलिए यदि मैं पहली क्लिक हैंडलिंग विधि में बटन को अक्षम करना चाहता हूं, तो कतार में पहले से मौजूद इवेंट एक्शन हैंडल होने की प्रतीक्षा कर रहे हैं!

कृपया मदद धन्यवाद


हम GreyBeardedGeek कोड का उपयोग कोड लागू कर सकते हैं। मुझे यकीन नहीं है कि आपने उर गतिविधि में अमूर्त वर्ग का उपयोग कैसे किया?
CoDe

इस समाधान के रूप में अच्छी तरह से stackoverflow.com/questions/20971484/…
दिमित्रीबॉयको

जवाबों:


111

यहाँ एक 'बहस' है जिसे मैंने हाल ही में लिखा था। आप इसे बताते हैं कि क्लिक के बीच न्यूनतम स्वीकार्य संख्या क्या है। के onDebouncedClickबजाय अपने तर्क को लागू करेंonClick

import android.os.SystemClock;
import android.view.View;

import java.util.Map;
import java.util.WeakHashMap;

/**
 * A Debounced OnClickListener
 * Rejects clicks that are too close together in time.
 * This class is safe to use as an OnClickListener for multiple views, and will debounce each one separately.
 */
public abstract class DebouncedOnClickListener implements View.OnClickListener {

    private final long minimumIntervalMillis;
    private Map<View, Long> lastClickMap;

    /**
     * Implement this in your subclass instead of onClick
     * @param v The view that was clicked
     */
    public abstract void onDebouncedClick(View v);

    /**
     * The one and only constructor
     * @param minimumIntervalMillis The minimum allowed time between clicks - any click sooner than this after a previous click will be rejected
     */
    public DebouncedOnClickListener(long minimumIntervalMillis) {
        this.minimumIntervalMillis = minimumIntervalMillis;
        this.lastClickMap = new WeakHashMap<>();
    }

    @Override 
    public void onClick(View clickedView) {
        Long previousClickTimestamp = lastClickMap.get(clickedView);
        long currentTimestamp = SystemClock.uptimeMillis();

        lastClickMap.put(clickedView, currentTimestamp);
        if(previousClickTimestamp == null || Math.abs(currentTimestamp - previousClickTimestamp) > minimumIntervalMillis) {
            onDebouncedClick(clickedView);
        }
    }
}

3
ओह, अगर केवल हर वेबसाइट को इन लाइनों के साथ कुछ लागू करने से परेशान किया जा सकता है! कोई और अधिक "दो बार सबमिट न करें या आपसे दो बार शुल्क लिया जाएगा"! धन्यवाद।
फ्लोरिस

2
जहाँ तक मुझे पता है, नहीं। OnClick हमेशा UI थ्रेड पर होनी चाहिए (केवल एक ही है)। इतने क्लिक्स, जबकि समय के करीब, हमेशा एक ही धागे पर अनुक्रमिक होना चाहिए।
ग्रेबियरगेड गीक

45
@FengDai दिलचस्प है - यह "गड़बड़" वही करता है जो आपकी लाइब्रेरी करती है, कोड की मात्रा के लगभग 1/20 वें हिस्से में। आपके पास एक दिलचस्प वैकल्पिक समाधान है, लेकिन यह काम करने वाले कोड का अपमान करने की जगह नहीं है।
ग्रेबियरगेड गीक

13
@GreyBeardedGeek उस बुरे शब्द का उपयोग करने के लिए क्षमा करें।
फेंग दाई

2
यह थ्रॉटलिंग है, डिबगिंग नहीं।
10

71

RxBinding के साथ इसे आसानी से किया जा सकता है। यहाँ एक उदाहरण है:

RxView.clicks(view).throttleFirst(500, TimeUnit.MILLISECONDS).subscribe(empty -> {
            // action on click
        });

build.gradleRxBinding निर्भरता को जोड़ने के लिए निम्न पंक्ति जोड़ें:

compile 'com.jakewharton.rxbinding:rxbinding:0.3.0'

2
सबसे अच्छा निर्णय। बस ध्यान दें कि यह आपके विचार के लिए मजबूत लिंक रखता है इसलिए सामान्य जीवन चक्र पूरा होने के बाद टुकड़े को एकत्र नहीं किया जाएगा - इसे ट्रेलो की लाइफसाइकल लाइब्रेरी में लपेटें। फिर इसे अनसब्सक्राइब किया जाएगा और चुने हुए जीवनचक्र विधि के बाद मुक्त किया जाएगा (आमतौर पर onDestroyView)
Den Drobiazko

2
यह एडेप्टर के साथ काम नहीं करता है, फिर भी कई मदों पर क्लिक कर सकता है, और यह थ्रॉटल फ़र्स्ट करेगा, लेकिन प्रत्येक व्यक्तिगत विचारों पर।
desgraci

1
हैंडलर के साथ आसानी से लागू किया जा सकता है, यहां RxJava का उपयोग करने की कोई आवश्यकता नहीं है।
Miha_x64 8

20

यहाँ स्वीकृत उत्तर का मेरा संस्करण है। यह बहुत समान है, लेकिन दृश्यों को मानचित्र में संग्रहीत करने का प्रयास नहीं करता है जो मुझे नहीं लगता कि यह एक अच्छा विचार है। इसमें एक रैप विधि भी शामिल है जो कई स्थितियों में उपयोगी हो सकती है।

/**
 * Implementation of {@link OnClickListener} that ignores subsequent clicks that happen too quickly after the first one.<br/>
 * To use this class, implement {@link #onSingleClick(View)} instead of {@link OnClickListener#onClick(View)}.
 */
public abstract class OnSingleClickListener implements OnClickListener {
    private static final String TAG = OnSingleClickListener.class.getSimpleName();

    private static final long MIN_DELAY_MS = 500;

    private long mLastClickTime;

    @Override
    public final void onClick(View v) {
        long lastClickTime = mLastClickTime;
        long now = System.currentTimeMillis();
        mLastClickTime = now;
        if (now - lastClickTime < MIN_DELAY_MS) {
            // Too fast: ignore
            if (Config.LOGD) Log.d(TAG, "onClick Clicked too quickly: ignored");
        } else {
            // Register the click
            onSingleClick(v);
        }
    }

    /**
     * Called when a view has been clicked.
     * 
     * @param v The view that was clicked.
     */
    public abstract void onSingleClick(View v);

    /**
     * Wraps an {@link OnClickListener} into an {@link OnSingleClickListener}.<br/>
     * The argument's {@link OnClickListener#onClick(View)} method will be called when a single click is registered.
     * 
     * @param onClickListener The listener to wrap.
     * @return the wrapped listener.
     */
    public static OnClickListener wrap(final OnClickListener onClickListener) {
        return new OnSingleClickListener() {
            @Override
            public void onSingleClick(View v) {
                onClickListener.onClick(v);
            }
        };
    }
}

रैप विधि का उपयोग कैसे करें? क्या आप एक उदाहरण दे सकते हैं। धन्यवाद।
मेहुल जोसर

1
@MehulJoisar इस तरह:myButton.setOnClickListener(OnSingleClickListener.wrap(myOnClickListener))
BoD

10

हम इसे बिना किसी पुस्तकालय के कर सकते हैं। बस एक एकल एक्सटेंशन फ़ंक्शन बनाएं:

fun View.clickWithDebounce(debounceTime: Long = 600L, 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()
        }
    })
}

नीचे दिए गए कोड का उपयोग करके देखें:

buttonShare.clickWithDebounce { 
   // Do anything you want
}

यह अच्छा है! हालांकि मुझे लगता है कि यहां अधिक उपयुक्त शब्द "थ्रोटल" है, "पराजय" नहीं। यानी clickWithThrottle ()
हॉपिया

9

आप इस परियोजना का उपयोग कर सकते हैं: एक समस्या के साथ इस समस्या को हल करने के लिए https://github.com/fengdai/clickguard :

ClickGuard.guard(button);

अद्यतन: यह लाइब्रेरी किसी भी अधिक अनुशंसित नहीं है। मैं निकिता का समाधान पसंद करता हूं। इसके बजाय RxBinding का उपयोग करें।


@ फ़ेंग दाई, इस पुस्तकालय का उपयोग कैसे करेंListView
CAMOBAP

एंड्रॉइड स्टूडियो में इसका उपयोग कैसे करें?
VVB

इस लाइब्रेरी को और अधिक अनुशंसित नहीं किया गया है। कृपया इसके बजाय RxBinding का उपयोग करें। देखें निकिता का जवाब
फेंग दाई

7

यहाँ एक सरल उदाहरण है:

public abstract class SingleClickListener implements View.OnClickListener {
    private static final long THRESHOLD_MILLIS = 1000L;
    private long lastClickMillis;

    @Override public void onClick(View v) {
        long now = SystemClock.elapsedRealtime();
        if (now - lastClickMillis > THRESHOLD_MILLIS) {
            onClicked(v);
        }
        lastClickMillis = now;
    }

    public abstract void onClicked(View v);
}

1
नमूना और अच्छा!
चूलो

5

GreyBeardedGeek समाधान पर बस एक त्वरित अद्यतन। क्लॉज करें और Math.abs फ़ंक्शन जोड़ें, तो बदलें। इसे इस तरह सेट करें:

  if(previousClickTimestamp == null || (Math.abs(currentTimestamp - previousClickTimestamp.longValue()) > minimumInterval)) {
        onDebouncedClick(clickedView);
    }

उपयोगकर्ता एंड्रॉइड डिवाइस पर समय को बदल सकता है और इसे अतीत में रख सकता है, इसलिए इसके बिना बग के कारण हो सकता है।

पुनश्च: आपके समाधान पर टिप्पणी करने के लिए पर्याप्त बिंदु नहीं हैं, इसलिए मैंने अभी एक और जवाब दिया है


5

यहाँ कुछ है जो किसी भी घटना के साथ काम करेगा, न कि केवल क्लिक पर। यह अंतिम घटना को भी वितरित करेगा, भले ही यह तीव्र घटनाओं की श्रृंखला का हिस्सा हो (जैसे कि आरएक्स डेब्यू )।

class Debouncer(timeout: Long, unit: TimeUnit, fn: () -> Unit) {

    private val timeoutMillis = unit.toMillis(timeout)

    private var lastSpamMillis = 0L

    private val handler = Handler()

    private val runnable = Runnable {
        fn()
    }

    fun spam() {
        if (SystemClock.uptimeMillis() - lastSpamMillis < timeoutMillis) {
            handler.removeCallbacks(runnable)
        }
        handler.postDelayed(runnable, timeoutMillis)
        lastSpamMillis = SystemClock.uptimeMillis()
    }
}


// example
view.addOnClickListener.setOnClickListener(object: View.OnClickListener {
    val debouncer = Debouncer(1, TimeUnit.SECONDS, {
        showSomething()
    })

    override fun onClick(v: View?) {
        debouncer.spam()
    }
})

1) श्रोता के एक क्षेत्र में डिबॉन्सर का निर्माण करें लेकिन कॉलबैक फ़ंक्शन के बाहर, टाइमआउट के साथ कॉन्फ़िगर किया गया और कॉलबैक fn जिसे आप थ्रॉटल करना चाहते हैं।

2) श्रोता के कॉलबैक फ़ंक्शन में अपने डिबॉन्सर के स्पैम विधि को कॉल करें।


4

RxJava का उपयोग करके समान समाधान

import android.view.View;

import java.util.concurrent.TimeUnit;

import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.subjects.PublishSubject;

public abstract class SingleClickListener implements View.OnClickListener {
    private static final long THRESHOLD_MILLIS = 600L;
    private final PublishSubject<View> viewPublishSubject = PublishSubject.<View>create();

    public SingleClickListener() {
        viewPublishSubject.throttleFirst(THRESHOLD_MILLIS, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<View>() {
                    @Override
                    public void call(View view) {
                        onClicked(view);
                    }
                });
    }

    @Override
    public void onClick(View v) {
        viewPublishSubject.onNext(v);
    }

    public abstract void onClicked(View v);
}

4

तो, यह उत्तर बटरकनीफ़ लाइब्रेरी द्वारा प्रदान किया गया है।

package butterknife.internal;

import android.view.View;

/**
 * A {@linkplain View.OnClickListener click listener} that debounces multiple clicks posted in the
 * same frame. A click on one button disables all buttons for that frame.
 */
public abstract class DebouncingOnClickListener implements View.OnClickListener {
  static boolean enabled = true;

  private static final Runnable ENABLE_AGAIN = () -> enabled = true;

  @Override public final void onClick(View v) {
    if (enabled) {
      enabled = false;
      v.post(ENABLE_AGAIN);
      doClick(v);
    }
  }

  public abstract void doClick(View v);
}

यह विधि पिछले क्लिक को संभालने के बाद ही क्लिक को संभालती है और ध्यान दें कि यह एक फ्रेम में कई क्लिक से बचा जाता है।


3

सिग्नल ऐपHandler से एक आधारित थ्रॉटलर ।

import android.os.Handler;
import android.support.annotation.NonNull;

/**
 * A class that will throttle the number of runnables executed to be at most once every specified
 * interval.
 *
 * Useful for performing actions in response to rapid user input where you want to take action on
 * the initial input but prevent follow-up spam.
 *
 * This is different from a Debouncer in that it will run the first runnable immediately
 * instead of waiting for input to die down.
 *
 * See http://rxmarbles.com/#throttle
 */
public final class Throttler {

    private static final int WHAT = 8675309;

    private final Handler handler;
    private final long    thresholdMs;

    /**
     * @param thresholdMs Only one runnable will be executed via {@link #publish} every
     *                  {@code thresholdMs} milliseconds.
     */
    public Throttler(long thresholdMs) {
        this.handler     = new Handler();
        this.thresholdMs = thresholdMs;
    }

    public void publish(@NonNull Runnable runnable) {
        if (handler.hasMessages(WHAT)) {
            return;
        }

        runnable.run();
        handler.sendMessageDelayed(handler.obtainMessage(WHAT), thresholdMs);
    }

    public void clear() {
        handler.removeCallbacksAndMessages(null);
    }
}

उदाहरण उपयोग:

throttler.publish(() -> Log.d("TAG", "Example"));

उदाहरण में उपयोग OnClickListener:

view.setOnClickListener(v -> throttler.publish(() -> Log.d("TAG", "Example")));

उदाहरण केटी उपयोग:

view.setOnClickListener {
    throttler.publish {
        Log.d("TAG", "Example")
    }
}

या विस्तार के साथ:

fun View.setThrottledOnClickListener(throttler: Throttler, function: () -> Unit) {
    throttler.publish(function)
}

फिर उदाहरण का उपयोग करें:

view.setThrottledOnClickListener(throttler) {
    Log.d("TAG", "Example")
}

1

मैं इस श्रेणी का उपयोग डेटाबाइंडिंग के साथ करता हूं। बहुत अच्छा काम करता है।

/**
 * This class will prevent multiple clicks being dispatched.
 */
class OneClickListener(private val onClickListener: View.OnClickListener) : View.OnClickListener {
    private var lastTime: Long = 0

    override fun onClick(v: View?) {
        val current = System.currentTimeMillis()
        if ((current - lastTime) > 500) {
            onClickListener.onClick(v)
            lastTime = current
        }
    }

    companion object {
        @JvmStatic @BindingAdapter("oneClick")
        fun setOnClickListener(theze: View, f: View.OnClickListener?) {
            when (f) {
                null -> theze.setOnClickListener(null)
                else -> theze.setOnClickListener(OneClickListener(f))
            }
        }
    }
}

और मेरा लेआउट इस तरह दिखता है

<TextView
        app:layout_constraintTop_toBottomOf="@id/bla"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:gravity="center"
        android:textSize="18sp"
        app:oneClick="@{viewModel::myHandler}" />

1

इस परिदृश्य को संभालने का अधिक महत्वपूर्ण तरीका RxJava2 के साथ थ्रॉटलिंग ऑपरेटर (थ्रॉटल फर्स्ट) का उपयोग करना है। कोटलिन में इसे प्राप्त करने के लिए कदम:

1)। निर्भरता: - build.gradle एप्लिकेशन स्तर फ़ाइल में rxjava2 निर्भरता जोड़ें।

implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.10'

2)। एक अमूर्त वर्ग का निर्माण करता है जो View.OnClickListener को कार्यान्वित करता है और दृश्य के OnClick () विधि को संभालने के लिए थ्रोटल पहले ऑपरेटर को शामिल करता है। कोड स्निपेट इस प्रकार है:

import android.util.Log
import android.view.View
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.subjects.PublishSubject
import java.util.concurrent.TimeUnit

abstract class SingleClickListener : View.OnClickListener {
   private val publishSubject: PublishSubject<View> = PublishSubject.create()
   private val THRESHOLD_MILLIS: Long = 600L

   abstract fun onClicked(v: View)

   override fun onClick(p0: View?) {
       if (p0 != null) {
           Log.d("Tag", "Clicked occurred")
           publishSubject.onNext(p0)
       }
   }

   init {
       publishSubject.throttleFirst(THRESHOLD_MILLIS, TimeUnit.MILLISECONDS)
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe { v -> onClicked(v) }
   }
}

3)। गतिविधि में देखने के क्लिक पर इस सिंगलक्लिकस्टनर वर्ग को लागू करें। इसे निम्न प्रकार से प्राप्त किया जा सकता है:

override fun onCreate(savedInstanceState: Bundle?)  {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val singleClickListener = object : SingleClickListener(){
      override fun onClicked(v: View) {
       // operation on click of xm_view_id
      }
  }
xm_viewl_id.setOnClickListener(singleClickListener)
}

ऐप में इन उपरोक्त चरणों को लागू करने से केवल 600mS तक किसी दृश्य पर कई क्लिकों से बचा जा सकता है। हैप्पी कोडिंग!


1

आप उस उद्देश्य के लिए Rxbinding3 का उपयोग कर सकते हैं। बस इस निर्भरता को build.gradle में जोड़ें

build.gradle

implementation 'com.jakewharton.rxbinding3:rxbinding:3.1.0'

फिर अपनी गतिविधि या खंड में, बोले कोड का उपयोग करें

your_button.clicks().throttleFirst(10000, TimeUnit.MILLISECONDS).subscribe {
    // your action
}

0

इस तरह हल किया जाता है

Observable<Object> tapEventEmitter = _rxBus.toObserverable().share();
Observable<Object> debouncedEventEmitter = tapEventEmitter.debounce(1, TimeUnit.SECONDS);
Observable<List<Object>> debouncedBufferEmitter = tapEventEmitter.buffer(debouncedEventEmitter);

debouncedBufferEmitter.buffer(debouncedEventEmitter)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<List<Object>>() {
      @Override
      public void call(List<Object> taps) {
        _showTapCount(taps.size());
      }
    });

0

यहाँ एक बहुत ही सरल उपाय है, जिसका उपयोग लंबोदर के साथ किया जा सकता है:

view.setOnClickListener(new DebounceClickListener(v -> this::doSomething));

यहाँ कॉपी / पेस्ट तैयार स्निपेट दिया गया है:

public class DebounceClickListener implements View.OnClickListener {

    private static final long DEBOUNCE_INTERVAL_DEFAULT = 500;
    private long debounceInterval;
    private long lastClickTime;
    private View.OnClickListener clickListener;

    public DebounceClickListener(final View.OnClickListener clickListener) {
        this(clickListener, DEBOUNCE_INTERVAL_DEFAULT);
    }

    public DebounceClickListener(final View.OnClickListener clickListener, final long debounceInterval) {
        this.clickListener = clickListener;
        this.debounceInterval = debounceInterval;
    }

    @Override
    public void onClick(final View v) {
        if ((SystemClock.elapsedRealtime() - lastClickTime) < debounceInterval) {
            return;
        }
        lastClickTime = SystemClock.elapsedRealtime();
        clickListener.onClick(v);
    }
}

का आनंद लें!


0

@GreyBeardedGeek उत्तर के आधार पर ,

  • बनाएं debounceClick_last_Timestampपर ids.xmlपिछली क्लिक टाइमस्टैम्प टैग करने के लिए।
  • इस कोड को ब्लॉक में जोड़ें BaseActivity

    protected void debounceClick(View clickedView, DebouncedClick callback){
        debounceClick(clickedView,1000,callback);
    }
    
    protected void debounceClick(View clickedView,long minimumInterval, DebouncedClick callback){
        Long previousClickTimestamp = (Long) clickedView.getTag(R.id.debounceClick_last_Timestamp);
        long currentTimestamp = SystemClock.uptimeMillis();
        clickedView.setTag(R.id.debounceClick_last_Timestamp, currentTimestamp);
        if(previousClickTimestamp == null 
              || Math.abs(currentTimestamp - previousClickTimestamp) > minimumInterval) {
            callback.onClick(clickedView);
        }
    }
    
    public interface DebouncedClick{
        void onClick(View view);
    }
    
  • उपयोग:

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            debounceClick(v, 3000, new DebouncedClick() {
                @Override
                public void onClick(View view) {
                    doStuff(view); // Put your's click logic on doStuff function
                }
            });
        }
    });
    
  • लैम्ब्डा का उपयोग करना

    view.setOnClickListener(v -> debounceClick(v, 3000, this::doStuff));
    

0

यहाँ एक छोटा सा उदाहरण रखो

view.safeClick { doSomething() }

@SuppressLint("CheckResult")
fun View.safeClick(invoke: () -> Unit) {
    RxView
        .clicks(this)
        .throttleFirst(300, TimeUnit.MILLISECONDS)
        .subscribe { invoke() }
}

1
कृपया लिंक या विवरण प्रदान करें कि आपका RxView क्या है
BekaBot

0

मेरे समाधान, कॉल करने की आवश्यकता है removeallजब हम टुकड़ा और गतिविधि से बाहर (नष्ट) करते हैं:

import android.os.Handler
import android.os.Looper
import java.util.concurrent.TimeUnit

    //single click handler
    object ClickHandler {

        //used to post messages and runnable objects
        private val mHandler = Handler(Looper.getMainLooper())

        //default delay is 250 millis
        @Synchronized
        fun handle(runnable: Runnable, delay: Long = TimeUnit.MILLISECONDS.toMillis(250)) {
            removeAll()//remove all before placing event so that only one event will execute at a time
            mHandler.postDelayed(runnable, delay)
        }

        @Synchronized
        fun removeAll() {
            mHandler.removeCallbacksAndMessages(null)
        }
    }

0

मैं कहूंगा कि KProgressHUD जैसी "लोडिंग" लाइब्रेरी का उपयोग करना सबसे आसान तरीका है।

https://github.com/Kaopiz/KProgressHUD

OnClick मेथड में पहली चीज लोडिंग एनीमेशन को कॉल करना होगा जो तुरंत सभी UI को ब्लॉक करता है जब तक कि देव इसे मुक्त करने का निर्णय नहीं लेता है।

तो आपके पास ऑनक्लिक एक्शन के लिए यह होगा (यह बटरकॉइन का उपयोग करता है लेकिन यह स्पष्ट रूप से किसी भी तरह के दृष्टिकोण के साथ काम करता है):

इसके अलावा, क्लिक के बाद बटन को निष्क्रिय करना न भूलें।

@OnClick(R.id.button)
void didClickOnButton() {
    startHUDSpinner();
    button.setEnabled(false);
    doAction();
}

फिर:

public void startHUDSpinner() {
    stopHUDSpinner();
    currentHUDSpinner = KProgressHUD.create(this)
            .setStyle(KProgressHUD.Style.SPIN_INDETERMINATE)
            .setLabel(getString(R.string.loading_message_text))
            .setCancellable(false)
            .setAnimationSpeed(3)
            .setDimAmount(0.5f)
            .show();
}

public void stopHUDSpinner() {
    if (currentHUDSpinner != null && currentHUDSpinner.isShowing()) {
        currentHUDSpinner.dismiss();
    }
    currentHUDSpinner = null;
}

और तुम चाहो तो doHction () विधि में stopHUDSpinner विधि का उपयोग कर सकते हैं:

private void doAction(){ 
   // some action
   stopHUDSpinner()
}

अपने ऐप लॉजिक के अनुसार बटन को फिर से सक्षम करें: button.setEnabled (true);

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.