关于 Flutter 中的Table你了解多少呢

关于 Flutter 中的 Table 你了解多少,本系列文章将对 Table 进行全面的剖析,让你对 Table有更全面的了解和使用

本篇文章主要对Table进行一个介绍,让你对Table有一个大概的了解,后续将进行更详细的介绍

Table相关属性

dart 复制代码
Table({  
    super.key,  
    // 每一行
    this.children = const <TableRow>[],  
    // 单独定义每列的宽度
    this.columnWidths,  
    // 默认列宽
    this.defaultColumnWidth = const FlexColumnWidth(),  
    // 文字对齐方式
    this.textDirection,  
    // 单元格边框
    this.border,  
    // 单元格对齐方式
    this.defaultVerticalAlignment = TableCellVerticalAlignment.top,  
    // 文本基线
    this.textBaseline,
})

下面介绍下 Table 中各个属性的意思

TableColumnWidth 介绍

dart 复制代码
// 优先级高于`defaultColumnWidth`,同时存在情况下,列宽使用`columnWidths`中的定义
final Map<int, TableColumnWidth>? columnWidths;
// 所有的列表宽都使用这个方式。
final TableColumnWidth defaultColumnWidth;

TableColumnWidth是一个抽象类,一共提供了6种类型,让我们一起看一下

FixedColumnWidth(value),列的宽度为 value 传入的大小

dart 复制代码
class FixedColumnWidth extends TableColumnWidth {  
    /// Creates a column width based on a fixed number of logical pixels.  
    const FixedColumnWidth(this.value);  

    /// The width the column should occupy in logical pixels.  
    final double value;  

    @override  
    double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return value;  
    }  

    @override  
    double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return value;  
    }  
}

IntrinsicColumnWidth,根据内容自适应大小

dart 复制代码
class IntrinsicColumnWidth extends TableColumnWidth {  
    const IntrinsicColumnWidth({ double? flex }) : _flex = flex;  

    @override  
    double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        double result = 0.0;  
        for (final RenderBox cell in cells) {  
            result = math.max(result, cell.getMinIntrinsicWidth(double.infinity));  
        }  
        return result;  
    }  

    @override  
    double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        double result = 0.0;  
        for (final RenderBox cell in cells) {  
            result = math.max(result, cell.getMaxIntrinsicWidth(double.infinity));  
        }  
        return result;  
    }  

    final double? _flex;  

    @override  
    double? flex(Iterable<RenderBox> cells) => _flex;  
}

MinColumnWidth(a,b) ,比较 a,b 两个TableColumnWidth取其中最小的

dart 复制代码
class MinColumnWidth extends TableColumnWidth {  
    /// Creates a column width that is the minimum of two other column widths.  
    const MinColumnWidth(this.a, this.b);  

    /// An upper bound for the width of this column.  
    final TableColumnWidth a;  

    /// Another upper bound for the width of this column.  
    final TableColumnWidth b;  

    @override  
    double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return math.min(  
            a.minIntrinsicWidth(cells, containerWidth),  
            b.minIntrinsicWidth(cells, containerWidth),  
        );  
    }  

    @override  
    double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return math.min(  
            a.maxIntrinsicWidth(cells, containerWidth),  
            b.maxIntrinsicWidth(cells, containerWidth),  
        );  
    }  

    @override  
    double? flex(Iterable<RenderBox> cells) {  
        final double? aFlex = a.flex(cells);  
        final double? bFlex = b.flex(cells);  
        if (aFlex == null) {  
            return bFlex;  
        } else if (bFlex == null) {  
            return aFlex;  
        }  
        return math.min(aFlex, bFlex);  
    }  
}

MaxColumnWidth(a,b) ,比较 a,b 两个TableColumnWidth取其中最大的

dart 复制代码
class MaxColumnWidth extends TableColumnWidth {  
    /// Creates a column width that is the maximum of two other column widths.  
    const MaxColumnWidth(this.a, this.b);  

    /// A lower bound for the width of this column.  
    final TableColumnWidth a;  

    /// Another lower bound for the width of this column.  
    final TableColumnWidth b;  
  
    @override  
    double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return math.max(  
            a.minIntrinsicWidth(cells, containerWidth),  
            b.minIntrinsicWidth(cells, containerWidth),  
        );  
    }  
  
    @override  
    double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return math.max(  
            a.maxIntrinsicWidth(cells, containerWidth),  
            b.maxIntrinsicWidth(cells, containerWidth),  
        );  
    }  

    @override  
    double? flex(Iterable<RenderBox> cells) {  
        final double? aFlex = a.flex(cells);  
        final double? bFlex = b.flex(cells);  
        if (aFlex == null) {  
            return bFlex;  
        } else if (bFlex == null) {  
            return aFlex;  
        }  
        return math.max(aFlex, bFlex);  
    }   
}

FractionColumnWidth(value) ,约束的最大 width * value,如果约束是无限的,则为0

dart 复制代码
class FractionColumnWidth extends TableColumnWidth {  
    /// Creates a column width based on a fraction of the table's constraints'  
    /// maxWidth.  
    const FractionColumnWidth(this.value);  

    /// The fraction of the table's constraints' maxWidth that this column should  
    /// occupy.  
    final double value;  

    @override  
    double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        if (!containerWidth.isFinite) {  
            return 0.0;  
        }  
            return value * containerWidth;  
    }  

    @override  
    double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        if (!containerWidth.isFinite) {  
            return 0.0;  
        }  
        return value * containerWidth;  
    }  
  
}

FlexColumnWidth([this.value = 1.0]) ,和Flex的效果一样,等分空间

