AhmedLSayed9 / dropdown_button2

Flutter's core Dropdown Button widget with steady dropdown menu and many other features.
https://pub.dev/packages/dropdown_button2
MIT License
264 stars 122 forks source link

How can i create menu items with exactly height for each element #264

Open brunos0 opened 4 months ago

brunos0 commented 4 months ago

Hello.

I'm try to use Dropdown Button 2, but I having an issue about items heights. I have a list of strings with different length like:

ITEM 1 ITEM 2 AND ANOTHER DETAIL ITEM 3 AND ANOTHER SO LONG DETAIL ITEM 4 DETAIL ITEM 5 D3T41L ITEM 6 ITEM 7 AND ANOTHER AMAZING SO LOOOOONGGGGG DETAIL DESCRIPTION

I`m trying to calculate the height for each item, but even much similar description the height gets different and the result looks like:

ITEM 1 -------

ITEM 2 AND ANOTHER DETAIL ------- ITEM 3 AND ANOTHER SO LONG DETAIL ------- ITEM 4 DETAIL ------- ITEM 5 D3T41L

-------

.....

It's very difficult calculate the precise height for each element.

I'm create DropdownMenuItem like this:

 List<DropdownMenuItem<String>> _addDividersAfterItems(
    List<UniqueKey> keys,
    bool isSmallScreen,
  ) {
    final menuItems = <DropdownMenuItem<String>>[];

    for (var index = 0; index < values.length; index++) {
      menuItems.addAll(
        [
          DropdownMenuItem<String>(
            key: keys[index],
            value: values[index]['id'],
            child: Text(
              values[index]['nome'] ?? '',
              style: const TextStyle(
                fontSize: 14,
              ),
              softWrap: true,
            ),
          ),
          //If it's last item, we will not add Divider after it.
          if (index != values.length - 1)
            const DropdownMenuItem<String>(
              enabled: false,
              child: Divider(),
            ),
        ],
      );
    }

    return menuItems;
  }

And calculate the height like this:

  List<double> _getCustomItemsHeights(
    double textScaleFactor,
    bool isSmallScreen,
  ) {
    final itemsHeights = <double>[];
    var itemIndex = 0;
    for (var i = 0; i < (values.length * 2) - 1; i++) {
      if (i.isEven) {
        final textSpan = TextSpan(
          text: values[itemIndex]['nome'],
          style: const TextStyle(fontSize: 14),
        );

        final textPainter = TextPainter(
          text: textSpan,
          textDirection: TextDirection.ltr,
          textScaleFactor: textScaleFactor,
          textWidthBasis: TextWidthBasis.longestLine,
        );

        double height;
        int lineCount;

        if (isSmallScreen) {
          textPainter.layout(maxWidth: 250);
          lineCount = textPainter.computeLineMetrics().length;

          height = textScaleFactor >= 1.3
              ? 14 * lineCount * textScaleFactor
              : 14 * lineCount * textScaleFactor;
        } else {
          textPainter.layout(maxWidth: maxLineWidth(textScaleFactor));
          lineCount = textPainter.computeLineMetrics().length;

          height = textScaleFactor >= 1.3
              ? 13 * lineCount * textScaleFactor
              : 25 * lineCount * textScaleFactor;
        }

        if (itemIndex == 0 && lineCount == 1) {
          height += 10;
        }
        itemsHeights.add(height);
        itemIndex++;
      }
      //Dividers indexes will be the odd indexes
      if (i.isOdd) {
        itemsHeights.add(10);
      }
    }
    return itemsHeights;
  }

Ps. maxLineWidth function is a custom method to give me the maxWidth for the current textScaleFactor.

But I think that I a solve this problem in scale 1.0, another scales works fine too.

Exist a better way to calculate the line height or just shirink the container for DropdownMenuItem shows only Text and divider?

Sorry about my English.

Kind Regards.