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',
  )
];

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章