布局

基本布局

GridView

代码

/// GridView()
GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,//交叉轴方向的数目
  ),
  children: <Widget&gt;[
    Text('1'),Text('2'),Text('3'),
    Text('4'),Text('5'),Text('6'),
    Text('7'),Text('8'),Text('9'),
    ],
),
/// GridView.builder()
final List<String&gt; name = <String&gt;['1','2','3',];
GridView.builder(
  itemCount: name.length,
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,//交叉轴方向item的数量
    mainAxisSpacing: 2.0,//主轴方向的间隔
    crossAxisSpacing: 2.0,//交叉轴之间的间隔
  ),
  itemBuilder: (context, index) {
    return Container(
      child: Text(name[index]),
    );
  },
),
/// GridView.costom()
 GridView.custom(
    gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
      maxCrossAxisExtent: 80.0,//在交叉轴方向上单个item最大长度
      crossAxisCount: 3,//交叉轴方向item的数量
	  mainAxisSpacing: 2.0,//主轴方向的间隔
    ),
    childrenDelegate: SliverChildBuilderDelegate(
      (context, index) {
        return Container(
          child: Text(name[index]),
        );
      },
      childCount: name.length,
    ),
),
/// GirdView.count()
GridView.count(
  crossAxisCount: 3,
  children: <Widget>[
    Text('1'),Text('2'),Text('3'),
    Text('4'),Text('5'),Text('6'),
    Text('7'),Text('8'),Text('9'),
    ],
),
/// GridView.extent()
GridView.extent(
  maxCrossAxisExtent: 100.0,//在交叉轴方向上item最大长度
  crossAxisCount: 3,//交叉轴方向item的数量
  mainAxisSpacing: 2.0,//主轴方向的间隔
  children: <Widget>[
    Container(
          child: Text("1"),
        ),
    Container(
          child: Text("2"),
        ),
    Container(
          child: Text("3"),
        ),
  ],
),

完整示例代码

import 'package:flutter/material.dart';

class HomeTabPage1 extends StatelessWidget {
  List listData = [
    {
      "title": "标题1",
      "author": "内容1",
      "image": "https://www.itying.com/images/flutter/1.png"
    },
    {
      "title": "标题2",
      "author": "内容2",
      "image": "https://www.itying.com/images/flutter/2.png"
    },
    {
      "title": "标题3",
      "author": "内容3",
      "image": "https://www.itying.com/images/flutter/3.png"
    },
    {
      "title": "标题4",
      "author": "内容4",
      "image": "https://www.itying.com/images/flutter/4.png"
    },
    {
      "title": "标题5",
      "author": "内容5",
      "image": "https://www.itying.com/images/flutter/5.png"
    },
    {
      "title": "标题6",
      "author": "内容6",
      "image": "https://www.itying.com/images/flutter/6.png"
    },
    {
      "title": "标题7",
      "author": "内容7",
      "image": "https://www.itying.com/images/flutter/7.png"
    },
    {
      "title": "标题8",
      "author": "内容8",
      "image": "https://www.itying.com/images/flutter/1.png"
    },
    {
      "title": "标题9",
      "author": "内容9",
      "image": "https://www.itying.com/images/flutter/2.png"
    },
    {
      "title": "标题1",
      "author": "内容1",
      "image": "https://www.itying.com/images/flutter/1.png"
    },
    {
      "title": "标题2",
      "author": "内容2",
      "image": "https://www.itying.com/images/flutter/2.png"
    },
    {
      "title": "标题3",
      "author": "内容3",
      "image": "https://www.itying.com/images/flutter/3.png"
    },
    {
      "title": "标题4",
      "author": "内容4",
      "image": "https://www.itying.com/images/flutter/4.png"
    },
    {
      "title": "标题5",
      "author": "内容5",
      "image": "https://www.itying.com/images/flutter/5.png"
    },
    {
      "title": "标题6",
      "author": "内容6",
      "image": "https://www.itying.com/images/flutter/6.png"
    }
  ];

