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.

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ęć.


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.


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)?


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ę :-)


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.



3
    /**
 * Remove an onclick listener
 *
 * @param view
 * @author malin.myemail@gmail.com
 * @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();
        }

    }
}

0

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

mTitleView = findViewById (R.id.mTitleView);

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.