flutter中ListView的详细讲解

1.ListView的简单介绍

ListView是最常用的可以滚动组件之一,
它可以沿一个方向进行线性排列所有的子组件。
下面是ListView的属性值介绍:

scrollDirection:列表的滚动方向,
可选值有Axis的horizontal和vertical,
默认是垂直方向上滚动。

controller:控制器,与列表滚动相关,比如监听列表的滚动事件。

physics: 列表滚动至边缘后继续拖动的物理效果,
Android与iOS效果不同。
Android会呈现出一个波纹状(对应ClampingScrollPhysics),
而iOS上有一个回弹的弹性效果(对应BouncingScrollPhysics)。
如果你想不同的平台上呈现各自的效果可以使用AlwaysScrollableScrollPhysics,
它会根据不同平台自动选用各自的物理效果。如果你想禁用在边缘的拖动效果,
那可以使用NeverScrollableScrollPhysics;

shrinkWrap: 该属性将决定列表的长度是否仅包裹其内容的长度。
当ListView嵌在一个无限长的容器组件中时,
shrinkWrap必须为true,否则Flutter会给出警告;

padding: 列表内边距;

itemExtent: 子元素长度。
当列表中的每一项长度是固定的情况下可以指定该值,
有助于提高列表的性能
(因为它可以帮助ListView在未实际渲染子元素之前就计算出每一项元素的位置);

children: 容纳子元素的组件数组。

2.ListTile 属性简介

this.leading,// 内容的==>前置图标
this.title,// 内容的==>标题
this.subtitle,// 内容的==>副标题
this.trailing,// 内容的==>后置图标
this.isThreeLine = false,// 内容的==>是否三行显示
this.dense,// 内容的==>直观感受是整体大小
this.contentPadding,// 内容的==>内容内边距
this.enabled = true,// 内容 是否禁用
this.onTap,// item onTap 点击事件
this.onLongPress,// item onLongPress 长按事件
this.selected = false,// item 是否选中状态

3.ListView的基本使用

我们做一个新闻列表;
结构非常的简单:有主标题和副标题
title(主标题)和subtitle(subtitle)
我们一起来看看长成什么样子。
class MyCont extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(children: <Widget>[
      ListTile(
        // 主标题
        title: Text('Flutter 由 Google 的工程师团队打造,用于创建高性能、跨平台的移动应用',//文字左对齐
            textAlign: TextAlign.left,//超出显示省略号
            overflow: TextOverflow.ellipsis,style: TextStyle(
              //数字必须是Double类型的
              fontSize: 20.0,//  设置字体的颜色
              color: Color.fromARGB(200,100,8)
            )
        ),// 副标题
        subtitle: Text('你好flutter'),),ListTile(
        title: Text('Flutter 由 Google 的工程师团队打造,用于创建高性能、跨平台的移动应用'),subtitle: Text('你好flutter'),]);
  }
}

4.listView列表设置前置图标

class MyCont extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(children: <Widget>[
      ListTile(
        // 主标题
        // 在前面设置图标
        leading: Icon(
          //设置图标类型
          Icons.settings,//0x后面开始 两位FF表示透明度16进制,
          color: Color(0xFFFFB6C1),//这是图标的大小
          size: 30.0
        ),// 在后面设置图标
        // trailing: Icon(Icons.accessible),title: Text('flutter教程_2021 Dart Flutter入门实战视频教程132讲',//文字左对齐
          textAlign: TextAlign.left,//超出显示省略号
          overflow: TextOverflow.ellipsis,style: TextStyle(
            fontSize: 20.0,//数字必须是Double类型的
            //  设置字体的颜色
            color: Color(0xFFFFB6C1)
          )
        ),subtitle: Text('不管是Ios还是Android开发都可以在flutter官网上查到安装及使用步骤,这里我就不累述太多'),]);
  }
}

5.设置前置图片

class MyCont extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(children: <Widget>[
      ListTile(
        // 主标题
        // 通过leading可以将图片放在前面
        leading: Image.network(
          "https://giidu.c/ster/src=http%3A%2F%2Ft14.npg"),title: Text(
            'flutter教程_2021 Dart Flutter入门实战视频教程132讲',textAlign: TextAlign.left,//文字左对齐
            overflow: TextOverflow.ellipsis,//超出显示省略号
            style: TextStyle(
              fontSize: 20.0,//数字必须是Double类型的
              //  设置字体的颜色
              color: Color(0xFFFFB6C1)
            )
          ),]);
  }
}

