日益努力,而后风生水起|

Flutter不常用组件(四)

Offstage

创建一个在视觉上隐藏其子项的小部件。隐藏后不占空间。

该组件有以下几个属性:

  • Key? key:标识键
  • bool offstage = true:是否隐藏。默认为true
  • Widget? child:子组件
Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      ...List.generate(
        5,
        (index) => Offstage(
          offstage: index == 2 ? _flag : false,
          child: Container(
            width: 200,
            height: 80,
            color: Colors.primaries[index % Colors.primaries.length],
          ),
        ),
      ).toList(),
      const SizedBox(height: 24),
      ElevatedButton(
        onPressed: () {
          _flag = !_flag;
          setState(() {});
        },
        child: const Text("切换Offstage"),
      ),
    ],
  ),
)

image

OverflowBar

一个小部件,它的子部件排成一行,除非它们“溢出”了可用的水平空间,在这种情况下,它将它们排成一列。

该组件有以下几个属性:

  • Key? key:标志键
  • double spacing:水平排列时子组件的间距
  • MainAxisAlignment? alignment:水平排列时的对齐方式
  • double overflowSpacing:垂直排列时组件的间距
  • OverflowBarAlignment overflowAlignment:垂直排列时的对齐方式。默认为OverflowBarAlignment.start
  • VerticalDirection overflowDirection = VerticalDirection.down:盒子垂直流动的方向
  • TextDirection? textDirection:文本流动的方向
  • Clip clipBehavior = Clip.none:内容将根据此选项被剪裁(或不剪裁)
  • List<Widget> children:子组件
OverflowBar(
  spacing: 10,
  alignment: MainAxisAlignment.center,
  overflowSpacing: 10,
  overflowAlignment: OverflowBarAlignment.start,
  overflowDirection: VerticalDirection.down,
  textDirection: TextDirection.ltr,
  clipBehavior: Clip.none,
  children: List.generate(
    _count,
    (index) => Container(
      width: 60,
      height: 60,
      color: Colors.primaries[index % Colors.primaries.length],
      alignment: Alignment.center,
      child: Text(
        index.toString(),
        style: const TextStyle(fontSize: 24, color: Colors.white),
      ),
    ),
  ).toList(),
)

image

OverflowBox

对子组件施加的约束与从父组件获得的约束不同,可能会允许子组件溢出父组件。

该组件有以下几个属性:

  • Key? key:标识键
  • AlignmentGeometry alignment:子组件对齐方式。默认为Alignment.center
  • double? minWidth:最小宽
  • double? maxWidth:最大宽
  • double? minHeight:最小高
  • double? maxHeight:最大高
  • Widget? child:子组件
Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: [
      Container(
        height: 150,
        width: 150,
        color: Colors.red,
        child: Container(
          height: 250,
          width: 250,
          color: Colors.blue.withOpacity(.5),
        ),
      ),
      Container(
        height: 150,
        width: 150,
        color: Colors.red,
        child: OverflowBox(
          minWidth: 50,
          minHeight: 50,
          maxWidth: 300,
          maxHeight: 300,
          child: Container(
            height: 350, // 无效,最终为300
            width: 250,
            color: Colors.blue.withOpacity(.5),
          ),
        ),
      ),
    ],
  ),
)

image

Overlay 和 OverlayEntry

在所有页面顶部悬浮一个组件。

使用OverlayEntry来创建要显示的组件:

final _entry = OverlayEntry(
  builder: (context) {
    return Positioned(
      bottom: 100,
      right: 20,
      child: Image.asset("assets/images/st.png", width: 80),
    );
  },
);

创建一个显示或隐藏的方法:

showOverlay() {
  final overlay = Overlay.of(context);
  if (_flag) {
    _entry.remove();
  } else {
    overlay?.insert(_entry);
  }
  _flag = !_flag;
  setState(() {});
}

在页面中调用方法:

