flutter学习ListView

Posted 临风而眠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flutter学习ListView相关的知识,希望对你有一定的参考价值。

flutter学习(4)ListView

文章目录

一.基础列表组件

  • 垂直列表
  • 垂直图文列表
  • 水平列表
  • 动态列表
  • 矩阵式列表

二.列表参数

三.垂直列表

  • 基本列表

    import 'package:flutter/material.dart';
    import 'package:testforgramma/main_bk2.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget 
      // const MyApp(Key? key) : super(key: key);
    
      @override
      Widget build(BuildContext context) 
        return MaterialApp(
            home: Scaffold(
          appBar: AppBar(title: Text('FltterDemo')),
          body: HomeContent(),
        ));
      
    
    
    
    class HomeContent extends StatelessWidget 
      @override
      Widget build(BuildContext context) 
        return ListView(
          children: <Widget>[
            ListTile(
              title: Text("冬奥会", style: TextStyle(fontSize: 24)),
              subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)),
            )
          ],
        );
      
    
    
    • 用一下刚学的提取代码快捷键嘿嘿

      抽取出来

      import 'package:flutter/material.dart';
      import 'package:testforgramma/main_bk2.dart';
      
      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget 
        // const MyApp(Key? key) : super(key: key);
      
        @override
        Widget build(BuildContext context) 
          return MaterialApp(
              home: Scaffold(
            appBar: AppBar(title: Text('FltterDemo')),
            body: HomeContent(),
          ));
        
      
      
      class HomeContent extends StatelessWidget 
        // const HomeContent(Key? key) : super(key: key);
      
        @override
        Widget build(BuildContext context) 
          return ListView(
            children: <Widget>[
              buildListTile(),
              buildListTile(),
              buildListTile(),
              buildListTile(),
            ],
          );
        
      
        ListTile buildListTile() 
          return const ListTile(
            title: Text("冬奥会", style: TextStyle(fontSize: 24)),
            subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)), //二级标题
          );
        
      
      
    • ListTile可加图标

      leading属性

        ListTile buildListTile() 
          return const ListTile(
            leading: Icon(Icons.search, color: Colors.blue),
            title: Text("冬奥会", style: TextStyle(fontSize: 24)),
            subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)), //二级标题
          );
        
      
      
      
      • 多玩几个图标

        leading是前面的图标

        trailing是后面的图标

        import 'package:flutter/material.dart';
        
        void main() => runApp(MyApp());
        
        class MyApp extends StatelessWidget 
          // const MyApp(Key? key) : super(key: key);
        
          @override
          Widget build(BuildContext context) 
            return MaterialApp(
                home: Scaffold(
              appBar: AppBar(title: Text('FltterDemo')),
              body: HomeContent(),
            ));
          
        
        
        class HomeContent extends StatelessWidget 
          // const HomeContent(Key? key) : super(key: key);
        
          @override
          Widget build(BuildContext context) 
            return ListView(
              children: const <Widget>[
                ListTile(
                    leading: Icon(Icons.search, color: Colors.blue, size: 40),
                    title: Text("冬奥会", style: TextStyle(fontSize: 24)),
                    subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18))),
                //二级标题
                ListTile(
                  leading: Icon(Icons.ac_unit, color: Colors.blue),
                  title: Text("冬奥会", style: TextStyle(fontSize: 24)),
                  subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)),
                  trailing: Icon(Icons.ac_unit, color: Colors.blue),
                ),
        
                //二级标题
                ListTile(
                  leading: Icon(Icons.home_max, color: Colors.blue),
                  title: Text("冬奥会", style: TextStyle(fontSize: 24)),
                  subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)),
                  trailing: Icon(Icons.accessibility_new_outlined, color: Colors.blue),
                ),
              ],
            );
          
        
        
    • leading 也可以是远程图片

      class HomeContent extends StatelessWidget 
        // const HomeContent(Key? key) : super(key: key);
      
        @override
        Widget build(BuildContext context) 
          return ListView(
            children: <Widget>[
              ListTile(
                  leading: Image.network(
                      "https://tse4-mm.cn.bing.net/th/id/OIP-C.Hi8-77RG-95MCRQF9gaFxgHaHI?w=214&h=206&c=7&r=0&o=5&dpr=1.38&pid=1.7"),
                  title: Text("冬奥会", style: TextStyle(fontSize: 24)),
                  subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18))),
              //二级标题
              ListTile(
                leading: Icon(Icons.ac_unit, color: Colors.blue),
                title: Text("冬奥会", style: TextStyle(fontSize: 24)),
                subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)),
                trailing: Icon(Icons.ac_unit, color: Colors.blue),
              ),
      
              //二级标题
              ListTile(
                leading: Icon(Icons.home_max, color: Colors.blue),
                title: Text("冬奥会", style: TextStyle(fontSize: 24)),
                subtitle: Text("2022北京冬奥顺利开展", style: TextStyle(fontSize: 18)),
                trailing: Icon(Icons.accessibility_new_outlined, color: Colors.blue),
              ),
            ],
          );
        
      
      

      加载了这个网络图片,就不能const 了

  • 图文列表👇

  • 中间用Container人为扩大图片间距

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget 
      // const MyApp(Key? key) : super(key: key);
    
      @override
      Widget build(BuildContext context) 
        return MaterialApp(
            home: Scaffold(
          appBar: AppBar(title: Text('FltterDemo')),
          body: HomeContent(),
        ));
      
    
    
    class HomeContent extends StatelessWidget 
      // const HomeContent(Key? key) : super(key: key);
    
      @override
      Widget build(BuildContext context) 
        return ListView(
          padding: EdgeInsets.all(10),
          children: <Widget>[
            Image.network(
              "https://tse4-mm.cn.bing.net/th/id/OIP-C.Hi8-77RG-95MCRQF9gaFxgHaHI?w=214&h=206&c=7&r=0&o=5&dpr=1.38&pid=1.7",
              colorBlendMode: BlendMode.colorBurn,
              color: Colors.blue,
            ),
            Container(
                child: Text('标题在此',
                    textAlign: TextAlign.center, style: TextStyle(fontSize: 28)),
                height: 40),
            Image.network(
              "https://tse4-mm.cn.bing.net/th/id/OIP-C.Hi8-77RG-95MCRQF9gaFxgHaHI?w=214&h=206&c=7&r=0&o=5&dpr=1.38&pid=1.7",
              colorBlendMode: BlendMode.colorDodge,
              color: Colors.cyan,
            ),
            Image.network(
              "https://tse4-mm.cn.bing.net/th/id/OIP-C.Hi8-77RG-95MCRQF9gaFxgHaHI?w=214&h=206&c=7&r=0&o=5&dpr=1.38&pid=1.7",
              colorBlendMode: BlendMode.darken,
              color: Colors.blueAccent,
            ),
            Image.network(
                "https://tse4-mm.cn.bing.net/th/id/OIP-C.Hi8-77RG-95MCRQF9gaFxgHaHI?w=214&h=206&c=7&r=0&o=5&dpr=1.38&pid=1.7"),
          ],
        );
      
    
    
    

