Home > Back-end >  Flutter: Dynamic Height of Widgets must be multiple of a given number
Flutter: Dynamic Height of Widgets must be multiple of a given number

Time:12-04

The widgets have different heights, that are dynamic. I need the height to be a multiple of 20, so it fits in the grid I created.

Is there a possibility to force the widgets to increase their height by 20 pixels at a time if they need to expand?

In othe words I need it to snap to a grid I pre defined.

import 'package:flutter/material.dart';

class TreeNode extends StatelessWidget {
  const TreeNode({
    Key? key,
    required this.child,
    required this.minSize,
    required this.maxSize,
  }) : super(key: key);

  final Widget child;
  final int minSize, maxSize;

  @override
  Widget build(BuildContext context) {
    return FittedBox(
      child: Container(
        color: Colors.green,
        width: MediaQuery.of(context).size.width <= 400
            ? minSize.toDouble()
            : maxSize.toDouble(),
        height: 200, // needs to be changed
        child: Visibility(
          visible: true,
          child: child,
          maintainSize: true,
          maintainState: true,
          maintainAnimation: true,
        ),
      ),
    );
  }
}

Thanks for your help. Example of how it looks now:

EDIT: I figured it out. For anybody else who has a similar Problem.

I used IntrinsicWidth() with stepHeight and stepWidth It may be quite expensive to do, but it fits my needs.

New Code:

import 'package:flutter/material.dart';

class TreeNode extends StatelessWidget {
  const TreeNode({
    Key? key,
    required this.child,
    required this.minSize,
    required this.maxSize,
  }) : super(key: key);

  final Widget child;
  final int minSize, maxSize;

  @override
  Widget build(BuildContext context) {
    return IntrinsicWidth(
      stepHeight: 20,
      stepWidth: 20,
      child: Container(
        color: Colors.green,
        width: MediaQuery.of(context).size.width <= 400
            ? minSize.toDouble()
            : maxSize.toDouble(),
        child: Visibility(
          visible: false,
          child: child,
          maintainSize: true,
          maintainState: true,
          maintainAnimation: true,
        ),
      ),
    );
  }
}

CodePudding user response:

To add 20 px: height 20.0;

To multiply just add a factor of your choice (can also be dynamic): height * 1.5 or height * dynamicFactor.

If you want do to it conditionally, you can add a boolean shouldMultiply and use it to toggle like this: givenValue * (shouldMultiply ? 20 : 1);

Using your code example:

import 'package:flutter/material.dart';

class TreeNode extends StatelessWidget {
  const TreeNode({
    Key? key,
    required this.child,
    required this.minSize,
    required this.maxSize,
  }) : super(key: key);

  final Widget child;
  final int minSize, maxSize;
  final factor = 1.15; //  15%
  bool requiresFactor; // Either change this via method you define and hook up to
                       // the ontap handler of a gesture detector (which can wrap your FittedBox),

  @override
  Widget build(BuildContext context) {
    return FittedBox(
      child: Container(
        color: Colors.green,
        width: MediaQuery.of(context).size.width <= 400
            ? minSize.toDouble()
            : maxSize.toDouble(),
        height: 200   (requiresFactor ? 20.0 : 0.0),
        // or height: 200 * (shouldMultiply ? factor : 1),
        child: Visibility(
          visible: true,
          child: child,
          maintainSize: true,
          maintainState: true,
          maintainAnimation: true,
        ),
      ),
    );
  }
}

Edit (as the OP figured out correctly): The IntrinsicWidth class can be used to snap to a multiple of the stepWidth or stepHeight with their respective properties to be set to a non-null value. [WARNING:] However, as the docs warn you "This class is relatively expensive, because it adds a speculative layout pass before the final layout phase. Avoid using it where possible.". Hence, you should consider writing your own simplified "work-around" logic for your case, as this class is not really necessary here. So, definitely try it out - if you find an obstacle update your question, comment me and I´ll try my best to help you out :)

  • Related