(九)ListView 基础

ListView介绍

  • ListView是最常用的可滚动widget,它可以沿一个方向线性排布所有子widget
  • 利用默认的构造函数children参数,传入一个Widget列表(List)创建的ListView实例,如下,这种方式适合只有少量的子widget的情况,因为这种方式需要将所有children都提前创建好(这需要做大量工作),而不是等到子widget真正显示的时候再创建。
ListView(
  shrinkWrap: true, 
  padding: const EdgeInsets.all(10.0),
  children: <Widget>[
    const Text('ONE'),
    const Text('TWO'),
    const Text('Three'),
  ],
);
  • ListView.builder适合列表项比较多(或者无限)的情况,因为只有当子Widget真正显示的时候才会被创建,适合动态展现。
    • itemBuilder:它是列表项的构建器,类型为IndexedWidgetBuilder,返回值为一个widget。当列表滚动到具体的index位置时,会调用该构建器构建列表项。
    • itemCount:列表项的数量,如果为null,则为无限列表。
  • ListView.separated可以生成列表项之间的分割器
    • 它比ListView.builder多了一个separatorBuilder参数,该参数是一个分割器生成器。如下例子,奇数行添加一条蓝色下划线,偶数行添加一条绿色下划线。

class MallListBuilderSeparatView extends StatelessWidget {

  Widget _listItemBuilder(BuildContext context, int index){
    return Container(
      color: Colors.white,
      margin: EdgeInsets.all(4.0),
      child: Column(
        children: <Widget>[
          Image.network(posts[index].imageUrl),
          SizedBox(height: 16.0), // 图片下面预留的高度
          Text(
              posts[index].title,
              style:Theme.of(context).textTheme.title
          ),
          Text(
              posts[index].author,
              style:Theme.of(context).textTheme.subhead
          ),
        ],
      ), // 从上到下排列的容器
    );
  }

  @override
  Widget build(BuildContext context) {
    //下划线widget预定义以供复用。
    Widget divider1=Divider(color: Colors.blue,);
    Widget divider2=Divider(color: Colors.green);
    return ListView.separated(
      itemCount: 3,
      //列表项构造器
      itemBuilder: _listItemBuilder,
      //分割器构造器
      separatorBuilder: (BuildContext context, int index) {
        return index%2==0?divider1:divider2;
      },
    );
  }
}

在这里插入图片描述

构造函数介绍

  • scrollDirection 控制滚动方向默认Axis.vertical
  • reverse 在滚动方向默认Axis.vertical时 reverse为false时,那么滑动方向就是从上往下。其实此属性本质上是决定可滚动widget的初始滚动位置是在“头”还是“尾”,取false时,初始滚动位置在“头”,反之则在“尾”。
  • itemExtent:该参数如果不为null,则会强制children的"长度"为itemExtent的值。
    • 这里的"长度"是指滚动方向上子widget的长度,即如果滚动方向是垂直方向,则itemExtent代表子widget的高度,如果滚动方向为水平方向,则itemExtent代表子widget的长度。
    • 在ListView中,指定itemExtent比让子widget自己决定自身长度会更高效,这是因为指定itemExtent后,滚动系统可以提前知道列表的长度,而不是总是动态去计算,尤其是在滚动位置频繁变化时(滚动系统需要频繁去计算列表高度)。

列表Demo

import 'package:flutter/material.dart';
import '../mode/fake_post.dart';

// 独立 _listItemBuilder
class MallListView extends StatelessWidget {

  Widget _listItemBuilder(BuildContext context, int index){
    return Container(
      color: Colors.white,
      margin: EdgeInsets.all(4.0),
      child: Column(
        children: <Widget>[
          Image.network(posts[index].imageUrl),
          SizedBox(height: 16.0), // 图片下面预留的高度
          Text(
            posts[index].title,
            style:Theme.of(context).textTheme.title   
          ),
          Text(
            posts[index].author,
            style:Theme.of(context).textTheme.subhead   
          ),
        ],
      ), // 从上到下排列的容器
    );
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ListView.builder( 
          itemCount: posts.length,
          itemBuilder: _listItemBuilder,//构建列表视图的项目
        ); // 创建列表视图;
  }
}

main 主文件

import 'package:flutter/material.dart';
import 'mall/mall-listview.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
      theme: ThemeData(
        primarySwatch: Colors.blue, // 应用主题颜色
        highlightColor: Color.fromRGBO(255, 255, 255, 0.5),// 点击后背景高亮的颜色
        splashColor: Colors.white54 // 水波纹yanse
      ),
    );
  }
}

class Home extends StatelessWidget {


  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        body: MallListView()
      ),
    );
  }
}

模拟的数据文件 fake_post.dart


class Post {
  const Post({
    this.title,
    this.author,
    this.imageUrl,
  });

  final String title;
  final String author;
  final String imageUrl;
}

final List<Post> posts = [
  Post(
    title: 'Apple iphone X',
    author: 'JD',
    imageUrl: 'https://m.360buyimg.com/babel/jfs/t1/7734/6/15470/209997/5c6fcbc9Ebd1c0f0b/e40b7b0dcac61c54.jpg!q70.jpg'
  ),  
  Post(
    title: '荣耀V20 胡歌同款 麒麟980',
    author: 'JD',
    imageUrl: 'https://m.360buyimg.com/babel/jfs/t18157/222/1822300674/231514/6c179af8/5ad87390N086a3c91.jpg!q70.jpg'
  ),
    Post(
    title: '小米9 xiaomi新品三摄 ',
    author: 'JD',
    imageUrl: 'https://m.360buyimg.com/babel/jfs/t1/7734/6/15470/209997/5c6fcbc9Ebd1c0f0b/e40b7b0dcac61c54.jpg!q70.jpg'
  )
];



在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JaysenLeo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值