4、Flutter - 控件基础 (二)ListView 列表展示数据、布局

ListView 列表展示数据、布局

 

接上篇,几点注意事项与说明

1、创建工程项目的时候,存放路径不要有中文,有中文会有警告,而且后面可能会有一些未知的问题。
如果有中文路径,创建完工程移动工程位置的时候,用AS 直接运行编辑是没有问题的,因为AS会自动修改,但是如果直接用xcode 打开的话是有问题的。可以用AS打开运行之后再去用xcode 打开,这样配置的路径就会修改了。

2、Dart 中没有析构函数,有自己的垃圾回收机制
不同于OC 需要些 dealloc

3、MaterialApp()
右上角会显示出来一个DEBUG 图标,可以在 MaterialApp() 里面设值,让其消失
debugShowCheckedModeBanner: false,

 

用一个 Demo 来说明部分功能

Demo地址 -> flutter_testdemo1

效果如下:

 

1、数据模型

首先定义一下数据模型,上图可知有name 和 image

创建一个文件car.dart

1.1、系统自动添加构造函数

第一种如下这样写,不需要我们自己写构造函数,系统会自动处理。

 但是如果我们这些数据是不需要修改的(运行时赋值之后不再修改),那么这样写也可以,只不过没有加上final 修饰更节约性能

car.dart

//不需要自己写构造函数,系统会自动处理
class Car {
  String name;
  String imageUrl;
}

main.dart 调用

  //  1、属性不加fina
  Car ca1 = Car();
  ca1.name = 'liujilou';
  ca1.imageUrl = 'url';

2、final修饰,手动添加构造函数(不可选参数)

car.dart

//如果变量后面不需要修改用fine 修饰,赋值之后就不可变。是运行时的,能节约一点性能
//需要些构造函数,可以直接 option + enter
//这样的话 main中就不能直接点 赋值了,需要调用Car函数传值.这叫同名构造函数
// 传值是更跟传过来的顺序有关系
class Car {
  final String name;
  final String imageUrl;

//  const 修饰是为了以后区分有状态无状态进行界面渲染的时候,全是常量的模型重新构建
//  如果全是final 修饰的不改变的变量的模型。不去重新构建提高性能
//  const 修饰的前提是,成员必须都是final 的时候
//  const Car(this.name, this.imageUrl);
  Car(this.name, this.imageUrl);

}

main.dart

//2、属性加fina 用如下构造函数
 Car ca1 = Car('liujilou', 'url');

3、final修饰,手动添加构造函数(可选参数)

car.dart

class Car {
  final String name;
  final String imageUrl;

//  用{}括住的是可选参数,没有括住的是必填参数
//  Car(this.name, {this.imageUrl});
  Car({this.name, this.imageUrl});

main.dart

//  3、用{}括住的是可选参数,没有括住的是必填参数
//  可选参数的传值,需要用属性名。不需要传值的时候,可以不传
//  Car ca1 = Car('liujilou',imageUrl: 'url');
  Car ca1 = Car(name: 'liujilou', imageUrl: 'url');

4、通过数组返回对象

class Car {
  String name;
  String imageUrl;

//  通过一个数组返回一个对象,这个时候就不能用final 了
//  这里name = list[0] 这个类似字典没事根据数据中的值,取出来赋值给对应的
  Car.fromList(List<dynamic> list) {
    name = list[0];
    imageUrl = list[1];
  }

  //调用的方法1
  Car.defalut(String name,String url){
    Car(name: name, imageUrl: url);
  }

  //调用的方法2
  //: 代表重定向,也就是左边的参数传过来之后,直接调用右边的函数(注意函数名)
  Car.defalut(String name, String url) : this.fromList([name,url]);
//或
  Car.defalut(String name, String url) : this(name: name, imageUrl: url);
}

main.dart

  Car.fromList(['liujilou','url']);
//或
  Car ca1 = Car.defalut('liujilou', 'url');

 

2、布局

2.1、ListView

这里将ListView单独抽出来写成一个文件,方便以后修改

listview_demo.dart

import 'package:flutter/material.dart';

import 'car.dart';

class ListViewDemo extends StatelessWidget {
  //  定义一个函数.这里不要写死,要不后面需要修改的话不好修改,
//  return一个容器 Container,将控件放进去
  Widget _itemForRow(BuildContext context, int index) {
    return Container(
        color: Colors.white,
        margin: EdgeInsets.all(10),
        child: Column(children: <Widget>[
          Image.network(datas[index].imageUrl),
//         margin: EdgeInsets.fromLTRB(0, 0, 0, 10),
          SizedBox(
            height: 10,
          ),
          Text(
            datas[index].name,
            style: TextStyle(
              fontWeight: FontWeight.w800,
              fontSize: 18.0,
              fontStyle: FontStyle.values[1],
            ),
          ),
        ]));
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: datas.length, //相当于iOS中的cell个数
      itemBuilder: _itemForRow,
    );
  }
}

final List<Car> datas = [];//数据在文章最后写的,以免数据太占篇幅影响阅读

car.dart

class Car {
  final String name;
  final String imageUrl;

  Car({this.name, this.imageUrl});
}

1、设置约束,距离

margin: EdgeInsets.all(10),

EdgeInsets.fromLTRB(left, top, right, bottom),

 

2、纵向布局控件

里面是数组
child: Column(children: <Widget>[

])

 

3、填空,给一个高或者宽就行了

例如在纵向布局中,给一个高度,就是出现整个屏幕宽度,和给定高度的一个矩形。

在两个item(类型iOS中的cell)中间需要隔开的时候使用功能,或者是两个控件之间加间距的时候都可以使用
SizedBox(
  height: 10,
),

 

4、图片

Image.network(datas[index].imageUrl),  //网络图片

Image(image: AssetImage('images/icon.png')), //本地图片

 

在main.dart 中调用

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertestdome1/model/listview_demo.dart';

//void main() {
//  //  1、属性不加fina
//  Car ca1 = Car();
//  ca1.name = 'liujilou';
//  ca1.imageUrl = 'url';
//
2、属性加fina 用如下构造函数
// Car(this.name, this.imageUrl);
//  Car ca1 = Car('liujilou', 'url');

//  3、用{}括住的是可选参数,没有括住的是必填参数
//  可选参数的传值,需要用属性名。不需要传值的时候,可以不传
//  const Car(this.name, {this.imageUrl});
//  Car ca1 = Car('liujilou',imageUrl: 'url');
//  Car ca1 = Car('liujilou', 'url');
//  Car ca1 = Car(name: 'liujilou', imageUrl: 'url');

  Car.fromList(['liujilou','url']);
//  Car ca1 = Car.defalut('liujilou', 'url');
//
//  print('\nname:' + ca1.name + 'imageUrl:' + ca1.imageUrl);
//}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Home(),
        theme: ThemeData(
          primaryColor: Colors.blue,
        ));
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.grey,
        appBar: AppBar(
          title: Text('Flutte Demo'),
        ),
        body: ListViewDemo());
  }
}

 

listview_demo.dart

中的数据列表就放到最下边了,以免放到上面影响阅读

final List<Car> datas = [
  Car(
    name: '保时捷918 Spyder',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '兰博基尼Aventador',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '法拉利Enzo',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: 'Zenvo ST1',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '迈凯伦F1',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '萨林S7',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '科尼赛克CCR',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '布加迪Chiron',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '轩尼诗Venom GT',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  ),
  Car(
    name: '西贝尔Tuatara',
    imageUrl:
        'https://upload-images.jianshu.io/upload_images/2990730-3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
  )
];

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值