  List<Widget> _getData() {
    List<Widget> list = [];
    for (var i = 0; i < listData.length; i++) {
      list.add(Container(
        child: Column(
          children: [
            Image.network(
              listData[i]["image"],
              fit: BoxFit.cover,
            ),
            Text(
              listData[i]["title"],
              textAlign:TextAlign.center,
            )
          ],
        ),
      ));
    }
    return list;
  }


  @override
  Widget build(BuildContext context) {
    return GridView.count(
      //设置滚动方向
      scrollDirection: Axis.vertical,
      //设置列数
      crossAxisCount: 5,
      //设置内边距(整个GridView的)
      padding: EdgeInsets.all(30),
      //设置横向间距(3个间距一起用就能控制item各种距离了)
      crossAxisSpacing: 30,
      //设置主轴间距
      mainAxisSpacing: 30,
      children: _getData(),
    );
  }
}

常用参数

gridDelegate
scrollDirection
* 滚动方向
    * Axis.vertical
        * 竖向滚动
    * Axis.horizontal
        * 横向滚动
reverse
* 组件反向排序
controller
* 滚动监听
primary
* 值为false,内容不足不可滑动
* 值为true,内容不足可以尝试滑动
shrinkWrap
* 内容适配默认false
padding
* 内边距
crossAxisCount
* 列数
mainAxisSpacing
* 主轴之间的间距
crossAxisSpacing
* 横轴之间的间距
childAspectRatio
* 设置宽高的比例
* GridView的子组件直接设置宽高没有反应,可以通过childAspectRatio修改宽高
cacheExtent
* 设置预加载区域
children
* 组件元素 const Widget列表
* 数组添加widget类型的数据
* flutter的所有组件都是widget,也就是说所有的GridView可以添加所有的组件
semanticChildCount
* 提供语义信息的子组件数量

ListBody

  • 很少单独使用,搭配如Row、Column、ListView、Flex一起使用

代码

Column(
  //主轴垂直排列的列表,未限制宽,默认将充满屏幕
  children: <Widget>[
    ListBody(
      //指定主轴方向与父框架相同
      mainAxis: Axis.vertical,
      reverse: false,//不反向
      children: <Widget>[
        Container(color: Colors.red, width: 50.0, height: 50.0),
        Container(color: Colors.yellow, width: 50.0, height: 50.0),
        Container(color: Colors.green, width: 50.0, height: 50.0),
        Container(color: Colors.blue, width: 50.0, height: 50.0),
        Container(color: Colors.black, width: 50.0, height: 50.0),
      ],
    )
  ],
)

Table

  • 像表格一样布局

代码

Container(
  width: 300.0,height: 200.0,
  padding: EdgeInsets.all(2.0),
  color: Color(0xFFC5CAE9),
  child: Table(
    //每行单元格宽度,TableRow内元素个数,即列数,从第一个最后一个宽度
    //如果排列根据排列方向显示不同
    columnWidths: const <int, TableColumnWidth>{
      0: FixedColumnWidth(30.0),
      1: FixedColumnWidth(70.0),
      2: FixedColumnWidth(50.0),
      3: FixedColumnWidth(100.0),
    },
    //默认显示宽度  默认的每一列宽度值,默认情况下均分。
    defaultColumnWidth: const FlexColumnWidth(1.0),
    //每个表格的排列方向,此处设置从右到左
    textDirection: TextDirection.rtl,
    //表格边框,此处设置蓝色,2像素宽,实线
    border: TableBorder.all(color: Colors.blue, width: 2.0, style: BorderStyle.solid),
    //每一个单元格垂直方向的对齐方式,默认为顶部对齐
    defaultVerticalAlignment: TableCellVerticalAlignment.top,
    //基线类型,与TableCellVerticalAlignment.baseline一起使用
    //textBaseline: null,
    children: <TableRow>[
      TableRow(
        decoration: BoxDecoration(color: Colors.purpleAccent),
        children: <Widget>[
          Text('A1'),Text('A2'),Text('A3'),Text('A4'),
        ],
      ),
      TableRow(
        decoration: BoxDecoration(color: Colors.purpleAccent),
        children: <Widget>[
          Container(color: Colors.red, child: Text('赤')),
          Container(color: Colors.orange, child: Text('橙')),
          Container(color: Colors.yellow, child: Text('黄')),
          Container(color: Colors.green, child: Text('绿')),
        ],
      ),
      TableRow(children: <Widget>[
        Text('B1'),Text('B2'),Text('B3'),Text('B4'),
      ]),
    ],
  ),
)

