Як передати подію onClick перегляду своєму батьківському на Android?


100

У мене TextView в макеті, фоном якого є селектор. І текст TextView встановлений на Spanned від HTML. Потім я встановлюю TextView методом LinkMovementMethod.

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

Як це слід вирішити?

Відповіді:


45

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

Activity.dispatchTouchEvent(MotionEvent) - Це дозволяє Вашій діяльності перехоплювати всі торкаються подій, перш ніж вони будуть відправлені у вікно.

ViewGroup.onInterceptTouchEvent(MotionEvent) - Це дозволяє ViewGroup дивитись події під час їх надсилання до дочірніх переглядів.

ViewParent.requestDisallowInterceptTouchEvent(boolean) - Зателефонуйте цьому на батьківський перегляд, щоб вказати, що він не повинен перехоплювати події дотику з onInterceptTouchEvent (MotionEvent).

Більше інформації тут .

Сподіваюся, що це допомагає.


1
Чи є простіший спосіб передавати події, щоб викликати onClick і onLongClick у батьківському перегляді, або я повинен їх реалізувати сам?
шиямі

Перевірте це: stackoverflow.com/questions/2136696/pass-event-to-parent-view Можливо, ви можете спробувати передати того самого слухача кліків іншим екземплярам, ​​як було запропоновано, хоча я не знаю, чи він спрацює , але, можливо, варто спробувати.
Луїс Мігель Серрано

Відповідь нижче набагато чіткіша
JPM

Чи варто інстанціювати MotionEvent? Будь ласка, поясніть, @LuisMiguelSerrano
olegario

@olegario, зазвичай ви переосмислюєте метод, наприклад, для dispatchTouchEvent, за допомогою @Override, щоб визначити нову поведінку для нього, тому ви просто отримуєте подію руху, яку система надала вашій діяльності (або іншому компоненту вашої програми), і ви обробляти його та / або пересилати будь-яку кількість компонентів дітей відповідно до власних правил. Щось на кшталт: @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
Луїс Мігель Серрано

212

Заявіть, що TextViewне можна натискати / орієнтуватися, використовуючи android:clickable="false"та android:focusable="false"або v.setClickable(false)та v.setFocusable(false). Події клацання зараз слід відправити TextViewбатькові батька.

Примітка:

Для того, щоб досягти цього , вам потрібно додати клацання до його прямого parent. або встановити android:clickable="false"і android:focusable="false"його безпосередній батько передати слухач подальшого батькові .


1
О людино, якби я міг дати це +100, я б. Ви намагалися розібратися, як змусити працювати лише з клацанням у ViewPager, а не в макеті адаптерів за допомогою TouchImageView, що реалізує OnTouch! Це рішення спрацювало як шарм.
JPM

1
але що робити, якщо я хочу обробити подію Focus change EditText?
SweetWisher ツ

2
Сценарій такий: у мене є макет, який містить редакційний текст, відносний макет, спінер і подання списку. Я хочу запустити подію батьківського макета, коли я торкаюсь будь-якого місця на екрані, окрім редакційного тексту та
спінера

9
Щось важливо пам’ятати, це те, що якщо ви користуєтесь TextView#setOnClickListener()на TextView, він стає доступним для натискання, навіть якщо він оголошений як android:clickable="false", і навіть якщо значення параметра ClickListenerвстановлено на null( setOnclickListener(null))
Крістіан Гарсія

3
Факт забави: якщо в TextView є android:inputTypeатрибут, він мовчки споживає події кліку навіть з натисканням: false і focusable: false; в моєму випадку це було встановлено в стилі, і мені знадобилося 30 хвилин, щоб з'ясувати причину.
Кирило Кармазін

18

Десь тільки це допомагає:

View child = parent.findViewById(R.id.btnMoreText);
    child.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            View parent = (View) v.getParent();
            parent.performClick();
        }
    });

Інший варіант, працює не завжди:

child.setOnClickListener(null);

Це спрацьовувало CardViewяк дитячий погляд, оскільки, CardViewздається, ігнорує clickable="false"і focusable="false". Однак використання setOnTouchListenerта виклик onTouchEventбатька натомість дозволяє батькові відображати зворотній зв'язок із дотиком (наприклад, ефект пульсації).
методи

Я розмістив відповідний код нижче: stackoverflow.com/a/52928884/5652513 .
методи

10

Покладіть

android:duplicateParentState="true"

У дитини тоді погляди отримують його стан, який можна зрозуміти (зосереджений, притиснутий і т. д.) від свого безпосереднього батька, а не від самого себе. Ви можете встановити onclick для батьків, і це дзвінок, коли дитина натиснув


ОП хоче викликати слухача батьків, коли натискають дитину, а не навпаки.
Фарид

3

Якщо ви TextViewстворюєте проблеми з натисканням, видаліть android:inputType=""із файлу xml


Якщо ви не знаєте чому, рекомендую вам цього не робити. Просто кажучи ... кожному своє.
dell116

Ви повинні встановити йогоandroid:inputType="none"
AZ_

1

Ця відповідь схожа на відповідь Олександра Ухова , за винятком того, що вона використовує сенсорні події, а не події клацання. Ці події дозволяють батькові відображати правильні натиснуті стани (наприклад, ефект пульсації). Ця відповідь також є в Котліні замість Java.

view.setOnTouchListener { view, motionEvent ->
    (view.parent as View).onTouchEvent(motionEvent)
}

0

Якщо ви хочете, щоб і те, OnTouchі OnClickслухач батьків і дітей переглядали і те, і інше, скористайтеся нижче фокусом:

  1. Користувальний ScrollView як батьківський вигляд і всередині, яке розмістило ваше подання дитини у Relative / LinearLayout

  2. Зробіть батьківський ScrollView, android:fillViewport="true"щоб Перегляд не прокручувався.

  3. Потім встановіть OnTouchслухача для батьків і OnClickслухача для подання дитини. І насолоджуйтесь обома відкликами слухачів.

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