React native TouchableOpacity onPress не работает на Android

TouchabelOpacity отлично работает на iOS, но метод onPress у меня не работает на Android.

Моя версия для реагирования: 0.57.4

Мой код:

const initDrawer = navigation => (
  <TouchableOpacity
    style = {{ left: 16 }}
    onPress = {() => onPressDrawerButton(navigation)}
  >
    <Ionicons name = "ios-menu" color = "white" size = {30} />
  </TouchableOpacity>
);

Я могу подтвердить, что он отлично работает на Android с версией 0.57.7. Можете ли вы позволить себе обновление?

Benoit 30.11.2018 00:16
29
1
47 980
21

Ответы 21

У меня была такая же проблема, все кнопки TouchableOpacity работали нормально в сборке iOS, но в Android была одна, которая не срабатывала. Я наткнулся на этот ответь здесь, в котором упоминалось, что position: absolute испортит триггер. Это решило мою проблему.

Аналогичным образом я решил свою проблему. Что касается иерархии, у меня был вид в пределах осязаемой непрозрачности; Я добавлял позиционирование к представлению, предполагая, что Touchable Opacity примет и свое дочернее позиционирование, и вот в чем моя проблема, касание представления не привело бы к выполнению моего метода, потому что осязаемая непрозрачность имела другое позиционирование, чем его дочернее. Я решил это, сделав позиционирование на Touchable Opacity, а не на View. Надеюсь, это кому-то поможет.

user4414149 20.02.2020 15:40

Это тоже была моя проблема. Абсолютное положение препятствовало срабатыванию функции onPress. Спасибо за помощь, братан.

Jo Momma 02.06.2021 03:06

У меня была аналогичная проблема. Обратите внимание, откуда импортируйте ваш "TouchableOpacity". Когда я изменил "TouchableOpacity" с "response-native-gesture-handler" на "react-native", у меня это сработало (для платформы Android)

Должен быть ответ

Badr Filali 15.11.2019 11:36

Это действительный ответ

Shivansh Rajolia - HeLleR 22.02.2020 11:23

Я рекомендую добавить правило eslint без ограничений-импорта, запрещающее импорт из response-native-gesture-handler. 'no-restricted-imports': [ 'error', { paths: [ { name: 'react-native-gesture-handler', importNames: ['TouchableOpacity'], message: 'Import TouchableOpacity from react-native instead', }, ], }, ],

Sampo 07.04.2020 10:04

Для меня это сработало, когда я переключился с react-native на response-native-gesture-handler.

Amogh Jahagirdar 06.09.2020 09:54

этот автоматический импорт обработчика жестов rn невероятно раздражает

jovan 19.03.2021 16:54

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

Ali 29.05.2021 09:12

Удивительный! да, это тоже мое исправление.

Steve Pascoe 08.11.2021 04:00

Что касается меня, я использовал NativeBase и имел следующую структуру, которая ломалась на Android:

<List>
    <TouchableOpacity>
       <ListItem>
          <Text>Button</Text>
       </ListItem>
    </TouchableOpacity>
</List>

Как только я удалил ListItem и просто сделал текст прямым потомком TouchableOpacity, все заработало.

оберните значок в представлении следующим образом.

const initDrawer = navigation => (
  <TouchableOpacity
    style = {{ left: 16 }}
    onPress = {() => onPressDrawerButton(navigation)}
  >
    <View style = {{padding:5}}>
        <Ionicons name = "ios-menu" color = "white" size = {30} />
    </View>
  </TouchableOpacity>
);

затем, если проблема не исчезнет, ​​задайте для значка цвет backgroundColor, и вы увидите, что половина значка не имеет стиля backgroundColor, поэтому вам нужно увеличить размер отступа. Я не знаю, но у значков обычно проблемы с объемом, особенно в TouchableOpacity. Вот почему я сам делаю родительский View с отступом для значков. Еще кое-что, о чем упоминали и другие, это postion: 'absolute' prop, который мешает объему компонента.

Я забыл выполнить шаги по началу работы с Android для response-native-gesture-handler:

https://docs.swmansion.com/react-native-gesture-handler/docs/#android

Для меня это работало, но осязаемая область была очень маленькой. Почему-то область в iOS была больше, чем в Android.

В итоге я увеличил доступную для прикосновения область, используя свойство hitSlop, как показано ниже:

<TouchableOpacity
    onPress = {() => {}}
    hitSlop = {{ top: 30, bottom: 30, left: 30, right: 30 }}
>
    <Icon name = "eye" />
</TouchableOpacity>

Моей проблемы здесь не было, поэтому я хотел ее добавить.

На Android, если у вас есть TouchableOpacity внутри KeyboardAvoidingView, он не будет работать (по крайней мере, с теми настройками, которые я использовал).

Как только я ограничил область действия KeyboardAvoidingView только полями ввода, а не моими TouchableOpacities, он снова начал работать.

(Кстати, на IOS все было нормально)

Обнаружена такая же проблема. Убедитесь, что время вашего устройства совпадает с временем устройства, к которому оно подключено. В моем случае разница составляла 1 минуту, из-за чего все функции TouchableOpacity не работали.

В некоторых случаях собственный отладчик не работает должным образом на платформах iOS и Android, и я обнаружил, что у TouchableOpacity есть ошибки касания на Android с включенным отладчиком. Попробуйте отключить это, после сборки все будет нормально!

Это именно то, что я нашел! Как странно. Вы нашли причину этой проблемы?

Jaap Weijland 02.12.2020 10:31

@JaapWeijland Я думаю, что кое-что нашел в этом, но у меня все еще не было времени проверить это. Проверьте это: github.com/facebook/react-native/issues/…

Gabriel Felipe 09.03.2021 21:25

Я тоже это обнаружил. Похоже, что в моем случае это действительно было причиной этого.