四.水平列表

由scrollDirection属性来决定是水平还是垂直列表

水平列表的height是自适应的

垂直列表的width是自适应的

class HomeContent extends StatelessWidget 
  const HomeContent(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return ListView(
      scrollDirection: Axis.horizontal,
      padding: EdgeInsets.all(10),
      children: <Widget>[
        Container(height: 100, width: 100, color: Colors.deepOrange),
        Container(height: 100, width: 100, color: Colors.deepPurpleAccent),
        Container(height: 100, width: 100, color: Colors.cyanAccent)
      ],
    );
  

放进Container里面可以限制其高度

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget 
  // const MyApp(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FltterDemo')),
      body: HomeContent(),
    ));
  


class HomeContent extends StatelessWidget 
  const HomeContent(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Container(
        height: 80,
        child: ListView(
          scrollDirection: Axis.horizontal,
          padding: EdgeInsets.all(10),
          children: <Widget>[
            Container(height: 100, width: 100, color: Colors.deepOrange),
            Container(height: 100, width: 100, color: Colors.deepPurpleAccent),
            Container(height: 100, width: 100, color: Colors.cyanAccent)
          ],
        ));
  



class HomeContent extends StatelessWidget 
  const HomeContent(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Container(
        height: 480,
        child: ListView(
          scrollDirection: Axis.horizontal,
          padding: EdgeInsets.all(10),
          children: <Widget>[
            Container(height: 100, width: 100, color: Colors.deepOrange),
            Container(
                height: 100,
                width: 100,
                color: Colors.deepPurpleAccent,
                child: ListView(
                  children: <Widget>[
                    Image.network(
                      "https://tse4-mm.cn.bing.net/th/id/OIP-C.Hi8-77RG-95MCRQF9gaFxgHaHI?w=214&h=206&c=7&r=0&o=5&dpr=1.38&pid=1.7",
                      colorBlendMode: BlendMode.colorDodge,
                      color: Colors.cyan,
                    ),
                    Text("冬奥会")
                  ],
                )),
            Container(height: 100, width: 100, color: Colors.cyanAccent)
          ],
        ));
  

五.动态列表

  • 前面的都是静态列表

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget 
      const MyApp(Key? key) : super(key: key);
    
      @override
      Widget build(BuildContext context) 
        return MaterialApp(
            home: Scaffold(
          appBar: AppBar(title: Text('Flutter列表')),
          body: HomeContent(),
        ));
      
    
    
    class HomeContent extends StatelessWidget 
      const HomeContent(Key? key) : super(key: key);
    
      @override
      Widget build(BuildContext context) 
        return ListView(
          children: <Widget>[
            ListTile(
              tileColor: Colors.cyanAccent,
              leading: CircleAvatar(
                backgroundImage: NetworkImage(
                    "https://pic.52112.com/2019/12/23/EPS-191223_124/gBShjDAniH_small.jpg"),
              ),
              title: Text(
                'Horse',
                textAlign: TextAlign.end,
              ),
            ),
            Text("1", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
            Text("2", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
            Text("3", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
            Text("4", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
          ],
        );
      
    
    
    

for循环遍历

  • 把一个数组里的数据循环遍历到页面上就是循环数组

    • 先就把列表返回回来

      import 'package:flutter/material.dart';
      
      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget 
        const MyApp(Key? key) : super(key: key);
      
        @override
        Widget build(BuildContext context) 
          return MaterialApp(
              home: Scaffold(
            appBar: AppBar(title: Text('Flutter列表')),
            body: HomeContent(),
          ));
        
      
      
      class HomeContent extends StatelessWidget 
        const HomeContent(Key? key) : super(key: key);
      
        List<Widget> _getData() 
          return [
            ListTile(
              tileColor: Colors.cyanAccent,
              leading: CircleAvatar(
                backgroundImage: NetworkImage(
                    "https://pic.52112.com/2019/12/23/EPS-191223_124/gBShjDAniH_small.jpg"),
              ),
              title: Text(
                'Horse',
                textAlign: TextAlign.end,
              ),
            ),
            ListTile(
              title: Text("我是一个列表"),
            ),
            ListTile(title: Text("我也是一个列表")),
            Text("1", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
            Text("2", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
            Text("3", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
            Text("4", textAlign: TextAlign.center, style: TextStyle(fontSize: 24)),
          ];
        
      
        @override
        Widget build(BuildContext context) 
          return ListView(
            children: this._getData(),
          );
        
      
      
      

    • 循环列表

      class HomeContent extends StatelessWidget 
        List<Widget> list = List.empty(growable: true);
      
        List<Widget> _getData() 
          for (var i = 0; i < 20; i++) 
            list.add(ListTile(title: Text("列表第$i行")));
          
          return list;
        
      
        @override
        Widget build(BuildContext context) 
          return ListView(
            children: this._getData(),
          );
        
      
      
      

      遇到的问题:

      List<Widget> list = new List();
      

      报错:

      The default 'List' constructor isn't available when null safety is enabled. Try using a list literal, 'List.filled' or 'List.generate'.

      解决参考:

      Flutter2.2 new List() 已弃用 替换方案

      官方文档

  • 从服务器上获取数据

    在lib文件夹里面新建res文件夹,新建listData.dart

      List listData=[
          
              "title": 'Candy Shop',
              "author": 'Mohamed Chahin',
              "imageUrl": 'https://www.itying.com/images/flutter/1.png',
          ,
           
              "title": 'Childhood in a picture',
              "author": 'Google',
              "imageUrl": 'https://www.itying.com/images/flutter/2.png',
          ,
          
              "title": 'Alibaba Shop',
              "author": 'Alibaba',
              "imageUrl": 'https://www.itying.com/images/flutter/3.png',
          ,
          
              "title": 'Candy Shop',
              "author": 'Mohamed Chahin',
              "imageUrl": 'https://www.itying.com/images/flutter/4.png',
          ,
           
              "title": 'Tornado',
              "author": 'Mohamed Chahin',
              "imageUrl": 'https://www.itying.com/images/flutter/5.png',
          ,
          
              "title": 'Undo',
              "author": 'Mohamed Chahin',
              "imageUrl": 'https://www.itying.com/images/flutter/6.png',
          ,
          
              "title": 'white-dragon',
              "author": 'Mohamed Chahin',
              "imageUrl": 'https://www.itying.com/images/flutter/7.png',
                
    
      ];
    
    
    • 在main.dart里面引入

      import './res/listData.dart';
      

      修改刚刚的List <Widget> _getdata()方法

        List<Widget> _getData() 
          var tempList = listData.map((value) 
            return ListTile(title: Text(value["title"]));
          );
          //map方法对列表每一项进行遍历
          return tempList.toList();
        
      
      • 效果

      完善那个动态列表

      List<Widget> _getData() 
      
      	var tempList = listData.map( (value) 
      	
      		return ListTile(
      		
      			leading: Image.network(value["imageUrl"]),
      			title: Text(value["title"]),
      			subtitle: Text(value["author"]),
      		);
      	
      		
      	);
      
      	return tempList.tolist();
      
      
      • 效果

ListView.builder实现循环

普通列表

import 'package:flutter/material.dart';
import './res/listData.dart';

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

class MyApp extends StatelessWidget 
  const MyApp(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(title: Text('Flutter列表')), body: HomeContent()));
  


class HomeContent extends StatelessWidget 
  List list_2 = [];
  //构造函数给list增加点数据
  HomeContent() 
    for (var i = 0; i < 20; i++) 
      this.list_2.add('我是第$i条');
    
  

  @override
  Widget build(BuildContext context) 
    return ListView.builder(
      itemCount: this.list_2.length,
      //指定长度
      itemBuilder: (context, index) 
        return ListTile(title: Text(this.list_2[index]));
        //每一项返回组件
      ,
    );
  

刚刚那个listData.dart里面的数据

class HomeContent extends StatelessWidget 
  @override
  ListTile _getListData(context, index) 
    return ListTile(
        leading: Image.network(listData[index]["imageUrl"]),
        title: Text(listData[index]["title"]),
        subtitle: Text(listData[index]["author"]));
    //每一项返回组件
  

  Widget build(BuildContext context) 
    return ListView.builder(
        itemCount: listData.length,
        //指定长度
        itemBuilder: this._getListData //赋值
        );
  

以上是关于flutter学习ListView的主要内容,如果未能解决你的问题,请参考以下文章

Flutter学习-滚动的Widget

flutter学习之Listview

Flutter项目中ListView的滚动不流畅

Flutter从ListView的左滑删除,简单理解KeyWidget与Element之间的关系

Flutter从ListView的左滑删除,简单理解KeyWidget与Element之间的关系

Flutter学习 可滚动Widget 上