body: Center(
  child: ElevatedButton(
    onPressed: showOverlay,
    child: const Text("Overlay 开关"),
  ),
)

image

PageStorage 和 PageStorageBucket

用来保存页面状态。

PageStorage有以下几个属性:

  • Key? key:标识键
  • PageStorageBucket bucketPageStorageBucket对象
  • Widget child:子组件

创建一个PageStorageBucket对象:

final PageStorageBucket _bucket = PageStorageBucket();

创建一个组件用来显示在不同的页面:

class ColorPage extends StatelessWidget {
  const ColorPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemExtent: 200,
      itemBuilder: (context, index) {
        return Container(
          color: Colors.primaries[index % Colors.primaries.length],
          alignment: Alignment.center,
          child: Text(
            "$index",
            style: const TextStyle(fontSize: 24, color: Colors.white),
          ),
        );
      },
    );
  }
}

创建主页面:

Scaffold(
  appBar: AppBar(title: const Text('PageStorage')),
  body: PageStorage(
    bucket: _bucket,
    child: const [
      ColorPage(key: PageStorageKey("one")),
      ColorPage()
    ][_index],
  ),
  bottomNavigationBar: BottomNavigationBar(
    currentIndex: _index,
    onTap: (int index) {
      _index = index;
      setState(() {});
    },
    showSelectedLabels: false,
    showUnselectedLabels: false,
    items: const <BottomNavigationBarItem>[
      BottomNavigationBarItem(icon: Icon(Icons.home), label: ''),
      BottomNavigationBarItem(icon: Icon(Icons.person), label: ''),
    ],
  ),
);

image

可以发现,只有设置了PageStorageKey的才能保存界面状态。

PaginatedDataTable

数据分页表格。

该组件有以下几个属性:

  • Key? key:标识键
  • Widget? header:表格顶部的组件
  • List<Widget>? actionsheader最右边的组件
  • List<DataColumn> columnsDataColumn对象,表头
  • int? sortColumnIndex:当前主排序键的列
  • bool sortAscending:是否按升序排序。默认为true
  • void Function(bool?)? onSelectAll:当用户使用标题行中的复选框选择或取消选择每一行时调用
  • double dataRowHeight:数据行高。默认为kMinInteractiveDimension(48.0)
  • double headingRowHeight:表头行高。默认为56.0
  • double horizontalMargin:表格边缘与每行第一个和最后一个单元格中的内容之间的水平边距。默认24.0
  • double columnSpacing:每个数据列内容之间的水平边距。默认为56.0
  • bool showCheckboxColumn:是否显示可选行的复选框。默认为true
  • bool showFirstLastButtons:标记以显示分页按钮以转到第一页和最后一页。默认为false
  • int? initialFirstRowIndex:首次创建小部件时显示的第一行的索引。默认为0
  • void Function(int)? onPageChanged:数据页面改变时调用
  • int rowsPerPage = defaultRowsPerPage:每页显示的行数。默认为10
  • List availableRowsPerPage = const [defaultRowsPerPage, defaultRowsPerPage * 2, defaultRowsPerPage * 5, defaultRowsPerPage * 10]:为rowsPerPage提供的选项
  • void Function(int?)? onRowsPerPageChanged:当用户每页选择不同数量的行时调用
  • DragStartBehavior dragStartBehavior :确定处理拖动开始行为的方式。默认为DragStartBehavior.start
  • Color? arrowHeadColor:翻页箭头的颜色
  • DataTableSource sourceDataTableSource对象
  • double? checkboxHorizontalMargin:复选框周围的水平边距

创建一个继承自DataTableSource的类

class MyData extends DataTableSource {
  final List<Map<String, dynamic>> _data = List.generate(
    60,
    (index) => {
      "id": index + 1000,
      "name": Username.cn().fullname,
      "sex": Random().nextInt(10).isEven ? "男" : "女"
    },
  );