Jaap Weijland 10.03.2021 11:33

в моем случае я импортировал TouchableOpacity из «response-native-gesture-handler» после того, как я добавил его из "react-native", он сработал

да, это сработало, но почему не работает при импорте его из react-native ??

Mohamed Elmancy 23.09.2021 22:41

Прекращение - сервер метро (в случае, если он сейчас работает), а затем Бег - все это снова (как показано ниже) сработало для меня.


на консоли, на которой запущен метросервер, прекратить это

ctrl + c

затем на другой консоли бегать ваше приложение

react-native run-android

или

npx react-native run-android

Хотя следующая проблема вызвана недавними выпусками React Native, я думаю, что это может помочь людям, столкнувшимся с этой проблемой в последнее время.

Это может быть вызвано несоответствием между временем на вашем устройстве и временем на машине разработки при использовании Режим отладки. Я исправил это, выключив и включив автоматические настройки времени на моем устройстве, что «переопределило» время, заставив его синхронизироваться с моей машиной разработки.

Эта проблема связана с этим:

https://github.com/facebook/react-native/issues/27008

Была та же проблема - в моем случае это был элемент, отображаемый внутри TouchableOpacity с помощью position: 'absolute' и пропорциональный TouchableOpacity, я добавил zIndex: 0 к этому элементу, чтобы он работал.

Для меня сработало удаление «flex: 1» из всех родительских элементов.

Это то, что сработало для меня, но не смог воспроизвести ошибку в закуске или понять, что ее вызывает. Можно избежать использования гибкости, но это нежелательно. Кто-нибудь еще понимает, почему свойство flex: 1 в родительском элементе (иногда на нескольких узлах в цепочке) может отключать любые события onPress для дочерних элементов?

Benjamin Lee 25.03.2021 21:14

<TouchableOpacity
       style = {{backgroundColor: 'red', width: 50, height: 50, zIndex: 1}}
       onPress = {() => alert('working')}>
       <Text>tset</Text>
 </TouchableOpacity>

zIndex: 1 работает как по волшебству.

Проверьте библиотеку, из которой вы импортируете сенсорную прозрачность. Импортируйте его из "react-native". не из "реагировать-родного-жестового обработчика"

Использовать это

import { TouchableOpacity } from 'react-native';

вместо этого

import { TouchableOpacity } from 'react-native-gesture-handler';

если вы используете абсолютное положение. используйте z Index для регистрации кликов для TouchableOpacity

touchableOpacity: {
alignItems: 'center',
justifyContent: 'center',
width: 30,
height: 25,
zIndex: 1,
position: 'absolute',
left: 5},

Проверьте, работает ли нажатие Touchable дольше. В моем случае я тестировал на телефоне Android, и рендеринг нескольких TouchableOpacity замедлил работу телефона: если я коснусь компонента слишком быстро, он не будет зарегистрирован как действительный пресс.

Согласно официальному документу на onPress, это отменит недействительную печать: https://reactnative.dev/docs/touchablewithoutfeedback#onpress

В этом случае вы можете использовать onPressOut или onPressIn вместо onPress, чтобы убедиться, что ваше прикосновение всегда актуально.

спасибо тебе огромное, это сработало для меня, и я был так близок к тому, чтобы сошел с ума :)

yasin demir 21.09.2021 09:59

У меня была аналогичная проблема только для устройств серии Samsung S. Мой TochableOpacity работал нестабильно и пару месяцев пытался найти решение. Это исправило это. Спасибо

Saran Raj 10.10.2021 11:04

Если это кому-то поможет,

Старый код

<TouchableOpacity onPress = {()=>{callback()}} >
   <View style = {styles.action}>
      <MaterialCommunityIcons name = "close-thick" size = {25} color = {colors.white} style = {styles.icon}/>
   </View>
</TouchableOpacity>

Исправить

<TouchableOpacity onPress = {()=>{callback()}} style = {styles.action}>
   <View style = {{flex:1}}>
      <MaterialCommunityIcons name = "close-thick" size = {25} color = {colors.white} style = {styles.icon}/>
   </View>
</TouchableOpacity>

В моем случае на android TouchableOpacity отрисовывается (что ожидалось, поскольку позиция не абсолютна) из представления (которое имеет абсолютную позицию) внутри него. Добавление borderWidth и borderColor в TouchableOpacity показало, что они были отрисованы вдали от представления. Переключение стилей с дочернего представления на TouchableOpacity устранило проблему.

Для меня проблема заключалась в том, что пресса не регистрировалась на Android на TouchableWithoutFeedBack. Импорт из react-native-gesture-handler или react-native ничего не изменил.

Чтобы решить эту проблему, я импортировал TouchableOpacity из 'react-native' и использовал его вместо activeOpacity = {1}, который предотвращает изменение непрозрачности при нажатии. Это дает мне поведение TouchableWithoutFeedback, но работает на Android.

На самом деле я поменял его на Pressable, и он тоже работал

Я попробовал все другие ответы, но не смог заставить его работать. В моем случае у меня был родительский контейнер со следующими стилями:

.parentContainer {
    height: '100%',
    width: '100%',
    position: 'absolute',
    top: '-20%'
}

Я понял, что дочерние элементы вышли за пределы родительского контейнера, и хотя это не было большой проблемой с точки зрения стиля, все компоненты TouchableOpacity, которые вышли за пределы родительского контейнера, не работали (событие onPress не сработало). По сути, любой компонент TouchableOpacity, который оказался в нижних 20% экрана, не работал, потому что родительский элемент был перемещен на 20% вверх (вверху: «-20%»). Все, что мне нужно было сделать, это изменить высоту родительского контейнера с 100% на 120%, и он начал работать, как ожидалось.

Другие вопросы по теме