参数

Flow

  • 重点在于FlowDelegate的使用

FlowDelegate的方法

abstract class FlowDelegate {
  const FlowDelegate({ Listenable repaint }) : _repaint = repaint;
  final Listenable _repaint;
  //重写设置尺寸
  Size getSize(BoxConstraints constraints) => constraints.biggest;
  //重写设置约束
  BoxConstraints getConstraintsForChild(int i, BoxConstraints constraints) => constraints;
  //绘制children的位置大小
  void paintChildren(FlowPaintingContext context);
  //是否要从新布局,可自己定制规则
  bool shouldRelayout(covariant FlowDelegate oldDelegate) => false;
  //是否从新绘制,可自己定制规则
  bool shouldRepaint(covariant FlowDelegate oldDelegate);
  @override
  String toString() => '$runtimeType';
}

代码

Flow(
  delegate: TestFlowDelegate(margin: EdgeInsets.all(5.0)),
  children: <Widget>[
    new Container(
      width: 60.0,  height: 60.0, color: Colors.red,
      child: Text('红'), alignment: Alignment.center, 
    ),
    new Container(
      width: 60.0, height: 60.0,color: Colors.orange,
      child: Text('橙'),alignment: Alignment.center,  
    ),
    new Container(
      width: 60.0,height: 60.0,color: Colors.yellow,
      child: Text('黄'),alignment: Alignment.center,      
    ),
    new Container(
      width: 60.0,height: 60.0,color: Colors.green,
      child: Text('绿'),alignment: Alignment.center,  
    ),
    new Container(
      width: 60.0,height: 60.0,color: Colors.cyan,
      child: Text('青'),alignment: Alignment.center,     
    ),
    new Container(
      width: 60.0, height: 60.0,color: Colors.blue,
      child: Text('蓝'),alignment: Alignment.center,  
    ),
    new Container(
      width: 60.0,height: 60.0,color: Colors.purple,
      child: Text('紫'),alignment: Alignment.center,   
    ),
  ],
)
    
class TestFlowDelegate extends FlowDelegate {
  EdgeInsets margin = EdgeInsets.zero;
  TestFlowDelegate({this.margin});

  @override
  void paintChildren(FlowPaintingContext context) {
    var x = margin.left;
    var y = margin.top;
    for (int i = 0; i < context.childCount; i++) {
      var w = context.getChildSize(i).width + x + margin.right;
      if (w < context.size.width) {
        context.paintChild(i,
            transform: new Matrix4.translationValues(x, y, 0.0));
        x = w + margin.left;
      } else {
        x = margin.left;
        y += context.getChildSize(i).height + margin.top + margin.bottom;
        context.paintChild(i,
            transform: new Matrix4.translationValues(x, y, 0.0));
        x += context.getChildSize(i).width + margin.left + margin.right;
      }
    }
  }

  @override
  bool shouldRepaint(FlowDelegate oldDelegate) {
    return oldDelegate != this;
  }
}

Wrap

参数

代码

