91 votes

Faire en sorte que le widget du conteneur remplisse le parent verticalement

TL;DR Il faut que le conteneur remplisse l'espace vertical pour qu'il puisse agir comme un écouteur ontap. J'ai essayé la plupart des solutions mais rien ne semble fonctionner.

Ce que j'essaie de faire, c'est de faire en sorte que mon conteneur remplisse l'espace vertical tout en ayant une largeur fixe. Le premier est ce que j'ai et le troisième ce que je veux. . L'idée est d'avoir le conteneur transparent avec un écouteur de geste ontap. Si quelqu'un a une meilleure idée ou une solution différente, n'hésitez pas à la proposer.

Widget build(BuildContext context) {
return new GestureDetector(
  onHorizontalDragUpdate: _move,
  onHorizontalDragEnd: _handleDragEnd,
  child: new Stack(
    children: <Widget>[
      new Positioned.fill(           
        child: new Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            new Container(
              child: new IconButton(                          
                padding: new EdgeInsets.only(top: 16.0, bottom: 16.0, left: 24.0, right: 24.0),
                icon: new Icon(Icons.warning),
                color: Colors.black12,
                onPressed: () {},
              )
            ),
          ],
        ),
      ),
      new SlideTransition(
        position: new Tween<Offset>(
          begin:  Offset(0.0, 0.0),
          end: const Offset(-0.6, 0.0),
        ).animate(_animation),
        child: new Card(
          child: new Row(
            children: <Widget>[
              new Container(
                width: 20.0,
                height: 20.0,
                color: Colors.amber,
              ),
              new Expanded(
                child: new Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[

                    _getListTile(),
                    _ifStoplineIsToBeShown()
                  ],
                ),
              )
            ],
          )
        ),
      ),
    ],
  )
);

}

Je suis sûr que j'ai manqué quelque chose, car j'ai essayé beaucoup de choses différentes et rien ne semble fonctionner.

J'ai également téléchargé une image avec le tableau de débogage ici .

PS. Je sais que j'ai défini la hauteur à une valeur fixe, mais c'est la seule façon d'afficher le conteneur.

0 votes

Est onHorizontalDragStart ne pas être appelé ? Et où se trouve votre "largeur fixe" ?

124voto

Rémi Rousselet Points 45139

L'astuce consiste à combiner un IntrinsicHeight et un widget Row avec crossAxisAlignment: CrossAxisAlignment.stretch

Cela oblige les enfants de Row à s'étendre verticalement, mais Row prendra le moins d'espace vertical possible.

Card(
  child: IntrinsicHeight(
    child: Row(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Container(
          width: 20.0,
          color: Colors.amber,
        ),
        // Expanded(...)
      ],
    ),
  )
)

4 votes

Faut-il mentionner que IntrinsicHeight a des conséquences sur les performances ? docs.flutter.io/flutter/widgets/IntrinsicHeight-class.html

4 votes

Je ne pense pas. L'avertissement est là surtout pour vous mettre en garde contre l'utilisation de cette méthode lorsqu'une ConstraintBox est suffisant. Voici le cas d'utilisation prévu

0 votes

J'essaierai demain, mais ça semble prometteur. Merci à tous :)

94voto

Raj Points 221

Pour étirer le conteneur à la hauteur complète du parent, utilisez la propriété constraints:BoxConstraints.expand() dans le widget du conteneur. Le conteneur occupe tout l'espace indépendamment du widget enfant.

Container(
  color: Colors.green,
  child: Text("Flutter"),
  constraints: BoxConstraints.expand(),
)

Veuillez consulter le lien Aide-mémoire pour les conteneurs pour en savoir plus sur les conteneurs

5 votes

Cette réponse étant plus succincte, devrait-elle être utilisée à la place de la réponse acceptée ?

1 votes

Solution parfaite <3

0 votes

A fonctionné parfaitement

28voto

Omar Masri Points 1

À partir de janvier 2020, le plus simple sera d'utiliser un widget élargi.

Expanded(flex: 1,
         child: Container(..),
            ),

https://api.flutter.dev/flutter/widgets/Expanded-class.html

3 votes

Hey, j'ai essayé cette approche mais ça ne semble pas marcher. Pouvez-vous m'aider ? Le widget disparaît si je ne fixe pas la hauteur du conteneur qu'il contient.

