208 votes

Comment obtenir la hauteur d'un Widget ?

Je ne comprends pas comment LayoutBuilder est utilisé pour obtenir la hauteur d'un Widget.

J'ai besoin d'afficher la liste des widgets et d'obtenir leur hauteur afin de pouvoir calculer certains effets de défilement spéciaux. Je développe un paquet et d'autres développeurs fournissent des widgets (je ne les contrôle pas). J'ai lu que LayoutBuilder peut être utilisé pour obtenir la hauteur.

Dans un cas très simple, j'ai essayé d'envelopper le widget dans LayoutBuilder.builder et de le placer dans la pile, mais j'obtiens toujours les résultats suivants minHeight 0.0 et maxHeight INFINITY . Est-ce que j'utilise mal le LayoutBuilder ?

EDIT : Il semble que LayoutBuilder soit un échec. J'ai trouvé le CustomSingleChildLayout ce qui est presque une solution.

J'ai étendu ce délégué, et j'ai pu obtenir la hauteur du widget en getPositionForChild(Size size, Size childSize) méthode. MAIS, la première méthode qui est appelée est Size getSize(BoxConstraints constraints) et comme contraintes, j'obtiens 0 à INFINITY parce que je pose ces CustomSingleChildLayouts dans une ListView.

Mon problème est que SingleChildLayoutDelegate getSize fonctionne comme si elle avait besoin de retourner la hauteur d'une vue. Je ne connais pas la hauteur d'un enfant à ce moment-là. Je ne peux que renvoyer constraints.smallest (qui est 0, la hauteur est 0), ou constraints.biggest qui est infini et fait planter l'application.

Dans les docs, il est même dit :

...mais la taille du parent ne peut pas dépendre de la taille de l'enfant.

Et c'est une limitation bizarre.

1 votes

LayoutBuilder vous donnera les contraintes de boîte du parent. Si vous voulez les tailles des enfants, vous devez utiliser une stratégie différente. Un exemple que je peux citer est le widget Wrap, qui effectue la mise en page en fonction de la taille de ses enfants dans la classe RenderWrap associée. Mais cela se produit pendant la mise en page, et non pendant la fonction build().

0 votes

@JonahWilliams Hmm. Je ne vois pas comment Wrap peut m'aider puisque c'est un widget conçu pour disposer les enfants autour (fonctionne quelque chose comme la grille flexbox du web). J'ai un widget enfant dont j'ai besoin de trouver la hauteur. Veuillez voir l'édition dans la question. J'ai presque résolu le problème avec CustomSingleChildLayout mais je suis resté bloqué sur ses limites.

0 votes

Pouvez-vous expliquer plus précisément ce que vous voulez ? Il existe de multiples solutions. Mais chacune a des cas d'utilisation différents.

0voto

qqzhao Points 1

Utiliser le paquet : z_tools . Les étapes :

1. changer le fichier principal

void main() async {
  runZoned(
    () => runApp(
      CalculateWidgetAppContainer(
        child: Center(
          child: LocalizedApp(delegate, MyApp()),
        ),
      ),
    ),
    onError: (Object obj, StackTrace stack) {
      print('global exception: obj = $obj;\nstack = $stack');
    },
  );
}

2. utiliser en fonction

_Cell(
    title: 'cal: Column-min',
    callback: () async {
        Widget widget1 = Column(
        mainAxisSize: MainAxisSize.min,
        children: [
            Container(
            width: 100,
            height: 30,
            color: Colors.blue,
            ),
            Container(
            height: 20.0,
            width: 30,
            ),
            Text('111'),
        ],
        );
        // size = Size(100.0, 66.0)
        print('size = ${await getWidgetSize(widget1)}');
    },
),

0voto

Drashyr Points 1157

C'est facile et cela peut encore être fait dans StatelessWidget.

class ColumnHeightWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final scrollController = ScrollController();
    final columnKey = GlobalKey();

    _scrollToCurrentProgress(columnKey, scrollController);

    return Scaffold(
      body: SingleChildScrollView(
        controller: scrollController,
        child: Column(
          children: [],
        ),
      ),
    );
  }

  void _scrollToCurrentProgress(GlobalKey<State<StatefulWidget>> columnKey,
      ScrollController scrollController) {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      final RenderBox renderBoxRed =
          columnKey.currentContext.findRenderObject();
      final height = renderBoxRed.size.height;
      scrollController.animateTo(percentOfHeightYouWantToScroll * height,
          duration: Duration(seconds: 1), curve: Curves.decelerate);
    });
  }
}

de la même manière, vous pouvez calculer la hauteur de n'importe quel widget enfant et le faire défiler jusqu'à cette position.

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