6.垂直列表

class MyCont extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(children: <Widget>[
      Container(
        width: 750.0,height: 200.0,color:Color(0xFFFFB6C1),// 外边距 左上右下,跟css不一样哈
        margin: EdgeInsets.fromLTRB(10,10,0),Container(
        width: 750.0,color: Color(0xFFFFB6C1),)
    ]);
  }
}

7.水平排列

class MyCont extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200.0,child:new ListView(
        // 水平排列 
        scrollDirection: Axis.horizontal,children: <Widget>[
          Container(
            width: 220.0,// 外边距 左上右下,跟css不一样哈
            margin: EdgeInsets.fromLTRB(10,Container(
            width: 220.0,]
      )
    );
  }
}

8.动态列表

在项目的实际开发过程中;
我们会有很多的列表;
我们想将ListView中children中的代码封装成为一个函数。
方便后期的管理
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(appBar: AppBar(title: Text('首页')),body: MyCont()),//设置顶部的颜色
      theme: ThemeData(primarySwatch: Colors.yellow),);
  }
}

class MyCont extends StatelessWidget {
  // Lis里面的数据必须是Widget组件;
  // _backDataList方法下划线开头,表示当前这个类私有的。
  List<Widget> _backDataList() {
    return [
      ListTile(
        title: Text('我是新闻标题1'),ListTile(
        title: Text('我是新闻标题2'),ListTile(
        title: Text('我是新闻标题3'),ListTile(
        title: Text('我是新闻标题4'),)
    ];
  }

  @override
  Widget build(BuildContext context) {
    return ListView(children: this._backDataList());
  }
}

9.往数组中添加数据进行循环

class MyCont extends StatelessWidget {
  // Lis里面的数据必须是Widget组件;
  // _backDataList方法下划线开头,表示当前这个类私有的。
  List<Widget>_backDataList() {
    // 声明了一个数组,里面的数据类型是Widget
    List<Widget> list = []; 
    for (var i = 0; i < 10; i++) {
      list.add(ListTile(
        title: Text('我是新闻标题$i'),));
    }
    return list;
  }
  @override
  Widget build(BuildContext context) {
    return ListView(children: this._backDataList());
  }
}

10.为什么要使用ListView.builder

ListView.builder下的两个属性值
itemCount:指定被循环数组的长度
itemBuilder:它有2个参数。
itemBuilder(contText,index) {
    contText表示的循环的内容
    index表示循环的索引值
}

如果itemBuilder下是一个封装的函数,
不要添加括号,因为括号表示调用;
直接itemBuilder:this.youFunc就可以了

使用ListView.builder的优势:
ListView.builder适合列表项比较多(或者无限)的情况,
只有当子组件真正显示的时候列表才会被创建,
也就说通过该构造函数创建的ListView是支持基于Sliver的懒加载模型的。
也就是说使用ListView.builder可以提升性能。
下面我们将会使用ListView.builder来创建一个列表
在lib目录下创建一个res
在res目录下创建demo.dart
demo.dart文件下有数据的哈
import 'res/demo.dart';
List listData = [
  {
    'title': 'Python 创作季,秀出你的 Python 文章
  }
]
后面使用listData就可以直接获取数据了哈

class MyCont extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      // itemCount:指定该数组的长度
      itemCount: listData.length,//itemBuilder 会进行循环遍历
      itemBuilder: (contText,index) {
        return ListTile(
          title: Text(listData[index]['title']),//还有很多的属性xxxx........
        );
      },);
  }
}
前面我们说了,使用ListView.builder可以提高性能;
但是我们发现了itemBuilder下如果有很多属性的话;
那么就会变得非常的臃肿的;
后期是不利于我们维护;
那么我们能不能将 itemBuilder中的抽离出去了?
经过我的查询文档发现是可以的
请看下面:

11.将itemBuilder中的属性抽离出去