10 votes

Il n'est pas nécessaire de définir flex: 1 puisque c'est la valeur par défaut

0 votes

Cela a fonctionné pour moi lorsque j'ai essayé d'étendre un conteneur à l'intérieur d'un widget de carte avec une colonne. J'ai un bouton matériel dans un conteneur à la fin de la carte que je voulais centrer dans la partie restante de la carte. Le problème de l'infini ne s'est pas posé. Merci !

24voto

user1032613 Points 2229

Il suffit de passer : double.infinity .

Si vous voulez qu'un conteneur remplisse tout l'espace disponible, vous pouvez simplement le faire passer :

width: double.infinity,
height: double.infinity

Explication :

Dans Flutter, un widget enfant ne peut pas dépasser les "contraintes de mise en page" imposées par son widget parent. Pendant la phase de mise en page, le moteur de Flutter utilise un solveur de contraintes pour corriger automatiquement les valeurs "hors limites" en fonction de ce qui est autorisé par les contraintes de son parent.

Par exemple, si vous avez un conteneur de 50x50, et que pour son enfant, vous passez un autre conteneur de 300x300, le conteneur intérieur sera automatiquement corrigé pour "ne pas dépasser son parent", donc 50x50. Par conséquent, en utilisant des valeurs suffisamment grandes, vous serez toujours sûr de "remplir le parent".

En fait, même BoxConstraints.expand() exploite la même idée en interne. Si vous ouvrez le code source de expand() vous verrez :

  /// Creates box constraints that expand to fill another box constraints.
  ///
  /// If width or height is given, the constraints will require exactly the
  /// given value in the given dimension.
  const BoxConstraints.expand({
    double width,
    double height,
  }) : minWidth = width ?? double.infinity,
       maxWidth = width ?? double.infinity,
       minHeight = height ?? double.infinity,
       maxHeight = height ?? double.infinity;

Ainsi, si vous êtes absolument certain de vouloir remplir tous les espaces, vous pouvez intuitivement passer un nombre plus grand que le parent (ou plus grand que l'écran entier), comme suit double.infinity .

0 votes

Les modifications apportées par Flutter à cette logique ont plus de chances de casser votre code si vous vous contentez d'imiter ce que Flutter fait sous le capot. Une meilleure pratique consiste à utiliser constraints: BoxConstraints.expand() .

0 votes

@andreyrk Merci ! Bien que votre déclaration soit généralement correcte, il n'y a cependant aucun risque ici. Le moteur de Flutter utilise le résolveur de contraintes pour forcer des valeurs plus grandes à se conformer à ce qui est autorisé par son parent, et c'est l'un des principes les plus fondamentaux derrière le fonctionnement de la mise en page de Flutter. BoxConstraints.expand() ne fait qu'exploiter le même fait. J'ai mis à jour ma réponse pour tenter de mieux l'expliquer. Si vous n'êtes pas familier avec ces sujets, vous pourriez vouloir regarder comment le moteur de Flutter exécute la mise en page sous le capot.

1 votes

C'est la voie à suivre. Simple à lire et à comprendre, sans ajouter un autre widget à l'arbre (du moins dans le code que vous voyez).

5voto

jitesh mohite Points 3119

Il y a beaucoup de réponses qui suggèrent d'utiliser deux choses

  1. contraintes : BoxConstraints.expand(),
  2. hauteur : double.infini,

Mais ces deux réponses vous donneront une erreur telle que

BoxConstraints force une hauteur infinie.

Nous pouvons éviter ces problèmes en calculant la hauteur de l'écran comme suit

  1. Barre d'application
  2. Espace de la barre supérieure (Existe sur la barre d'application ci-dessus)
  3. Écran restant

1. Obtenez la MediaQuery

 final mediaQuery = MediaQuery.of(context);

2. Déclarez le Widget AppBar et la même instance d'App Bar doit être utilisée dans l'App Bar de Scaffold.

final PreferredSizeWidget appBar = AppBar(
      title: Text('Home'),
    );

3. Utiliser la hauteur calculée

      Container(
              width: mediaQuery.size.width,
              height: (mediaQuery.size.height -
                  appBar.preferredSize.height -
                  mediaQuery.padding.top),
              color: Colors.red,
            ),

Sortie :

enter image description here

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