A maioria dos aplicativos hoje em dia permite que os usuários interajam com os principais componentes deslizando, tocando duas vezes, pinçando, pressionando longamente etc. Quando implementado corretamente em seu aplicativo móvel, os gestos fornecem aos usuários uma experiência envolvente, natural e intuitiva. Na verdade, você pode substituir a maioria dos controles visíveis, como botões e cliques em ícones, por gestos.
Existem vários pacotes que você pode usar para implementar gestos em um aplicativo React Native. A biblioteca mais popular e recomendada é react-native-manipulador de gestos
. Esta biblioteca expõe toque e gestos nativos específicos da plataforma (ou seja, Android e iOS) para React Native.
Embora os gestos no React Native possam ser manipulados usando o Gesture Responder integrado System , esta implementação tem algumas limitações porque é executada no encadeamento JavaScript. Portanto, sempre que um evento de gesto é realizado, ele envia os dados pela ponte React Native para a interface, o que pode levar a um desempenho ruim.
React Native Gesture Handler permite que você implemente gestos de alto desempenho no React Native porque são executados no thread nativo e seguem o comportamento específico da plataforma, que por sua vez leva a um melhor desempenho.
A biblioteca React Native Gesture Handler vem com muitos gestos úteis, incluindo:
PanGestureHandler
TapGestureHandler
LongPressGestureHandler
PinchGestureHandler
Além dos gestos acima, também demonstraremos como implementar os gestos de puxar para atualizar, deslizar e tocar duas vezes.
Inicializando um novo aplicativo Expo
Começaremos inicializando um novo aplicativo Expo. Se você ainda não tem o Expo instalado em sua máquina, execute o comando abaixo:
# instalando expo CLI globalmente npm install--global expo-cli
Para criar um novo aplicativo Expo, execute o seguinte comando em seu terminal
# Crie um projeto chamado react-native-gestures expo init react-native-gestures
Navegue até o diretório do seu projeto e execute o seguinte comando para iniciar o seu aplicativo:
início da exposição
Pressione i
para abrir em um iOS simulador ou pressione a
para abrir em um Emulador Android ou dispositivo conectado . Certifique-se de que seu simulador ou emulador já esteja configurado.
Agora vamos começar a implementar e gerenciar gestos em nosso aplicativo React Native.
Gesto de panorâmica
Para implementar um gesto panorâmico no React Native usando o biblioteca react-nativa-gestual-manipuladora
, usaremos PanGestureHandler
. PanGestureHandler
é um gerenciador de gesto contínuo que gera fluxos de eventos de gesto quando o usuário move (arrasta) um elemento.
Para começar com o PanGestureHandler
, temos que importá-lo da biblioteca react-native-gesture-handler
que instalamos anteriormente:
import {PanGestureHandler} de'react-native-gesture-handler';
Em seguida, precisamos envolver o elemento ao qual queremos aplicar o gesto panorâmico com o componente PanGestureHandler
importado anteriormente:
//em seu bloco de retorno
Para fazer as coisas se moverem, precisamos usar os adereços básicos do gerenciador de gestos chamados onGestureEvent
e passar uma função de retorno de chamada para ele.
Vamos criar uma função, que passaremos mais tarde para o onGestureEvent
:
//não se esqueça de importar Animated from react native onPanGestureEvent=Animated.event ( [ { nativeEvent: { translationX: this.translateX, translationY: this.translateY, }, }, ], {useNativeDriver: true} );
Observe que estamos usando um componente de classe aqui.
Vamos passar a função que acabamos de criar para o prop onGestureEvent
no componente PanGestureHandler
.
Como queremos que nosso componente View
seja animado, vamos substituí-lo por Animated.View
e adicionar translateX
e translateY
propriedades em nossa matriz transform
para especificar a tradução do gesto panorâmico ao longo dos eixos X e Y.
Aqui está o código completo para criar gestos panorâmicos com React Native Gesture Handler:
import React, {Component} de'react'; import {StatusBar} de'expo-status-bar'; import {PanGestureHandler} de'react-native-Gesture-handler'; import {Animated, StyleSheet, Text} de'react-native'; exportar a classe padrão PanGesture extends Component { translateX=novo Animated.Value (0); translateY=novo Animated.Value (0); onPanGestureEvent=Animated.event ( [ { nativeEvent: { translationX: this.translateX, translationY: this.translateY, }, }, ], {useNativeDriver: true} ); render () { Retorna ( <>Manipulador de gestos panorâmicos > ); } } estilos const=StyleSheet.create ({ quadrado: { largura: 150, altura: 150, backgroundColor:'# 28b5b5', marginTop: 22, }, });
TapGestureHandler
Com TapGestureHandler
, podemos implementar gestos de toque único e duplo. Vamos começar com um gesto de toque único e, em seguida, passar para um gesto de toque duplo.
Gesto de toque único
Implementaremos o gesto de toque único usando o componente TapGestureHandler
. Observe que estamos adicionando adereços onHandlerStateChange
e passando uma função:
import {View, StyleSheet, Text} de'react-native'; import {TapGestureHandler, State} de'react-native-gesture-handler'; função padrão de exportação TapGesture () { const onSingleTapEvent=(event)=> { if (event.nativeEvent.state===State.ACTIVE) { alerta ('Ei, toque único!'); } }; Retorna ( <>Manipulador de gestos de toque duplo e único > ); }
Toque duas vezes
A principal diferença entre a implementação do gesto de toque único e duplo é o numberOfTaps
props, que é passado para o componente TapGestureHandler
. Observe que estamos passando 2
para numberOfTaps
para especificar que queremos acionar o retorno de chamada do evento onHandlerStateChange
:
import React, {useRef, useState} de'react'; import {View, StyleSheet, Text} de'react-native'; import {TapGestureHandler, State} de'react-native-gesture-handler'; função padrão de exportação TapGesture () { const [likeColour, setLikeColour]=useState ('# 28b5b5'); const doubleTapRef=useRef (null); const onDoubleTapEvent=(evento)=> { if (event.nativeEvent.state===State.ACTIVE) { likeColour==='# 28b5b5' ? setLikeColour ('red') : setLikeColour ('# 28b5b5'); } }; estilos const=StyleSheet.create ({ quadrado: { largura: 150, altura: 150, backgroundColor: likeColour, marginTop: 22, marginBottom: 22, }, }); Retorna ( <>Manipulador de gestos de toque duplo e único > ); }
Observe que estamos usando um componente funcional aqui porque estamos usando o gancho useRef
.
Implementação de toque único e duplo em um componente
Com TapGestureHandler
, podemos implementar um gesto em que um evento é chamado com um toque e outro com um toque duplo. Um bom exemplo disso é o aplicativo móvel LinkedIn, em que um único clique abre a postagem e um clique duplo gosta da postagem.
import React, {useRef, useState} de'react'; import {View, StyleSheet, Text} de'react-native'; import {TapGestureHandler, State} de'react-native-gesture-handler'; função padrão de exportação TapGesture () { const [likeColour, setLikeColour]=useState ('# 28b5b5'); const doubleTapRef=useRef (null); const onSingleTapEvent=(event)=> { if (event.nativeEvent.state===State.ACTIVE) { alert ('Ei, solteiro'); } }; const onDoubleTapEvent=(evento)=> { if (event.nativeEvent.state===State.ACTIVE) { likeColour==='# 28b5b5' ? setLikeColour ('red') : setLikeColour ('# 28b5b5'); } }; estilos const=StyleSheet.create ({ quadrado: { largura: 150, altura: 150, backgroundColor: likeColour, marginTop: 22, marginBottom: 22, }, }); Retorna ( <>Manipulador de gestos de toque duplo e único > ); }
Para fazer isso funcionar, precisamos adicionar o waitFor={doubleTapRef}
ao componente TapGestureHandler
de toque único. Quando o doubleTapRef
é verdadeiro, o on onSingleTapEvent
não será chamado.
Gesto deslizante
Para demonstrar como implementar um gesto deslizante, vamos criar uma lista de itens onde os usuários podem deslizar para a direita ou esquerda e certos eventos ou métodos são chamados.
Vamos criar um componente de lista plana e passar nossos dados para as propriedades data
:
item.id} renderItem={({item})=> } ItemSeparatorComponent={()=> } />
Observe que os props renderItem
estão retornando um componente ListItem
. Isso representa nossa lista de itens a fazer, conforme mostrado na demonstração acima.
Agora vamos criar nosso componente ListItem
e torná-lo deslizável.
Primeiro, importe o componente Swipeable
do pacote react-native-gesture-handler
:
import Swipeable de'react-native-gesture-handler/Swipeable';
Em seguida, envolva os componentes View
e Text
com o componente Swipeable
que importamos anteriormente. Com isso no lugar, nosso componente pode ser deslizado. Mas em um cenário do mundo real, você gostaria que algum tipo de evento ou função fosse chamado quando o usuário deslizar para a esquerda ou direita.
Para renderizar contêineres à esquerda, use os adereços renderLeftActions
e passe um componente. Para renderizar contêineres à direita, use os adereços renderRightActions
.
Ao deslizar para a esquerda, temos o contêiner delete
e ao deslizar para a direita, temos o contêiner bookmark
. As propriedades renderLeftActions
e renderRightActions
tornam isso possível.
Os adereços onSwipeableRightOpen
aceitam um método que é chamado quando o gesto de deslizar da direita para a esquerda é concluído-ou seja, quando o painel de ação direito é aberto. Os props onSwipeableLeftOpen
aceitam um método que é chamado quando o painel de ação esquerdo é aberto.
const ListItem=({text})=> (); {texto}
Aqui está o código completo para o gesto de deslizar:
import React from'react'; import { SafeAreaView, StyleSheet, Visualizar, Texto, Barra de status, FlatList, } de'react-native'; importar Swipeable de'react-native-ght-handler/Swipeable'; const todoList=[ {id:'1', texto:'Aprenda JavaScript'}, {id:'2', texto:'Aprenda a reagir'}, {id:'3', texto:'Aprenda TypeScript'}, ]; const Separator=()=>; const LeftSwipeActions=()=> { Retorna ( marca páginas ); }; const rightSwipeActions=()=> { Retorna ( Excluir ); }; const swipeFromLeftOpen=()=> { alerta ('Deslize da esquerda'); }; const swipeFromRightOpen=()=> { alerta ('Deslize da direita'); }; const ListItem=({text})=> ( ); const SwipeGesture=()=> { Retorna ( <> {texto} Deslize para a direita ou esquerda item.id} renderItem={({item})=> } ItemSeparatorComponent={()=> } /> > ); }; estilos const=StyleSheet.create ({ container: { flex: 1, }, itemSeparator: { flex: 1, altura: 1, backgroundColor:'# 444', }, }); exportar SwipeGesture padrão;
Segure/mantenha pressionado o gesto
Com o React Native Gesture Handler, implementar o gesto de manter/manter pressionado é simples.
Basicamente, precisamos envolver o componente React Native em que queremos implementar o gesto com LongPressGestureHandler
, que é importado de react-native-gesture-handler
, e em seguida, adicione os adereços onHandlerStateChange
, que acionam um método quando o usuário segura o componente por um determinado período. Para especificar a duração do toque longo, passamos minDurationMs
, que aceita um número expresso em milissegundos.
Aqui está o código para a demonstração mostrada acima:
import React from'react'; import {View, StyleSheet} from'react-native'; importar {LongPressGestureHandler, State} de'react-native-gesture-handler'; função padrão de exportação LongPressGesture () { const onLongPress=(evento)=> { if (event.nativeEvent.state===State.ACTIVE) { alerta ("Fui pressionado por 800 milissegundos"); } }; Retorna (); } estilos const=StyleSheet.create ({ caixa: { largura: 150, altura: 150, backgroundColor:'# 28b5b5', marginTop: 22, marginBottom: 22, }, });
Aperte para aplicar zoom
Assim como o nome indica, este é um gesto contínuo que rastreia a distância entre dois dedos e usa essa informação para dimensionar ou ampliar seu conteúdo.
render () { Retorna (); }
Para fazer isso funcionar, precisamos adicionar os adereços onGestureEvent
ao nosso PinchGestureHandler
e, em seguida, definir a {scale: this.scale}
objeto em nossa matriz transform
:
import React, {Component} de'react'; import {View, Image, StyleSheet, Animated} de'react-native'; importar {PinchGestureHandler, State} de'react-native-Gesture-handler'; exportar classe padrão PinchToZoom extends Component { baseScale=novo Animated.Value (1); pinchScale=novo Animated.Value (1); escala=Animated.multiply (this.baseScale, this.pinchScale); lastScale=1; onPinchGestureEvent=Animated.event ( [{nativeEvent: {scale: this.pinchScale}}], {useNativeDriver: true} ); onPinchHandlerStateChange=(evento)=> { if (event.nativeEvent.oldState===State.ACTIVE) { this.lastScale *=event.nativeEvent.scale; this.baseScale.setValue (this.lastScale); this.pinchScale.setValue (1); } }; render () { Retorna (); } } estilos const=StyleSheet.create ({ pinchableImage: { largura: 250, altura: 250, backgroundColor:'# 28b5b5', marginTop: 22, marginBottom: 22, }, });
Puxe para atualizar
Para implementar puxar para atualizar no React Native, você não precisa de uma biblioteca externa. Basta adicionar as propriedades onRefresh
, que aceita uma função no componente FlatList
e também define as propriedades refreshing
como booleanas.
//no topo do seu componente const [atualizando, setrefreshing]=useState (false);item.id} refrescando={refrescando} onRefresh={onRefresh} />
Por padrão, estamos definindo refreshing
como false
e então, quando o método onRefresh
é chamado, definimos o atualizando
estado para true
usando setrefreshing
:
Aqui está o código completo para a demonstração acima:
import React, {useState} de'react'; import { SafeAreaView, Visualizar, FlatList, StyleSheet, Texto, Barra de status, } de'react-native'; const DATA=[ { id:'1', título:'Tome café', }, { id:'2', título:'Escreva algum código', }, { id:'3', título:'Faça o teste', }, { id:'4', título:'Exercício', }, ]; Item const=({title})=> ({title} ); função padrão de exportação PullToRefresh () { const [atualizando, setrefreshing]=useState (false); const [dados, setdata]=useState (DATA); const onRefresh=()=> { setrefreshing (verdadeiro); setTimeout (()=> { setdata ((dados)=> [ ...dados, { id:'57878', título:'Dê um passeio no parque', }, ]); setrefreshing (falso); }, 2000); }; const renderItem=({item})=> ; Retorna ( item.id} refrescando={refrescando} onRefresh={onRefresh} /> ); } estilos const=StyleSheet.create ({ container: { flex: 1, marginTop: StatusBar.currentHeight || 0, }, item: { backgroundColor:'# fad586', preenchimento: 20, marginVertical: 8, marginHorizontal: 16, }, título: { fontSize: 20, }, });
Conclusão
Implementar gestos no React Native pode ajudar a melhorar a experiência do usuário e fazer com que seu aplicativo pareça natural para os usuários.
Neste tutorial, cobrimos a implementação e o gerenciamento de gestos em um aplicativo React Native, incluindo deslizar, deslocar, tocar duas e vezes uma vez, pinçar para aplicar zoom e muito mais.
Todo o código desta demonstração está disponível em GitHub .
A postagem React Native Gesture Handler: Deslizar, pressionar longamente e muito mais apareceu primeiro no LogRocket Blog .