Usuń detektor onclick

194

Mam obiekt, w którym tekst cyklicznie wyświetla komunikaty o stanie. Gdy wiadomości się zmieniają, chcę, aby zdarzenie kliknięcia obiektu uległo zmianie, aby zabrać Cię do działania, którego dotyczy wiadomość.

Mam więc TextView mTitleViewi przypisuję takie wydarzenie.

public void setOnTitleClickListener(OnClickListener listener) {
    mTitleView.setOnClickListener(listener);
}

Jak usunąć to zdarzenie kliknięcia? Niektóre komunikaty o stanie nie mają obszaru, w którym można wykonać akcję, dlatego chciałbym wyłączyć zdarzenie kliknięcia. Chciałbym również móc cyklicznie przełączać się między tymi zdarzeniami kliknięć i usuwać je w odpowiedni sposób, ale nie jestem pewien najlepszej praktyki.

Josh
źródło

Odpowiedzi:

417

mTitleView.setOnClickListener(null) powinien załatwić sprawę.

Lepszym rozwiązaniem może być sprawdzenie stanu w OnClickListener, a następnie ustalenie, czy kliknięcie powinno coś zrobić, czy nie dodawanie i usuwanie detektorów kliknięć.

Robby Pond
źródło
1
Nie ma innych porządków, które muszę zrobić, aby wyrejestrować wydarzenie?
Josh
2
Nie. Odbiornik jest tylko obiektem, którego widok używa do wywoływania metody po kliknięciu, więc po ustawieniu jej na null niszczy ją.
Robby Pond,
15
zastanawiam się, czy słuchacze powodują alokację pamięci? Czy musimy je uwolnić? Czy to zwiększy wydajność aplikacji?
alicanbatur
2
Dziękuję za odpowiedź, dodając, dlaczego według ciebie sprawdzanie stanu lub flagi w odbiorniku jest lepsze.
kapv89
2
Kiedy mówisz, a better designże sugerujesz wpływ na wydajność, czy po prostu mówisz, że to trochę niesmaczne?
RTF,
132

Pamiętaj, że jeśli widoku nie można kliknąć (na przykład TextView), ustawienie setOnClickListener(null)oznacza, że ​​widok można kliknąć. Użyj, mMyView.setClickable(false)jeśli nie chcesz, aby Twój widok był klikalny. Na przykład jeśli użyjesz xml rysowalnego dla tła, który pokazuje różne kolory dla różnych stanów, jeśli twój widok jest nadal klikalny, użytkownicy mogą go kliknąć, a inny kolor tła pokaże, co może wyglądać dziwnie.

FreewheelNat
źródło
Dobrze jest wiedzieć o TextView i tym podobnych, ale w przypadku ListView nie ma on wpływu, gdy wcześniej ustawiono OnClickListener.
Ktoś gdzieś
4
Właśnie dlatego napisałem „Zauważ, że jeśli widoku nie da się kliknąć (na przykład TextView)” - ListView można kliknąć, więc to nie działa.
FreewheelNat
Jeśli potrzebujemy przełączać się tam iz powrotem, aby wyłączyć / włączyć widok onClickListener, moim zdaniem jest to lepsze rozwiązanie niż ustawienie setOnClickListener (null).
Panini Luncher,
1
view.setOnClickListener (null) wraz z view.setClickable (false) to poprawna odpowiedź, dzięki !!!!
Petros Mastrantonas
12

Być może setOnClickListener(null)?

Luther
źródło
1
Nie działa to specjalnie dla pól wyboru i prawdopodobnie nie będzie działać również w przypadku innych widżetów.
Chris
8

Ustawienie setOnClickListener(null)jest dobrym pomysłem, aby usunąć detektor kliknięć w czasie wykonywania.

A także ktoś skomentował, że dzwonienie View.hasOnClickListeners()po tym wróci true, NIE mój przyjacielu.

Oto implementacja hasOnClickListeners()wzięta z android.view.Viewklasy

 public boolean hasOnClickListeners() {
        ListenerInfo li = mListenerInfo;
        return (li != null && li.mOnClickListener != null);
    }

Dzięki Bogu. Sprawdza, czy null.

Więc wszystko jest bezpieczne. Cieszyć się :-)

Azim Ansari
źródło
4

Powyższe odpowiedzi wydają się niepotrzebne i niewiarygodne. Próbowałem to zrobić za pomocą ImageView w prostym układzie względnym i nie wyłączało to zdarzenia onClick.

Dla mnie zadziałało użycie setEnabled.

ImageView v = (ImageView)findViewByID(R.id.layoutV);
v.setEnabled(false);

Następnie możesz sprawdzić, czy Widok jest włączony za pomocą:

boolean ImageView.isEnabled();

Inną opcją jest użycie setContentDescription (String string) i String getContentDescription () do ustalenia statusu widoku.

Brandon Thompson
źródło
4

Mówiąc wprost, to zadziałało dla mnie

itemView.setOnClickListener(null);
Sai Gopi N.
źródło
3
    /**
 * Remove an onclick listener
 *
 * @param view
 * @author [email protected]
 * @website https://github.com/androidmalin
 * @data 2016-05-16
 */
public static void unBingListener(View view) {
    if (view != null) {
        try {
            if (view.hasOnClickListeners()) {
                view.setOnClickListener(null);

            }

            if (view.getOnFocusChangeListener() != null) {
                view.setOnFocusChangeListener(null);

            }

            if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
                ViewGroup viewGroup = (ViewGroup) view;
                int viewGroupChildCount = viewGroup.getChildCount();
                for (int i = 0; i < viewGroupChildCount; i++) {
                    unBingListener(viewGroup.getChildAt(i));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
androidmalin
źródło
0

Wystarczy ponowna inicjalizacja przedmiotu, jak poniżej. Usuwałby onclick, onlonglick, onitemclick, onitemlongclick na podstawie elementu

mTitleView = findViewById (R.id.mTitleView);

Rockit Rockit
źródło