98 votes

Comment mettre une icône à l'intérieur d'un TextInput dans React Native ?

Je pense avoir quelque chose comme ceci https://Android-arsenal.com/details/1/3941 où vous avez une icône sur laquelle vous appuyez pour afficher le mot de passe en clair, et non sous forme de points. Cependant, je n'ai pas réussi à trouver un composant personnalisé qui pourrait m'aider.

Je ne veux pas consacrer trop de temps à une fonction aussi mineure, c'est pourquoi je pose la question sans avoir encore tenté quoi que ce soit : Y a-t-il un composant personnalisé que j'ai manqué ? Sinon, existe-t-il un moyen simple d'ajouter des enfants à TextInput ? Ou devrais-je simplement avoir TextInput et Touchable côte à côte ?

148voto

Anton Artemev Points 577

Vous pouvez utiliser une combinaison de View, Icon et TextInput comme suit :

<View style={styles.searchSection}>
    <Icon style={styles.searchIcon} name="ios-search" size={20} color="#000"/>
    <TextInput
        style={styles.input}
        placeholder="User Nickname"
        onChangeText={(searchString) => {this.setState({searchString})}}
        underlineColorAndroid="transparent"
    />
</View>

et utiliser la direction de flexion pour le style

searchSection: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
},
searchIcon: {
    padding: 10,
},
input: {
    flex: 1,
    paddingTop: 10,
    paddingRight: 10,
    paddingBottom: 10,
    paddingLeft: 0,
    backgroundColor: '#fff',
    color: '#424242',
},

Les icônes proviennent de "react-native-vector-icons".

1 votes

C'est la façon de procéder si vous ne voulez pas utiliser une bibliothèque. Remarque : si vous voulez que l'icône "disparaisse", vous devez passer une propriété pour savoir si une recherche est active ou non, et ensuite basculer la visibilité de l'icône en fonction de cette propriété de recherche.

48voto

linasmnew Points 2079

En fait, il est impossible de placer une icône à l'intérieur d'un textInput, mais vous pouvez le simuler en l'intégrant dans une vue et en définissant quelques règles de style simples.

Voici comment cela fonctionne :

  • mettre les deux Icône et TextInput à l'intérieur d'un Vue parentale
  • set flexDirection du parent à "rangée qui alignera les enfants les uns à côté des autres
  • donner TextInput flex 1 afin qu'il prenne toute la largeur de la vue parent.
  • donner Vue parentale a borderBottomWidth et pousser cette frontière vers le bas avec paddingBottom (cela le fera apparaître comme un textInput normal avec un borderBottom)
    • (ou vous pouvez ajouter n'importe quel autre style en fonction de l'aspect que vous souhaitez lui donner)

Code :

<View style={styles.passwordContainer}>
  <TextInput
    style={styles.inputStyle}
      autoCorrect={false}
      secureTextEntry
      placeholder="Password"
      value={this.state.password}
      onChangeText={this.onPasswordEntry}
    />
  <Icon
    name='what_ever_icon_you_want'
    color='#000'
    size={14}
  />
</View>

Le style :

passwordContainer: {
  flexDirection: 'row',
  borderBottomWidth: 1,
  borderColor: '#000',
  paddingBottom: 10,
},
inputStyle: {
  flex: 1,
},

(Remarque : l'icône se trouve sous le TextInput et apparaît donc à l'extrême droite, si elle était au-dessus du TextInput, elle apparaîtrait à gauche).

2 votes

C'est génial ! Une amélioration consiste à ajouter alignItems: 'center' à passwordContainer afin de centrer verticalement l'entrée et l'icône

3voto

Léo Points 209

Vous pouvez utiliser ce module qui est facile à utiliser : https://github.com/halilb/react-native-textinput-effects

0 votes

Cela semble correct, mais dans l'exemple et le fichier readme, rien n'indique que les icônes puissent réagir à une pression.

1 votes

Si vous faites un fork du projet, vous pouvez envelopper l'icône avec '<TouchableHighlight />'.

3voto

Sobol Roman Points 81

Vous pouvez envelopper votre TextInput sur View .

<View>
  <TextInput/>
  <Icon/>
<View>

et calculer dynamiquement la largeur, si vous voulez ajouter une icône,

iconWidth = 0.05*viewWidth 
textInputWidth = 0.95*viewWidth

sinon textInputwWidth = viewWidth .

View et TextInput la couleur de fond sont toutes deux blanches. (Petite modification)

0voto

Facundo La Rocca Points 2274

Voici un exemple que j'ai pris dans mon propre projet, j'ai juste enlevé ce que je pensais ne pas être nécessaire pour l'exemple.

import React, { Component } from 'react';
import {
  Text,
  TouchableOpacity,
  View,
  StyleSheet,
  Dimensions,
  Image
} from 'react-native';

class YourComponent extends Component {
  constructor(props) {
    super(props);

    this._makeYourEffectHere = this._makeYourEffectHere.bind(this);

    this.state = {
        showPassword: false,
        image: '../statics/showingPassImage.png'
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity style={styles.button} onPress={this._makeYourEffectHere}>
          <Text>button</Text>
          <Image style={styles.image} source={require(this.state.image)}></Image>
        </TouchableOpacity>
        <TextInput password={this.state.showPassword} style={styles.input} value="abc" />
      </View>
    );
  }

  _makeYourEffectHere() {
    var png = this.state.showPassword ? '../statics/showingPassImage.png' : '../statics/hidingPassImage.png';
    this.setState({showPassword: !this.state.showPassword, image: png});
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
    justifyContent: 'center',
    flexDirection: 'column',
    alignItems: 'center',
  },
  button: {
    width: Dimensions.get('window').width * 0.94,
    height: 40,
    backgroundColor: '#3b5998',
    marginTop: Dimensions.get('window').width * 0.03,
    justifyContent: 'center',
    borderRadius: Dimensions.get('window').width * 0.012
  },
  image: {
    width: 25,
    height: 25,
    position: 'absolute',
    left: 7,
    bottom: 7
  },
  input: {
    width: Dimensions.get('window').width * 0.94,
    height: 30
  }
});

module.exports = YourComponent;

J'espère que cela vous aidera.

Faites-moi savoir si c'était utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X