Is it possible to force the alignment of a specific child widget in a Wrap widget?

后端 未结 1 888
独厮守ぢ
独厮守ぢ 2021-01-05 18:46

I\'m trying to create a layout in flutter consisting of a row with two child widgets, the first aligned to the left and the second aligned to the right, that also will wrap

相关标签:
1条回答
  • 2021-01-05 19:28

    Thanks to Rémi Rousselet's advice to use a custom RenderBox here is a basic implementation that solves the layout problem (based off the Wrap widgets RenderBox implementation 1 2)

    import 'package:flutter/widgets.dart';
    import 'package:flutter/rendering.dart';
    import 'dart:math' as math;
    
    class LeftRightAlign extends MultiChildRenderObjectWidget {
      LeftRightAlign({
        Key key,
        @required Widget left,
        @required Widget right,
      }) : super(key: key, children: [left, right]);
    
      @override
      RenderLeftRightAlign createRenderObject(BuildContext context) {
        return RenderLeftRightAlign();
      }
    }
    
    class LeftRightAlignParentData extends ContainerBoxParentData<RenderBox> {}
    
    class RenderLeftRightAlign extends RenderBox
        with
            ContainerRenderObjectMixin<RenderBox, LeftRightAlignParentData>,
            RenderBoxContainerDefaultsMixin<RenderBox, LeftRightAlignParentData> {
    
      RenderLeftRightAlign({
        List<RenderBox> children,
      }) {
        addAll(children);
      }
    
      @override
      void setupParentData(RenderBox child) {
        if (child.parentData is! LeftRightAlignParentData)
          child.parentData = LeftRightAlignParentData();
      }
    
      @override
      void performLayout() {
        final BoxConstraints childConstraints = constraints.loosen();
    
        final RenderBox leftChild = firstChild;
        final RenderBox rightChild = lastChild;
    
        leftChild.layout(childConstraints, parentUsesSize: true);
        rightChild.layout(childConstraints, parentUsesSize: true);
    
        final LeftRightAlignParentData leftParentData = leftChild.parentData;
        final LeftRightAlignParentData rightParentData = rightChild.parentData;
    
        final bool wrapped =
            leftChild.size.width + rightChild.size.width > constraints.maxWidth;
    
        leftParentData.offset = Offset.zero;
        rightParentData.offset = Offset(
            constraints.maxWidth - rightChild.size.width,
            wrapped ? leftChild.size.height : 0);
    
        size = Size(
            constraints.maxWidth,
            wrapped
                ? leftChild.size.height + rightChild.size.height
                : math.max(leftChild.size.height, rightChild.size.height));
      }
    
      @override
      bool hitTestChildren(HitTestResult result, {Offset position}) {
        return defaultHitTestChildren(result, position: position);
      }
    
      @override
      void paint(PaintingContext context, Offset offset) {
        defaultPaint(context, offset);
      }
    }
    
    ...
    
    class HomePageState extends State<HomePage> {
      @override
      Widget build(BuildContext context) {
        return CupertinoPageScaffold(
          navigationBar: CupertinoNavigationBar(middle: Text('App')),
          child: ListView(children: <Widget>[
            Container(
              margin: EdgeInsets.symmetric(horizontal: 32, vertical: 16),
              child: LeftRightAlign(
                left: Text(
                  'Left Widget',
                  style: TextStyle(fontSize: 40),
                ),
                right: Text(
                  'Right Widget',
                  style: TextStyle(fontSize: 40),
                ),
              ),
            ),
            Text('Next Line'),
          ])
        );
      }
    }
    
    
    0 讨论(0)
提交回复
热议问题