Flutter之ListView、GridView

ListView

ListView属性代码,与Android中ListView功能一样的列表控件。

ListView({
    Key key,
    Axis scrollDirection: Axis.vertical,//滚动方向
    bool reverse: false,//十分反向显示数据
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,//物理滚动
    bool shrinkWrap: false,
    EdgeInsetsGeometry padding,
    this.itemExtent,//item有效范围
    bool addAutomaticKeepAlives: true,//自动保存视图缓存
    bool addRepaintBoundaries: true,//添加重绘边界
    List<Widget> children: const <Widget>[],
  })

示例中,在ListView的children数组子组件中,添加了多个ListTile,代码如下:

class MyHomePage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new ListView(
      children: <Widget>[
        new ListTile(
          leading: new Icon(Icons.access_alarm_rounded),
          title: Text("闹钟"),
        ),
        new ListTile(
          leading: new Icon(Icons.account_balance_rounded),
          title: Text("主页"),
        ),
        new ListTile(
          leading: new Icon(Icons.add_a_photo_outlined),
          title: Text("相机"),
        ),
        new ListTile(
          leading: new Icon(Icons.airplanemode_on_rounded),
          title: Text("飞机"),
        ),
        new ListTile(
          leading: new Icon(Icons.account_circle),
          title: Text("头像"),
        )
      ],
    );
  }
}

效果:


上面ListView是静态添加的少量数据,所以不能滑动,在实际情况数据多,需要滑动页面的多数据ListView,那么久需要使用ListView.builder。
相比于new ListView()只不过多出了两个参数而已,一个是itemCount指定item的数量,一个是itemBuilder,用来构建Item。

class HomeContent extends StatelessWidget {
  List<String> list = new List();

  HomeContent() {
    for(var i=0;i<20;i++) {
      list.add("第$i条数据");
    }
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: list.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(list[index]),
        );
      },
    );
  }

}

效果:


  • GridView

GirView的用法和ListView类似,只不过由于GridView可以在一列或者一行显示多个Item,这个做Android的都知道。

新增属性:
SliverGridDelegateWithFixedCrossAxisCount:用于固定列数的场景;
SliverGridDelegateWithMaxCrossAxisExtent:用于子元素有最大宽度限制的场景;
子属性:
crossAxisCount :横轴元素个数
crossAxisSpacing:横轴间距
mainAxisSpacing:纵轴间距
childAspectRatio:子组件宽高比例

代码:

class HomeContent extends StatelessWidget {
  List<ListItem> list = new List();

  HomeContent() {
    for (int i = 0; i < 20; i++) {
      list.add(new ListItem(
          "content",
          Image.network(
              "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602884612610&di=99e5e92e7d3fd95d9c922f29c35f4b61&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F57a2a20321de9.jpg",
              alignment: Alignment.topCenter)));
    }
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            mainAxisSpacing: 10,
            crossAxisSpacing: 0,
            childAspectRatio: 2),
        itemCount: list.length,
        itemBuilder: (context, index) {
          return ListTile(
            leading: list[index].image,
            title: Text(list[index].title),
          );
        });
  }
}

class ListItem {
  final String title;
  final Image image;

  ListItem(this.title, this.image);
}

效果:


ListView的item点击事件

在item的Widget的外层包装个GestureDetector,在onTap方法中获取点击事件。

ListView.builder(
            itemCount: list.length,
            itemBuilder: (context, index) {
             return GestureDetector(
                onTap: () {
                 
                },
           )
    }
)
ListView中添加分割线

在item的Container中设置BoxDecoration,添加底边线。

ListView.builder(
        itemCount: 3,
        itemBuilder: (BuildContext context, int index) {
          return Container(
            child: Text('content'),
            // 下边框,及item分割线
            decoration: BoxDecoration(
              border: Border(bottom: BorderSide(width: 0.5, color: Colors.black12))
            ),
          );
        });

推荐阅读更多精彩内容