web-dev-qa-db-fra.com

Comment animez-vous la hauteur en natif lorsque vous ne connaissez pas la taille du contenu?

Dans react-native, comment animer la taille d'une vue sans connaître la taille de son contenu?

Supposons que la hauteur du contenu de la vue puisse être comprise entre 0 et 400 points, que le contenu puisse être agrandi et réduit de façon dynamique et que vous souhaitiez animer les modifications apportées à la hauteur.

En gros, je cherche à reproduire le comportement de LayoutAnimation sans utiliser LayoutAnimation mais en utilisant Animated.

Je pense que ce qui m'échappe, c'est que je ne sais pas comment animer vers une hauteur cible car je ne connais pas la hauteur du contenu.

24
Poyan

J'utilise LayoutAnimation pour cela, juste avant le changement d'état qui provoque la modification de la hauteur de votre composant, ajoutez:

LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);

Vous pouvez utiliser différents préréglages:

11
Mahmoud Felfel

Vous allez devoir ajouter une sorte d’échelle de taille, probablement avec des pourcentages pour obtenir le meilleur effet.

Tout d’abord, vous devez utiliser Animated.View Au lieu de View.

Ensuite, vous devrez appliquer une transformation au style de la vue, ce qui signifie que celle-ci ressemble à celle ci-dessous. C'est la partie qui met à jour et change et crée la motion.

        <Animated.View style={[ styles.someStyleYouMade,
          {
            transform: [
              // scaleX, scaleY, scale, theres plenty more options you can find online for this.
              {  scaleX: ViewScaleValue } // this would be the result of the animation code below and is just a number.
            ]
          } 
        ]}
        >

Cette partie suivante est fondamentalement un exemple d’API animée, vous écririez quelque chose comme ceci (personnalisé selon votre choix) et lorsque ce script sera appelé, il s'animera de la manière que vous spécifiez.

  Animated.timing(                    // Animate over time
    this.state.ViewScale,             // The animated value to drive, this would be a new Animated.Value(0) object.
    {
      toValue: 100,                   // Animate the value
      duration: 5000,                 // Make it take a while
    }
  ).start();

Enfin, vous souhaiterez probablement appliquer une interpolation à la valeur pour la rendre aussi personnalisée que possible.

(cela ira dans votre fonction render() mais avant la return(). le ViewScaleValue ira dans la transformation Animated.View)

const ViewScaleValue = this.state.ViewScale.interpolate({
  inputRange: [0, 25, 50, 75, 100],
  outputRange: [0, .5, 0.75, 0.9, 1]
});

tout ce code ferait ViewScaleValue, un nombre simple, animer de 0 à 100, aller vite puis ralentir (à cause de l'interpolation) et appliquer chaque itération de l'animation à la transformation Animated.View.

Lisez l'API animée à côté de ceci pour bien le comprendre.

9

La méthode que j’ai choisie consiste à passer des passes de présentation à obtenir la hauteur du composant "tronqué" et celle du composant "taille réelle" (vous avez besoin d’un moyen de déterminer la hauteur tronquée, généralement en sachant rendre un "rangée" de contenu). Essentiellement, avant d'avoir ces valeurs, vous les présentez sous la forme de deux vues distinctes qui sont masquées:

hidden: {
  position: 'absolute',
  left: 0,
  top: 0,
  opacity: 0,
},

Utilisez onLayout pour capturer leurs sommets:

const onLayoutTruncated = ({nativeEvent}: LayoutChangeEvent) => {
  if (!doneProcessing) {
    truncatedHeight = nativeEvent.layout.height;
    checkIfDoneProcessingLayout();
  }
};

const onLayoutFull = ({nativeEvent}: LayoutChangeEvent) => {
  if (!doneProcessing) {
    fullHeight = nativeEvent.layout.height;
    checkIfDoneProcessingLayout();
  }
};

checkIfDoneProcessingLayout() vérifie si truncatedHeight et fullHeight sont définis et modifie leur état s'ils le sont (doneProcessing = true).

À partir de là, vous devriez afficher la vue tronquée et pouvoir animer les deux valeurs de hauteur à l'aide d'un Animated.Value Et d'une interpolation:

const expandingHeight = animatedValue.interpolate({
  inputRange: [0, 1],
  outputRange: [truncatedHeight, fullHeight],
});

Déclenchez l’animation de développement/réduction en cliquant sur en utilisant Animated.timing

Animated.timing(animatedValue, {toValue: isExpanded ? 0 : 1, easing: SOME_EASING_FUNCTION, duration: SOME_DURATION}).start();
1
sbearben