我们可以将原来itemBuilder下的代码
封装成为一个方法放置在自定义的_getListData下;
方便我们后期的维护以及修改
class MyCont extends StatelessWidget {
  //自定义的方法
  Widget _getListData(contText,index){
    return ListTile(
      title: Text(listData[index]['title']),);
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      // itemCount:指定该数组的长度
      itemCount: listData.length,//this._getListData是不需要加括号的;
      // 我们这里表示的复制该方法
      // this._getListData()表示的是直接去调用这个方法
      itemBuilder:this._getListData
    );
  }
}

12.ListView children与ListView.builder的区别

通过前面的例子,
我们可以发现ListView有默认构造函数。
ListView默认构造函数有一个children参数,
children接受一个Widget列表[List],通过children参数的形式接受的子组件列表。
这种方式需要将所有的children都提前创建好;
因此需要提前做大量的工作;
所以:这种形式只适合少量的子组件的情况

ListView.builder
ListView.builder适合列表项比较多(或者无限)的情况,
只有当子组件真正显示的时候列表才会被创建,
也就说通过该构造函数创建的ListView是支持基于Sliver的懒加载模型的。

13.制作一个好看的列表

我们将使用后置图标trailing这个属性来完成图片后置。
同时我们将给一个容器组件Container;
容器组件的宽高来限制图片的大小;
我们将会对图片进行裁剪,
在lib目录下创建一个res
在res目录下创建demo.dart
demo.dart文件下有数据的哈
import 'res/demo.dart';
List listData = [
  {
    'title': 'Python 创作季,秀出你的 Python 文章
  }
]

