android View with View. GONE все ще отримує onTouch і onClick


77

Це мене бентежить:

Наскільки я вже читав, подання з setVisibility (View.GONE); не повинні отримувати більше подій натискання або клацання. Мій макет складається з двох частин, які будуть видимими або зникли, так що лише одна з них буде видимою та придатною для використання одночасно, але View.GONE не робить трюку. Я не бачу подання GONE, як очікувалося, але він все одно реагує на onClick (і споживає подію, яку повинен отримати інший вигляд).

Можеш допомогти мені?

Можливо, це може зацікавити: Коли я починаю свій проект, одне представлення ЗНИКЛО, інше видно. Цього разу він буде працювати, як очікувалося (подання GONE в основному ігнорується), але після налаштування View.GONE через код він перестане працювати.


1
Це відбувається відразу після виклику View.GONE? Тільки на обмежений проміжок часу? Можливо, це пов’язано з тим, що зміни користувацького інтерфейсу впливають не відразу.
— Шеріл Саймон

1
Нам потрібна додаткова інформація. Спробуйте скористатися hierarchyviewerінструментом, щоб перевірити стан вашої ієрархії подання під час виконання. Це дозволить побачити стан видимості та багато іншого під час налагодження проблем із переглядом.
— adamp

Дякую. Це відбувається відразу після виклику View.GONE. Інструмент ієрархічного перегляду говорить, що подання ЗНИКЛО, але воно все ще потрапляє на Click. Моя платформа - cyanogenmod 2.2 (але, я сподіваюся, це все ще проблема в моєму коді: D)
— ShadowMare

У мене така сама проблема без анімації. Навіть встановлюючи кожен елемент у ViewGroup на GONE, я все одно можу вибрати вміст GONE EditText і отримати клавіатуру.
— Філіпп

Після View.GONE елемент макета отримує подію onClick (). Це має анімаційний перегляд і зник. Як це заблокувати?
— iBrain

Відповіді:


113

Ви, можливо, використовуєте анімацію, щоб показувати / приховувати подання? Я отримую таку поведінку, коли використовую анімацію з андроїдом: fillEnabled = "true" android: fillAfter = "true" Не розумію, і здається помилкою - якщо я використовую анімацію без fillEnabled / fillAfter, все працює, як очікувалося. ..


2
Чи є якесь обхідне рішення? Я використовую nineoldandroids і бачу цю поведінку на API10 - я думаю, що він використовує fillEnabled для імітації поведінки API 3.0 модифікації властивостей подання після анімації.
— Рафаель Нобре

1
У мене проблема з API Google 4.4.2 Android також.
— GuilhE

Дякую, правда, це мені допомогло :)
— Android Noob

Дякуємо за підказку, видалення android: fillAfter = "true", приєднати прослуховувач анімації за допомогою code @Override public void onAnimationEnd(Animation animation) { /* Android will make an exception when you change the view hierarchy * in animationEnd. http://stackoverflow.com/a/7445557/587186 */ new Handler().post(new Runnable() { public void run() { if (interventionPreview != null) { interventionPreview.setVisibility(View.GONE); } } }); } зробив це, сподіваюся, це допоможе.
— лисиця

Дякую, що врятували мене від незначного головного болю
— Коен Ван Ловерен

108

Якщо ви встановили setVisibility(View.GONE)після деякої анімації (наприклад, згасання), спробуйте очистити анімацію за допомогою clearAnimation(). Це мені допомогло.


3
Це краща відповідь. Є сценарії, коли ви хочете використовувати android:fillAfterі android:fillEnabledв своїх анімаціях, і ви хочете, щоб подання перестало реагувати.
— Mick Byrne

1
Це спрацювало для мене, але оскільки моя анімація триватиме одну-дві секунди, тоді clearAnimation()анімація зупиняється, і я не бачу згасання анімації. Замість цього я використовував alpha.setFillAfter(false);свою альфа-анімацію, і вона працювала точно так, як я очікував.
— osayilgan

9
Це найкращий aswer, дякую! @osayilgan, у цьому випадку вам просто потрібно встановити слухач onEndAnimation та clearAnimation () після закінчення анімації.
— Рафаель Нобре

Я вважаю, що ця відповідь краща за прийняту, оскільки поведінка fillAfter може бути бажаною. Дякую, ти врятував мені світ болю.
— ssawchenko

2
@osayilgan ви повинні ввести clearAnimation()виклик у onAnimationEnd()метод. Тоді це працює, як очікувалося.
— Саран

8

Спробуйте встановити для властивості clickkable значення false, використовуючи setClickable (false) після setVisibility (View.GONE)


5

Так, mview.clearAnimation()є деякі випуски, але amination.setFillAfter(false);і mview.setClickable(false);РОБОТИ ідеальні.


2

Я сподіваюсь, що відбувається так, що ви робите вигляд невидимим, але перегляди дітей все одно реагують на клацання (тобто ваш погляд - це ViewGroup). Ви можете зробити щось на зразок:

private void hideTheChildren(View v){
    if(v instanceof ViewGroup) {
        int count = ((ViewGroup)v).getChildCount();
        for(int k = 0 ; k < count ; k++) {
            hideTheChildren(((ViewGroup)v).getChildAt(k));
        }
        v.setVisibility(View.GONE);
    }
    else {
        v.setClickable(false);
        v.setVisibility(View.GONE);
    }
}

звичайно, тоді вам також доведеться робити навпаки

private void showTheChildren(View v){
    if(v instanceof ViewGroup) {
        int count = ((ViewGroup)v).getChildCount();
        for(int k = 0 ; k < count ; k++) {
            showTheChildren(((ViewGroup)v).getChildAt(k));
        }
        v.setVisibility(View.VISIBLE);
    }
    else {
        v.setClickable(true);
        v.setVisibility(View.VISIBLE);
    }
}

Це працювало у мене в минулому. Наразі я не знаю кращого способу зробити це.


1
Через 8 років це все ще залишається проблемою. Це буде працювати, поки у вас немає іншого погляду позаду.
— Тамоксин,

1

Я хотів би опублікувати це як коментар, але, на жаль, я не зміг розмістити коментар. Оскільки це може бути можливим рішенням для вас, я публікую це так:

Коли ви пишете "onClick", я припускаю, що ви використовуєте onClickатрибут у своєму XML-макеті. Спробуйте встановити OnClickListenerа setOnClickListenerзамість onClickатрибута. Можливо, це допомагає ...


Дякуємо за відповідь. Я вже використовую setOnClickListener замість тегу xml.
— ShadowMare

1

Тим, хто відповів вище та все ще не вирішив проблеми, рекомендую видалити представлення з батьківського подання. Якщо вам потрібно знову відобразити подання, просто створіть копію та додайте його до батьківського подання.

Це може здатися надмірним, але я приховував / показував цілі групи переглядів, у вашому випадку це може бути кнопка, текстовий перегляд або зображення, це рішення все одно буде працювати.


2
Це насправді єдине, що мені вдалося. ПРИМІТКА. Я використовував подання, щоб покрити інший вигляд під BottomSheetBehaviorчас завантаження даних. З усіма іншими відповідями погляд продовжував перехоплювати дотики / жести. І це зламало мене BottomSheetBehaviour| Android 8.0 з design-support-lib 27.0.2
— Entreco


0

якщо у вас є анімація у вигляді, вам слід викликати view.clearAnimation.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.