  @override
  DataRow? getRow(int index) {
    return DataRow(
      cells: [
        DataCell(Text(_data[index]["id"].toString())),
        DataCell(Text(_data[index]["name"].toString())),
        DataCell(Text(_data[index]["sex"].toString())),
      ],
    );
  }

  @override
  // TODO: implement isRowCountApproximate
  bool get isRowCountApproximate => false;

  @override
  // TODO: implement rowCount
  int get rowCount => _data.length;

  @override
  // TODO: implement selectedRowCount
  int get selectedRowCount => 0;
}

在页面中使用PaginatedDataTable

PaginatedDataTable(
  header: const Center(child: Text("班级花名册")),
  actions: const [Icon(Icons.edit_note_rounded)],
  columns: const [
    DataColumn(label: Text("序号")),
    DataColumn(label: Text("姓名")),
    DataColumn(label: Text("性别")),
  ],
  sortColumnIndex: 0,
  sortAscending: true,
  onSelectAll: (flag) {},
  dataRowHeight: kMinInteractiveDimension,
  headingRowHeight: 56,
  horizontalMargin: 40,
  columnSpacing: 100,
  showCheckboxColumn: true,
  showFirstLastButtons: true,
  initialFirstRowIndex: 0,
  onPageChanged: (value) {},
  rowsPerPage: 10,
  // onRowsPerPageChanged: (value) {},
  dragStartBehavior: DragStartBehavior.start,
  // arrowHeadColor: Colors.blue,
  source: MyData(),
  checkboxHorizontalMargin: 20,
)

image

关于行和列数据操作的方法请参考DataTable组件,具体的想过教程请自行搜索。

本文作者:DerFeigling

本文链接:https://www.cnblogs.com/ilgnefz/p/16949635.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   菠萝橙子丶  阅读(231)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Shining For One Thing 赵贝尔
Shining For One Thing - 赵贝尔
00:00 / 00:00
An audio error has occurred.

Shining For One Thing (《一闪一闪亮星星》影视剧歌曲) - 赵贝尔

词:萨吉

曲:金大洲

编曲:金大洲D-Jin

制作人:金大洲D-Jin

吉他/Bass:D-Jin

合声编写/合声:赵贝尔

人声录音/编辑:张德龙@D-Jin Music Studio

混音/母带处理:George Dum

宣传推广:杨慧颖/杨佩

封面设计:HOO

OP/音乐制作出品:D-Jin Music(北京翊辰文化传媒有限公司)

(未经著作权人许可,不得翻唱、翻录或使用)

夏夜的花火

夏夜的花火

因为你在身边而深刻

因为你在身边而深刻

幸运的是我

在宇宙之间听见承诺

在宇宙之间听见承诺

嗨 是我

这一次别再错过

这一次别再错过

喜欢你该由我主动了

喜欢你该由我主动了

星星那么多

星星那么多

有数不尽的浪漫闪烁

注定这一颗

会让你刻在手臂左侧

属于我

星形心率的贴合

幸有你总在守护我

幸有你总在守护我

I fall in love

I fall in love

I see your love

遇见你才发现我在

等你到来

等你到来

Fallen star

The wonder of you

我会永远在你天空

我会永远在你天空

为你闪烁 my love

为你闪烁 my love

Shining for one thing

Shining for one thing

Shining for one thing

Shining for one thing

It's you

It's you

星星那么多

星星那么多

有数不尽的浪漫闪烁

注定这一颗

会让你刻在手臂左侧

属于我

星形心率的贴合

幸有你总在守护我

幸有你总在守护我

I fall in love

I fall in love

I see your love

遇见你才发现我在

等你到来

等你到来

Fallen star

The wonder of you

我会永远在你天空

我会永远在你天空

为你闪烁 my love

为你闪烁 my love

Shining for one thing

Shining for one thing

Shining for one thing

Shining for one thing

It's you

It's you