class MyCont extends StatelessWidget {
  // Lis里面的数据必须是Widget组件;
  // _backDataList方法下划线开头,表示当前这个类私有的。
  List<Widget> _backDataList() {
    var temtepleList = listData.map((value) {
      return ListTile(
          title: Text(
            value['title'],// 超出显示省略号
            overflow: TextOverflow.ellipsis,style: TextStyle(fontSize: 16.0,color: Color(0xFF86909c)),subtitle: Text(
            value['cont'],overflow: TextOverflow.ellipsis,style: TextStyle(fontSize: 13.0,trailing: Container(
              width: 90.0,//容器宽
              height: 70.0,//容器高
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(4.0),image: DecorationImage(
                  image: NetworkImage(
                    value['img'],alignment: Alignment.topLeft,//左上角居中
                  fit: BoxFit.cover,//裁剪,充满整个容器。不会变形
                ) 
              )
          )
      );
    });
    // 转化成为一个数组
    return temtepleList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(children: this._backDataList());
  }
}

原文地址:https://www.cnblogs.com/IwishIcould

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要讲解了“FlutterComponent动画的显和隐怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究...
这篇文章主要讲解了“flutter微信聊天输入框功能如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“f...
本篇内容介绍了“Flutter之Navigator的高级用法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处...
这篇文章主要介绍“Flutter怎么使用Android原生播放器”,在日常操作中,相信很多人在Flutter怎么使用Android原生播放器问题上存在疑惑,小编查阅了各式资料,整...
Flutter开发的android端如何修改APP名称,logo,版本号,具体的操作步骤:修改APP名称找到文件:android\\app\\src\\main\\AndroidManifest.xml
Flutter路由管理初识路由概念一.路由管理1.1.Route1.2.MaterialPageRoute1.3.Navigator1.4.路由传值1.5 命名路由1.6.命名路由参数传递1.7.适配二、路由钩子三、onUnknownRoute四、结尾初识路由概念路由的概念由来已久,包括网络路由、后端路由,到现在广为流行的前端路由。无论路由的概念如何应用,它的核心是一个路由映射表。比如:名字 detail 映射到 DetailPage 页面等。有了这个映射表之后,我们就可以方便的根据名字来完成路由的转发
前提:针对Android开发者(windows系统下),已安装Git,AndroidStudio(建议4.0+版本)一.下载Flutter SDK地址:https://flutter.dev/docs/development/tools/sdk/releases,在 Stable channel (Windows)里面下最新版本即可。Flutter的渠道版本会不停变动,请以Flutter官网为准。在中国,要想正常获取安装包列表或下载安装包,可能需要翻墙,也可以去Flutter github项目下去下载安
一、变量变量是一个引用,根据Dart中“万物皆对象”原则,即变量存储的都是对象的引用,或者说它们都是指向对象。1.1.声明变量://1.不指定类型var name = 'aaa';//2.明确指定类型String name = 'aaa';因为有类型推导,所以两种实现效果一样,官方推荐在函数内的本地变量尽量使用var声明。在变量类型并不明确的情况下,可以使用dynamic关键字//3.使用dynamic关键字dynamic name = 'aaa';1.2.默认值未初始化的变量
前言Flutter2.0发布不久,对web的支持刚刚进入stable阶段。初学几天,构建web应用时候碰到一些问题,比如中文显示成乱码,然后加载图片出现图片跨域问题:Failed to load network image...Trying to load an image from another domain?1.开启web端构建:使用下面这个命令才可以开启Web端构建的支持flutter config --enable-web提示我们:重新启动编辑器,以便它们读取新设置。2.重
一.Flutter打Android release包的步骤:1.为项目创建一个.jks签名文件(很简单,跳过)2.创建一个文件key.properties,直接复制下面key.properties位置如图:在里面输入一下内容:storePassword=iflytekkeyPassword=iflytekkeyAlias=teachingmachinestoreFile=E:/teacher/app/keys/TeachingMachine.jks输入你自己的passwork以及
1 问题Android原生向js发消息,并且可以携带数据2 实现原理Android原生可以使用RCTEventEmitter来注册事件,然后这里需要指定事件的名字,然后在js那端进行监听同样事件的名字监听,就可以收到消息得到数据Android注册关键代码reactContext.getJSModule(DeviceEventManagerModule.RCT...
1 Flexbox布局1) flexDirection 可以决定布局的主轴,子元素是应该沿着水平轴(row)方向排列,还是沿着竖直轴(column)方向排列2) justifyContent 决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的排列方式 有flex-start、center、flex-end、space-around...
1 实现的功能在网上看React Native文档,我特码就想实现一个页面到另外一个页面的跳转,然后另外一个页面怎么获取参数,特么没找到一个说清楚的,要么太复杂,要么说了不理解,下面是我自己写的一个App.js文件,实现一个Home页面跳到另外Details页面,并且携带了参数怎么在Details页面获取,就是这么简单粗暴.2 测试DemoApp.js文件如下...
1 问题在一个文件构建一个对象,然后在另外一个文件里面new这个对象,通过构造方法传递参数,然后再获取这个参数2 测试代码Student.js文件如下'use strict';import React from 'react'import {NativeModules, NativeEventEmitter, DeviceEventEmitter,Ale...
1 简单部分代码export default class App extends Component&amp;lt;Props&amp;gt; { render() { return ( &amp;lt;View {styles.container}&amp;gt; &amp;lt;View {styles.welcome}&amp;gt; &amp;l...
1 怎么实现发送和接收事件理论上封装了Android原生广播的代码,需要注册和反注册,这里用DeviceEventEmitter实现//增加监听DeviceEventEmitter.addListener//取消监听//this.emitter.remove();这里可也可以通过安卓原生向页面js发送消息,可以参考我的这篇博客React Native之Android原生通过Dev...
1、Component介绍一般Component需要被其它类进行继承,Component和Android一样,也有生命周期英文图片如下2 具体说明1)、挂载阶段constructor()//构造函数,声明之前先调用super(props)componentWillMount()//因为它发生在render()方法前,因此在该方法内同步设置状态...
1 触摸事件普通点击我们可以使用onPress方法,我们可以使用Touchable 系列控件设计我们的按钮TouchableHighlight 背景会在用户手指按下时变暗TouchableNativeFeedback用户手指按下时形成类似墨水涟漪的视觉效果TouchableOpacity指按下时降低按钮的透明度,而不会改变背景的颜色TouchableWithoutFeedbac...
1 问题部分代码如下class HomeScreen extends React.Component { render() { return ( &amp;lt;View {{ flex: 1, alignItems: 'center', justifyContent: 'center' }}&amp;gt; &amp;lt;Text&amp;gt;Home Scre...
1 Props(属性)和State(状态)和简单样式简单使用App.js代码如下/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */import React, {Component} from 'react';import {Pla...