[译]Flutter 可拖拽调节尺寸灵活的分割视图组件 multi_split_view

597 阅读3分钟

Flutter 可拖拽调节尺寸灵活的窗口分割组件 multi_split_view

原文链接:multi_split_view | Flutter Package (flutter-io.cn)

译时版本: 2.4.0


Multi split view

用于Flutter,提供水平或垂直的多重分割视图组件。

  • 支持水平或垂直分割

  • 可为每个子组件配置比例或尺寸

  • 以下情况会自动计算比例:

    • 子组件未定义比例
    • 子组件删除时比例重新分配
  • 监听子组件的尺寸变化

水平分割

    MultiSplitView(children: [child1, child2, child3]);

垂直分割

    MultiSplitView(axis: Axis.vertical, children: [child1, child2]);

同时水平分割和垂直分割

    MultiSplitView(axis: Axis.vertical, children: [
      MultiSplitView(children: [child1, child2, child3]),
      child4
    ]);

设置初始比例

使用 StatelessWidget

    // 为第一个子组件设置 10% 的比例
    MultiSplitView multiSplitView = MultiSplitView(
        children: [child1, child2, child3], initialAreas: [Area(weight: 0.1)]);

使用 StatefulWidget

  MultiSplitViewController _controller =
      MultiSplitViewController(areas: [Area(weight: 0.1)]);

或者

  MultiSplitViewController _controller2 =
      MultiSplitViewController(areas: Area.weights([0.1]));

    // 为第一个子组件设置 10% 的比例
    MultiSplitView multiSplitView = MultiSplitView(
        children: [child1, child2, child3], controller: _controller);

用程序改变比例或尺寸

    _controller.areas = [Area(size: 150)];

最小子组件比例

  MultiSplitViewController _controller =
      MultiSplitViewController(areas: [Area(minimalWeight: .25), Area(minimalWeight: .25)]);

子组件的最小像素尺寸

  final MultiSplitViewController _controller =
      MultiSplitViewController(areas: [Area(minimalSize: 150)]);

可调整尺寸

    MultiSplitView(children: [child1, child2, child3], resizable: false);

监听器

    MultiSplitView(
        children: [child1, child2, child3, child4],
        onWeightChange: () =>
            DemoFlu.printOnConsole(context, 'Weight has changed'));

分割条宽度

    MultiSplitView multiSplitView =
        MultiSplitView(children: [child1, child2, child3]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        child: multiSplitView,
        data: MultiSplitViewThemeData(dividerThickness: 30));

自定义分割条

    MultiSplitView multiSplitView = MultiSplitView(
        children: [child1, child2, child3],
        dividerBuilder:
            (axis, index, resizable, dragging, highlighted, themeData) {
          return Container(
            color: dragging ? Colors.grey[300] : Colors.grey[100],
            child: Icon(
              Icons.drag_indicator,
              color: highlighted ? Colors.grey[600] : Colors.grey[400],
            ),
          );
        });

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        child: multiSplitView,
        data: MultiSplitViewThemeData(dividerThickness: 24));

分割条点击手势

    MultiSplitView multiSplitView = MultiSplitView(
        children: [...],
        onDividerTap: (dividerIndex) => {},
        onDividerDoubleTap: (dividerIndex) => {});

分割条绘制器

可以使用 DividerPainter 类定制分割条。

DividerPainters 工厂类提供默认的绘制器。

分割条 - 背景色

DividerPainters.background 允许设置背景色。默认颜色是 NULL

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        child: multiSplitView,
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.background(color: Colors.black)));

分割条 - 高亮背景色

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        child: multiSplitView,
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.background(
                color: Colors.grey[200], highlightedColor: Colors.grey[800])));

虚线分割条

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.dashed(
                color: Colors.deepOrange, highlightedColor: Colors.black)),
        child: multiSplitView);

虚线分割条 - 定制

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.dashed(
                gap: 30, size: 20, thickness: 3, highlightedThickness: 6)),
        child: multiSplitView);

沟槽分隔条 1

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.grooved1(
                color: Colors.indigo[100]!,
                highlightedColor: Colors.indigo[900]!)),
        child: multiSplitView);

沟槽分隔条 1 - 定制

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.grooved1(
                size: 5,
                highlightedSize: 30,
                thickness: 3,
                highlightedThickness: 6)),
        child: multiSplitView);

沟槽分隔条 2

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.grooved2(
                color: Colors.grey[400]!, highlightedColor: Colors.red)),
        child: multiSplitView);

沟槽分隔条 2 - 定制

    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        data: MultiSplitViewThemeData(
            dividerPainter: DividerPainters.grooved2(
                gap: 15,
                thickness: 4,
                count: 3,
                highlightedCount: 9,
                strokeCap: StrokeCap.square)),
        child: multiSplitView);

分割条 - 定制绘制器

可以扩展 DividerPainter 类从草稿创建绘制器。

class MyDividerPainter extends DividerPainter {
  @override
  Map<int, Tween> buildTween() {
    Map<int, Tween> map = super.buildTween();
    // 创建补间动画,例:
    map[100] = Tween<double>(begin: 1, end: 5);
    return map;
  }

  @override
  void paint(
      {required Axis dividerAxis,
      required bool resizable,
      required bool highlighted,
      required Canvas canvas,
      required Size dividerSize,
      required Map<int, dynamic> animatedValues}) {
    super.paint(
        dividerAxis: dividerAxis,
        resizable: resizable,
        highlighted: highlighted,
        canvas: canvas,
        dividerSize: dividerSize,
        animatedValues: animatedValues);
    double myAnimatedValue = animatedValues[100];
    // ...
  }
}
    MultiSplitView multiSplitView = MultiSplitView(children: [child1, child2]);

    MultiSplitViewTheme theme = MultiSplitViewTheme(
        child: multiSplitView,
        data: MultiSplitViewThemeData(dividerPainter: MyDividerPainter()));