Olá pessoal! Hoje, estamos compartilhando com você material cognitivo, cuja tradução foi preparada especificamente para os alunos do curso "ReactJS / React Native-developer" .
Então, vamos começar.
Todos nós vimos esses campos de entrada:

A legenda é grande e parece um espaço reservado até você se concentrar na entrada. Ele ficará menor e aumentará.
Parece ótimo. Sem problemas. Impecavelmente.
Parece também que apenas um desenvolvedor experiente pode fazer isso, certo?
Bem, talvez isso tenha acontecido antes do advento do React Native, naqueles dias em que as pessoas viviam em cavernas e criavam todo tipo de jogo. Mas isso é coisa do passado.
Você pode assistir ao vídeo ou continuar lendo. Tudo depende do que você preferir.
O que estamos tentando alcançar?
Existem duas opções para o que estamos lidando.
A primeira é quando não há foco no campo de entrada.

Uma inscrição aparece dentro do campo de entrada e seu tamanho é igual ao tamanho do campo de texto. A cor é opaca. Isso é muito semelhante à propriedade do
placeholder
.
E a segunda opção, quando há foco no campo de entrada.

A inscrição aparece acima do campo de entrada, seu tamanho é menor e a cor é diferente da cor do texto inserido.
Implementação mais simples
Finalmente, podemos começar a trabalhar. Até agora sem animações.
Como se vê, temos dois estados da interface do usuário:
- Não há foco no campo e na inscrição dentro do campo.
- Há um foco no campo, uma inscrição acima do campo de entrada.

De fato, poderíamos armazenar o estado de saber se há foco no campo ou não. Então, dependendo desse estado, poderíamos escolher onde colocar a inscrição e quais estilos aplicar a ela.
Como a inscrição deve estar em lugares diferentes, e não queremos que ela afete o posicionamento dos componentes, a posicionaremos absolutamente. Para garantir que haja espaço suficiente para isso, você precisará adicionar um recuo de cima na exibição de agrupamento.
class FloatingLabelInput extends Component { state = { isFocused: false, }; handleFocus = () => this.setState({ isFocused: true }); handleBlur = () => this.setState({ isFocused: false }); render() { const { label, ...props } = this.props; const { isFocused } = this.state; const labelStyle = { position: 'absolute', left: 0, top: !isFocused ? 18 : 0, fontSize: !isFocused ? 20 : 14, color: !isFocused ? '#aaa' : '#000', }; return ( <View style={{ paddingTop: 18 }}> <Text style={labelStyle}> {label} </Text> <TextInput {...props} style={{ height: 26, fontSize: 20, color: '#000', borderBottomWidth: 1, borderBottomColor: '#555' }} onFocus={this.handleFocus} onBlur={this.handleBlur} /> </View> ); } }
<FloatingLabelInput label="Email" value={this.state.value} onChange={this.handleTextChange} />
Após as etapas anteriores, podemos obter o seguinte:
https://snack.expo.io/Sk006AbdW?session_id=snack-session-JRMksbYK3E este é um bom ponto de partida. Até o momento, não temos animações, mas já podemos alterar a localização da inscrição, dependendo de onde o foco está.
Por que não usar um placeholder
?
Obviamente, o uso da propriedade TextInput
do espaço reservado parece tentador. No entanto, isso não funcionará, porque queremos controlar como, quando e onde a inscrição é exibida.
Em vez disso, queremos que o rótulo esteja dentro da caixa de texto quando o foco estiver nele. E queremos que ele suba quando o foco aparecer no campo de entrada, e isso só pode ser alcançado se trabalharmos com o mesmo elemento.
E a animação?
Na verdade, a parte mais fácil permaneceu.
Como temos dois estados nos quais pode haver uma inscrição, escolhemos um, dependendo do foco, e a animação dessa transição entre os próprios estados é bastante trivial.
Neste
guia, podemos destacar o seguinte:
Animated.Value
significa se há foco no campo (1) ou não (0);- Gradualmente, mudaremos o número para (1) quando focar e para (0) caso contrário;
- Na forma desse número, refletiremos o estilo da inscrição: em (0) e (1) definiremos estilos e o React Native calculará e aplicará automaticamente estilos intermediários. E até cores.
Implementar tudo isso não é difícil.
Animated.Value
, precisamos inicializar em
componentWillMount
.
componentWillMount() { this._animatedIsFocused = new Animated.Value(0); }
Então, como o valor desse número deve ser baseado no foco no campo de entrada ou não, e como já temos esse bit de informações de status, podemos adicionar a função
componentDidUpdate
, que mudará esse número dependendo
this.state
:
componentDidUpdate() { Animated.timing(this._animatedIsFocused, { toValue: this.state.isFocused ? 1 : 0, duration: 200, }).start(); }
Agora, para refletir o estilo da inscrição em tais termos, precisamos fazer apenas duas alterações:
Mude para
Animated.Text
.
Em vez de usar condições para definir estilos, defina-os da seguinte maneira:
const labelStyle = { position: 'absolute', left: 0, top: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: [18, 0], }), fontSize: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: [20, 14], }), color: this._animatedIsFocused.interpolate({ inputRange: [0, 1], outputRange: ['#aaa', '#000'], }), };
https://snack.expo.io/Hk8VCR-dZ?session_id=snack-session-AJ4vulSVwMais uma coisa
Se na demonstração acima você tentar inserir algo e remover o foco do campo de entrada, verá algo estranho.

Felizmente, isso é muito fácil de corrigir. Só precisamos alterar duas linhas no código.
Queremos verificar se o campo de entrada está vazio e alterar o estado para
"sem foco" apenas se as duas condições a seguir forem verdadeiras:
- O campo de entrada está vazio;
- Não há foco no campo.
Caso contrário, queremos que o estilo
"focado" seja aplicado e a legenda de substituição suba.
Agora que estamos rastreando o status do
campo de entrada , podemos acessar facilmente seu valor usando
this.props
.
https://snack.expo.io/ByZBAC-dZ?session_id=snack-session-YNZSqhqOC
Isso é tudo. Vejo você no
webinar gratuito .