在 Flutter 的扩展面板列表中展开时,有没有办法消除扩展面板之间的间距?

var*_*kun 6 margin expandablelistview dart flutter flutter-layout

我遇到了一个问题,我想在扩展面板时删除扩展面板列表的扩展面板之间的空间。

不良行为的图像,这些图像取自 flutter 文档:

未展开时列出,这很好:

在此处输入图片说明

展开时列出: - 您可以看到各部分之间的差距。这是我不想要的应用程序。

在此处输入图片说明

任何提示表示赞赏。

小智 7

您最好复制并expansion_panel.dart使用它,而不是更改源代码。为了使项目之间的空格消失,您必须注释掉第 486 和 487 行。

if (_isChildExpanded(index) && index != 0 && !_isChildExpanded(index - 1))
items.add(MaterialGap(key: _SaltedKey<BuildContext, int>(context, index * 2 - 1)));
Run Code Online (Sandbox Code Playgroud)

第 558 行和第 559 行。

if (_isChildExpanded(index) && index != widget.children.length - 1)
items.add(MaterialGap(key: _SaltedKey<BuildContext, int>(context, index * 2 + 1)));
Run Code Online (Sandbox Code Playgroud)

您可能想要修复的该组件的另一个问题是属性canTapOnHeader。将其设置为 true 可以让您点击卡片并展开,但卡片右侧会出现一堆死角。要解决此问题,请添加一个检查以仅显示expandIconContainer(第 526 行),如下所示:

if (!child.canTapOnHeader) expandIconContainer,
Run Code Online (Sandbox Code Playgroud)


小智 5

尝试修改实际实现

如果您有一些先前的编程经验,这应该是有意义的......

找到这些文件:

  • 扩展面板.dart
  • 扩展标题.dart
  • 展开图标.dart
  • mergeable_material.dart

这些文件应位于“外部库”>“Dart 包”>“Flutter”>“src”>“材质”中。注意,材料文件夹可以表示为“src.material”。

Android Studio 应该允许您将鼠标悬停在 ExpansionPanel Widget 上并右键单击它。右键单击它后,您应该会看到一个快捷方式列表,其中一个是“转到”。单击“转到”选项,将显示更多选项,其中之一是“实现”。这应该会带您到达您需要的地方。根据我的版本,双击小部件名称以使整个小部件的名称突出显示应该允许使用键盘快捷键 Ctrl+Alt+B。

您必须进入的关键文件是“mergeable_material.dart”。在“mergeable.dart”中,转到 MaterialGap 构造函数:

const MaterialGap({
    @required LocalKey key,
    this.size = 16.0, 
    //This is the size of the gap between ExpansionTiles WHEN EXPANDED
}) : assert(key != null),
   super(key);
Run Code Online (Sandbox Code Playgroud)

此大小变量仅在扩展时控制扩展图块之间的间隙。设置“this.size = 0.0”应该可以消除间隙。

如果您想知道为什么会这样,长话短说,当定义小部件属性的 ExpansionPanels 列表(位于expansion_panel.dart 中)时,会在子项之间添加“MaterialGap”。我们将材料间隙修改为 0.0,从而有效地消除了间隙。

您可以做的其他事情:

  1. 更改标题中的尾随图标。

    转到 Expand.dart 文件。转到文件底部的构建方法所在的位置。在返回语句中,将图标按钮替换为您想要的“任何”(在合理范围内)。

    @override
    Widget build(BuildContext context) {
      assert(debugCheckHasMaterial(context));
      assert(debugCheckHasMaterialLocalizations(context));
      final MaterialLocalizations localizations = MaterialLocalizations.of(context);
      final String onTapHint = widget.isExpanded ? localizations.expandedIconTapHint : 
      localizations.collapsedIconTapHint;
    
      return Semantics(
        onTapHint: widget.onPressed == null ? null : onTapHint,
        child: Container() //Replaced the Icon Button here to remove it
      );
    }
    
    Run Code Online (Sandbox Code Playgroud)

    请记住,如果没有按钮,则必须将 canTapOnHeader: true 设置为 true,否则将无法展开面板。您可以通过转到 ExpansionPanel 构造函数并更改“this.canTapOnHeader = false;”来确保您不会忘记执行此操作。到“this.canTapOnHeader = true;

      ExpansionPanel({
        @required this.headerBuilder,
        @required this.body,
        this.isExpanded = false,
        this.canTapOnHeader = true, //Changed this to true from false
      }) : assert(headerBuilder != null),
           assert(body != null),
           assert(isExpanded != null),
           assert(canTapOnHeader != null);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 移除阴影和/或分隔线

    转到expansion_panel.dart 文件的底部。这就是构建方法应该在的地方。构建方法的底部应该是 return 语句,它返回 MergeableMaterial。您可以执行以下操作:

      return MergeableMaterial(
        hasDividers: false, //Change the boolean value of this
        children: items,
        elevation: 0, 
        //Add this line to remove shadow from elevation, REQUIRES ANOTHER STEP             
      );
    
    Run Code Online (Sandbox Code Playgroud)

    如果添加“elevation: 0”属性,您必须返回 mergeable_material.dart 并添加以下代码行:

    void _paintShadows(Canvas canvas, Rect rect) {
        if (boxShadows == null) return; //ADD THIS LINE OF CODE
        for (BoxShadow boxShadow in boxShadows) {
          final Paint paint = boxShadow.toPaint();
          // TODO(dragostis): Right now, we are only interpolating the border radii
          // of the visible Material slices, not the shadows; they are not getting
          // interpolated and always have the same rounded radii. Once shadow
          // performance is better, shadows should be redrawn every single time the
          // slices' radii get interpolated and use those radii not the defaults.
          canvas.drawRRect(kMaterialEdges[MaterialType.card].toRRect(rect), paint);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

我想你明白了,你可以通过修改常量来做更多的事情来删除填充之类的东西。

担忧

注意:事实上,我对 Flutter 还比较陌生(去年夏天 2 个月,现在 2 个月——我是一名大学生)。我不知道修改这些文件可能会如何影响其他小部件,但我没有注意到这样做有任何问题。这也是我的第一篇文章,所以请持保留态度。修改材质实现可能会违反一些我将参考文档的规则或约定。