Container(
    alignment: Alignment.topCenter,
    child:  Wrap(
    //主轴方向,默认水平
    direction: Axis.horizontal,
    //主轴方向方式,包裹在一个控件效果明显,默认主轴方向开始位置开始
    alignment: WrapAlignment.spaceBetween,
    //主轴方向上child之间的间距,默认为0
    spacing: 6.0,
    // 新一行或一列的对齐方式
    runAlignment: WrapAlignment.spaceBetween,
    //新的一行或一列的间距,默认为0
    runSpacing: 0.0,
    //交叉轴的对齐方式,默认是从主轴开始位置开始
    crossAxisAlignment: WrapCrossAlignment.start,
    //每一行或一列的排列方式,如果一行有三个元素,则第一行取出前三个元素2,1,0这样排列
    //默认从左到右
    textDirection: TextDirection.ltr,
    //垂直方向上排列方式,默认从上到下
    verticalDirection: VerticalDirection.down,
    children: <Widget>[
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('1')),
        label: Text('Hamilton'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('2')),
        label: Text('Lafayette'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('3')),
        label: Text('Mulligan'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('4')),
        label: Text('Laurens'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('5')),
        label: Text('Hamilton'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('6')),
        label: Text('Lafayette'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('7')),
        label: Text('Mulligan'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('8')),
        label: Text('Laurens'),
      ),
      Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('9')),
        label: Text('Hamilton'),
      ),
      Chip(
        avatar: CircleAvatar(
            backgroundColor: Colors.blue.shade900, child: Text('10')),
        label: Text('Lafayette'),
      ),
      Chip(
        avatar: CircleAvatar(
            backgroundColor: Colors.blue.shade900, child: Text('11')),
        label: Text('Mulligan'),
      ),
      Chip(
        avatar: CircleAvatar(
            backgroundColor: Colors.blue.shade900, child: Text('12')),
        label: Text('Laurens'),
      ),
    ],
  ),
)

ScrollView

SingleChildScrollView

代码
SingleChildScrollView(
    child: Column(
    children: <Widget>[
        Container(
        height: 200,
        color: Colors.red,
        ),
        Container(
        height: 200,
        color: Colors.green,
        ),
        Container(
        height: 200,
        color: Colors.blue,
        ),
        Container(
        height: 200,
        color: Colors.yellow,
        ),
        Container(
        height: 200,
        color: Colors.orange,
        ),
    ],
    ),
),

自定义ScrollPhysics控制滑动效果

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyCustomScrollPhysics extends ScrollPhysics {
  const MyCustomScrollPhysics({ScrollPhysics? parent}) : super(parent: parent);

  @override
  MyCustomScrollPhysics applyTo(ScrollPhysics? ancestor) {
    return MyCustomScrollPhysics(parent: buildParent(ancestor));
  }

  @override
  double applyBoundaryConditions(ScrollMetrics position, double value) {
    // 检查是否已经滑动到边界
    if (value < position.pixels &amp;&amp; position.pixels <= position.minScrollExtent) {
      // 滑动顶部边界时,允许继续向上滚动
      return 0.0;
    } else if (value > position.pixels &amp;&amp; position.pixels >= position.maxScrollExtent) {
      // 滑动到底部边界时,允许继续向下滚动
      return 0.0;
    }
    // 其他情况,使用默认的边界条件
    return super.applyBoundaryConditions(position, value);
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          physics: MyCustomScrollPhysics(), // 使用自定义的ScrollPhysics
          slivers: <Widget>[
            SliverAppBar(
              expandedHeight: 200.0,
              pinned: true,
              flexibleSpace: FlexibleSpaceBar(
                title: Text('Custom Scroll Physics Example'),
              ),
            ),
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) {
                  return ListTile(
                    title: Text('Item $index'),
                  );
                },
                childCount: 100, // 你的列表项数量
              ),
            ),
          ],
        ),
      ),
    );
  }
}

原文地址:https://blog.csdn.net/sadkhkuhkjasga/article/details/134647598

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_20510.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注