dart 复制代码
class FlexColumnWidth extends TableColumnWidth {  
    /// Creates a column width based on a fraction of the remaining space once all  
    /// the other columns have been laid out.  
    const FlexColumnWidth([this.value = 1.0]);  

    /// The fraction of the remaining space once all the other columns have  
    /// been laid out that this column should occupy.  
    final double value;  

    @override  
    double minIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return 0.0;  
    }  

    @override  
    double maxIntrinsicWidth(Iterable<RenderBox> cells, double containerWidth) {  
        return 0.0;  
    }  

    @override  
    double flex(Iterable<RenderBox> cells) {  
        return value;  
    }  
  
}

TableRow 介绍

表格中的行

dart 复制代码
@immutable  
class TableRow {  
const TableRow({ this.key, this.decoration, this.children = const <Widget>[]});  
    final LocalKey? key;  
    // 行的装饰
    final Decoration? decoration;   
    // Widget 必须为 TableCell,每一行的 children 数量必须一致
    final List<Widget> children;  
}

TableBorder 介绍

dart 复制代码
const TableBorder({  
    // 头部
    this.top = BorderSide.none,  
    // 右侧
    this.right = BorderSide.none, 
    // 底部
    this.bottom = BorderSide.none,  
    // 左侧
    this.left = BorderSide.none,  
    // 内部横向
    this.horizontalInside = BorderSide.none,  
    // 内部垂直
    this.verticalInside = BorderSide.none,  
    // radius
    this.borderRadius = BorderRadius.zero,  
});

用法就和 BoxDecoraiton 里的 Border 一样,只是这里设置的是 Table 的 Border

Table的属性就介绍到这里,没什么复杂的地方,我们主要关注Table的实现和内部的方法,Table内部提供了很多有意思的方法

Table 的构造

dart 复制代码
class Table extends RenderObjectWidget {
    @override  
    RenderObjectElement createElement() => _TableElement(this);  

    @override  
    RenderTable createRenderObject(BuildContext context) {  
        assert(debugCheckHasDirectionality(context));  
        return RenderTable(  
            columns: children.isNotEmpty ? children[0].children.length : 0,  
            rows: children.length,  
            columnWidths: columnWidths,  
            defaultColumnWidth: defaultColumnWidth,  
            textDirection: textDirection ?? Directionality.of(context),  
            border: border,  
            rowDecorations: _rowDecorations,  
            configuration: createLocalImageConfiguration(context),  
            defaultVerticalAlignment: defaultVerticalAlignment,  
            textBaseline: textBaseline,  
        );  
    }  

    @override  
    void updateRenderObject(BuildContext context, RenderTable renderObject) {  
        assert(debugCheckHasDirectionality(context));  
        assert(renderObject.columns == (children.isNotEmpty ? children[0].children.length : 0));  
        assert(renderObject.rows == children.length);  
        renderObject  
        ..columnWidths = columnWidths  
        ..defaultColumnWidth = defaultColumnWidth  
        ..textDirection = textDirection ?? Directionality.of(context)  
        ..border = border  
        ..rowDecorations = _rowDecorations  
        ..configuration = createLocalImageConfiguration(context)  
        ..defaultVerticalAlignment = defaultVerticalAlignment  
        ..textBaseline = textBaseline;  
    }
}

Table创建的_TableElement这里就不介绍了,可以自行了解下即可。

通过代码可以看到Table直接继承自RenderObject,创建了一个RenderTable

dart 复制代码
class RenderTable extends RenderBox {  
    RenderTable({  
        int? columns,  
        int? rows,  
        Map<int, TableColumnWidth>? columnWidths,  
        TableColumnWidth defaultColumnWidth = const FlexColumnWidth(),  
        required TextDirection textDirection,  
        TableBorder? border,  
        List<Decoration?>? rowDecorations,  
        ImageConfiguration configuration = ImageConfiguration.empty,  
        TableCellVerticalAlignment defaultVerticalAlignment = TableCellVerticalAlignment.top,  
        TextBaseline? textBaseline,  
        List<List<RenderBox>>? children,  
    })
}

RenderTable中内置很多的方法,我们可以使用这些方法对 Table进行很多操作,我们也可以参照这些方法的实现逻辑,我们也可以参照这些逻辑实现自己的方法。

下面代码中可以看到,只需要使用 GlobalKey,我们就可以在Table渲染结束后获取到 RenderTable,获取到RenderTable后就可以进行很多有意思的操作了。

dart 复制代码
class _ExampleState extends State<Example> {  
  
    final GlobalKey _tableKey = GlobalKey();  
  
    @override  
    initState() {  
        super.initState();  
        WidgetsBinding.instance.addPostFrameCallback((_) {  
            if (_tableKey.currentContext == null) {  
                return;  
            }  
            final renderTable = _tableKey.currentContext!.findRenderObject() as RenderTable;  
        });  
    }  
  
    @override  
    Widget build(BuildContext context) {  
        return Table(  
            key: _tableKey,  
            children: [],  
        );  
    }  
}

本篇文章关于 Table 的介绍就到这里,更多内容后续介绍,感兴趣的可以自行去了解。

相关推荐
Jinkey4 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
Summer不秃8 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰8 小时前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
sunly_8 小时前
Flutter:AnimatedSwitcher当子元素改变时,触发动画
flutter
AiFlutter8 小时前
Flutter封装Coap
flutter
旭日猎鹰14 小时前
Flutter踩坑记录(三)-- 更改入口执行文件
flutter
旭日猎鹰14 小时前
Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行
flutter
️ 邪神14 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱1 天前
flutter项目苹果编译运行打包上线
flutter·ios
SoaringHeart1 天前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter