喜迎
春节

基础结构


Flutter项目结构通常包含lib、android、ios等目录,其中lib目录存放Dart代码,android和ios目录分别存放平台相关的代码。

1 基本结构

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('基本结构')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text('Hello Flutter!'),
    );
  }
}

2 容器组件

  • 容器组件:Container,与HTML中的div标签相似,主要用于布局。
    • decoration(装饰容器,例如:给容器添加背景或边框等)。
    • margin(和容器外部的间距)、padding(和容器内部的间距)。
    • width(容器宽度)、height(容器高度)、child(容器子元素)。
    • alignment(调整容器中组件的位置)、transform(让容器进行位移、缩放、旋转等)。
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('容器组件')),
        // body: const MyApp(),
        body: Column(
          children: const [
            MyApp(),
            MyButton(),
          ],
        ),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        // 配置容器内元素方位,center居中
        // alignment: Alignment.topLeft,
        // topLeft左上,bottomRight右下
        alignment: Alignment.center,
        // 配置容器外部间距,设置顶部高度
        margin: const EdgeInsets.fromLTRB(0, 60, 0, 0),
        // 配置容器宽度
        width: 270,
        // 配置容器高度
        height: 270,
        // 沿着y轴向下平移3
        transform: Matrix4.translationValues(0, 3, 0),
        // 沿着Z轴旋转0.2
        // transform: Matrix4.rotationZ(0.2),
        // 沿着Y轴倾斜缩放10
        // transform: Matrix4.skewY(10),
        decoration: BoxDecoration(
          // 配置容器的背景颜色
          color: Colors.green,
          // 配置边框颜色和宽度
          border: Border.all(
            color: Colors.purple,
            width: 3,
          ),
          // 配置容器圆角,100可实现圆形
          borderRadius: BorderRadius.circular(25),
          // 配置容器阴影效果
          boxShadow: const [
            BoxShadow(
              color: Colors.blue,
              blurRadius: 30.0,
            ),
          ],
          // 配置容器渐变颜色
          gradient: const LinearGradient(
            // LinearGradient背景线性渐变
            colors: [
              // RadialGradient径向渐变
              Colors.green,
              Colors.yellow,
            ],
          ),
        ),
        child: const Text(
          '容器组件',
          style: TextStyle(
            color: Colors.white,
            fontSize: 66,
          ),
        ),
      ),
    );
  }
}

// 创建一个自定义的按钮
class MyButton extends StatelessWidget {
  const MyButton({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      width: 200,
      height: 50,
      // 配置MyApp与MyButton边距
      // margin: const EdgeInsets.all(20),
      margin: const EdgeInsets.fromLTRB(0, 60, 0, 0),
      // 可替换alignment
      // padding: const EdgeInsets.all(5),
      // padding: const EdgeInsets.fromLTRB(70, 0, 0, 0),
      decoration: BoxDecoration(
        color: Colors.blue,
        // 配置按钮圆角
        borderRadius: BorderRadius.circular(20),
      ),
      child: const Text(
        '按钮',
        style: TextStyle(
          color: Colors.white,
          fontSize: 30,
        ),
      ),
    );
  }
}

3 文本组件

  • style(文本样式,参数如下)、maxLines(文本显示的最大行数)。
    • color(文字颜色)、fontWeight(字体粗细:bold粗体、normal正常体)。
    • fontSize(文字大小)、fontStyle(文字样式:italic斜体、normal正常体)。
    • wordSpacing(单词间隙:负值则单词变紧凑)、letterSpacing(字母间隙:负值则字母变紧凑)。
    • decoration(文字装饰线:none无线、lineThrough删除线、overline上划线、underline下划线)。
    • decorationColor(文字装饰线颜色:red、orange、yellow、green、cyan青、blue蓝、purple紫)。
    • decorationStyle(文字装饰线风格:[dashed/dotted]虚、double两根、solid一根实、wavy波浪)。
  • overflow(文本超出屏幕后的处理方式:clip裁剪、fade渐渐隐藏、ellipsis省略号)。
  • textAlign(文本对齐方式:center居中、left左对齐、right右对齐、justfy两端对齐)。
  • textScaleFactor(字体缩放)、textDirection(文本方向:ltr从左至右、rtl从右至左)。
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('文本组件')),
        body: const MyText(),
      ),
    ),
  );
}

class MyText extends StatelessWidget {
  const MyText({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 200,
      margin: const EdgeInsets.all(100),
      decoration: const BoxDecoration(
        color: Colors.yellow,
      ),
      child: const Text(
        '纸上得来终觉浅,绝知此事要躬行。—— 冬夜读书示子聿 ▪ 陆游',
        // 文本对齐方式
        textAlign: TextAlign.left,
        // 溢出显示隐藏点
        overflow: TextOverflow.ellipsis,
        // 文本显示最大行数
        maxLines: 1,
        style: TextStyle(
          // 字体大小20
          fontSize: 20,
          // 字体加粗900
          fontWeight: FontWeight.w900,
          // 字体颜色
          color: Colors.red,
          // 字体倾斜
          fontStyle: FontStyle.italic,
          // 字体间距
          letterSpacing: 2,
          // 下划线
          decoration: TextDecoration.underline,
          // 下划线黑色
          decorationColor: Colors.blue,
          // 波浪线
          decorationStyle: TextDecorationStyle.wavy,
        ),
      ),
    );
  }
}

4 图片组件

  • Image.network:加载远程图片。
    • alignment(图片对齐方式)、fit(依父容器控制图片的拉伸)、repeat(横纵或整个画布平铺)。
    • color和colorBlendMode(图片的背景颜色,通常两者配合使用,即图片颜色与背景色混合)。
    • width(图片宽度,结合ClipOval才能看到效果)、height(高度,结合ClipOval才能看到效果)。
  • Image.asset:加载本地图片,需在项目根目录中新建images目录(放置本地图片)并修改配置文件。
# myflutter(项目名)目录结构如下
- images/
  - 1.0x/
    - a.jpg
  - 2.0x/
    - b.jpg
  - c.jpg
- pubspec.yaml

# 修改pubspec.yaml配置文件内容
assets:
  - images/1.0x/a.jpg
  - images/2.0x/b.jpg
  - images/c.jpg

4-1 加载远程图片

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('加载远程图片')),
        // body: const MyApp(),
        body: Column(
          children: const [
            MyApp(),
            // 设置两容器间距
            SizedBox(height: 5),
            MyCircle(),
          ],
        ),
      ),
    ),
  );
}

/*
图片地址:http://gg.gg/13jnaa、http://gg.gg/13kuon、http://gg.gg/13kuow
*/

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        margin: const EdgeInsets.fromLTRB(0, 5, 0, 0),
        height: 300,
        width: 200,
        decoration: const BoxDecoration(
          color: Colors.yellow,
        ),
        child: Image.network(
          'http://gg.gg/13jnaa',
          // 图片向左居中
          // alignment: Alignment.centerLeft,
          // 图片缩小一倍
          // scale: 2,
          // 图片充满容器,可能会压缩变形
          // fit: BoxFit.fill,
          // 图片充满容器,自动裁剪成容器大小
          fit: BoxFit.cover,
          // 宽度裁剪
          // fit: BoxFit.fitWidth,
          // 高度裁剪
          // fit: BoxFit.fitHeight,
          // X轴平铺
          // repeat: ImageRepeat.repeatX,
          // Y轴平铺
          // repeat: ImageRepeat.repeatY,
          // X和Y轴都平铺
          // repeat: ImageRepeat.repeat,
        ),
      ),
    );
  }
}

// 实现椭圆图片
class MyCircle extends StatelessWidget {
  const MyCircle({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 288,
      width: 200,
      decoration: BoxDecoration(
        color: Colors.yellow,
        borderRadius: BorderRadius.circular(100),
        // 背景图片
        image: const DecorationImage(
          image: NetworkImage('http://gg.gg/13kuon'),
          fit: BoxFit.cover,
          // 图片会变形
          // fit: BoxFit.fill,
        ),
      ),
    );
  }
}

4-2 实现圆形图片

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('实现圆形图片')),
        body: const ClipImage(),
      ),
    ),
  );
}

/*
图片地址:http://gg.gg/13jnaa、http://gg.gg/13kuon、http://gg.gg/13kuow
*/

class ClipImage extends StatelessWidget {
  const ClipImage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ClipOval(
        child: Image.network(
          'http://gg.gg/13kuow',
          width: 300,
          height: 300,
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

4-3 加载本地图片

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('加载本地图片')),
        body: const LocalImage(),
      ),
    ),
  );
}

class LocalImage extends StatelessWidget {
  const LocalImage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.fromLTRB(50, 50, 50, 50),
      height: 500,
      width: 300,
      decoration: const BoxDecoration(
        color: Colors.yellow,
      ),
      child: Image.asset(
        'images/1.0x/a.jpg',
        // 'images/2.0x/b.jpg',
        // 'images/c.jpg',
        // fit: BoxFit.cover,
      ),
    );
  }
}

5 图标组件

  • 官方Icons图标(需要梯子访问):https://fonts.google.com/icons
  • 自定义图标:阿里巴巴矢量图标库,需要注册账号才能下载使用。
    • 下载自定义图标所对应的.ttf文件,将其复制粘贴到项目根目录的新建文件夹fonts中。
    • 例如在“阿里巴巴矢量图标库”中搜索想要的图标,加入购物车,购物车页点下载代码。
    • 解压下载的压缩包,复制其中的.ttf文件粘贴到fonts中,并修改pubspec.yaml配置文件。
# myflutter(项目名)目录结构如下
- fonts/
  - iconfont.ttf
- lib/
  - icon.dart
  - main.dart
- pubspec.yaml

# 修改pubspec.yaml配置文件内容
# family可依据需求自定义字体,并在lib目录中新建icon.dart文件
fonts:
  - family: Schyler
    fonts:
      - asset: fonts/iconfont.ttf

5-1 main.dart

import './icon.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('图标组件')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: const [
        SizedBox(height: 20),
        // 官方图标
        Icon(Icons.home, size: 60, color: Colors.red),
        SizedBox(height: 20),
        Icon(Icons.shop, size: 60, color: Colors.deepPurple),
        SizedBox(height: 20),
        // 自定义图标
        Icon(icon.book, size: 60, color: Colors.lightBlueAccent),
        SizedBox(height: 20),
        Icon(icon.wechat, size: 60, color: Colors.green),
        SizedBox(height: 20),
        // 自定义图标
        Icon(icon.cart, size: 60, color: Colors.cyan),
      ],
    );
  }
}

5-2 icon.dart

import 'package:flutter/material.dart';

class icon {
  static const IconData book = IconData(
    0Xe634,
    // code对应编码,解压的json文件中对应图标的unicode值
    // 保留Ox部分,或取css文件中的content值,去掉“\”
    // pubspec.yaml配置文件中,family依据需求自定义的字体
    fontFamily: 'Schyler',
    matchTextDirection: true,
  );
  static const IconData wechat = IconData(
    0Xe63f,
    fontFamily: 'Schyler',
    matchTextDirection: true,
  );
  static const IconData cart = IconData(
    0Xe826,
    fontFamily: 'Schyler',
    matchTextDirection: true,
  );
}

6 列表组件

  • 列表布局是开发中最常用的一种布局,通过ListView来定义列表项,支持垂直和水平方向展示。
  • 通过一个属性就可以控制列表的显示方向,其中列表又分成了垂直列表、水平列表和动态列表。
  • 常用参数
    • padding(内边距)、resolve(组件反向排序)、children(列表元素)。
    • scrollDirection(Axis.vertical垂直列表、Axis.horizontal水平列表)。

6-1 垂直列表

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('垂直列表')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    // 可上下滑动页面进行查看
    return ListView(
      children: const <Widget>[
        ListTile(
          leading: Icon(Icons.home, color: Colors.lightBlue),
          title: Text('首页'),
        ),
        // 水平分隔线
        Divider(),
        ListTile(
          leading: Icon(Icons.assignment, color: Colors.green),
          title: Text('订单'),
          // 右侧显示进入页面的“>”图标
          trailing: Icon(Icons.chevron_right_sharp),
        ),
        Divider(),
        ListTile(
          leading: Icon(Icons.payment, color: Colors.orange),
          title: Text('待付'),
          trailing: Icon(Icons.chevron_right_sharp),
        ),
        Divider(),
        ListTile(
          leading: Icon(Icons.favorite, color: Colors.red),
          title: Text('收藏'),
          trailing: Icon(Icons.chevron_right_sharp),
        ),
        Divider(),
        ListTile(
          leading: Icon(Icons.people, color: Colors.blueGrey),
          title: Text('客服'),
          trailing: Icon(Icons.chevron_right_sharp),
        ),
        Divider(),
      ],
    );
  }
}

(1) 图文列表

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('图文列表')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: const EdgeInsets.all(10),
      children: <Widget>[
        ListTile(
          leading: Image.network(
              'https://img2.baidu.com/it'
              '/u=2418477747,2527785597&fm=253'
              '&fmt=auto&app=138&f=JPEG?w=500&h=500',
            ),
          title: const Text('博美'),
          subtitle: const Text('风度翩翩,待人友好,不挑衅,外貌也特别有魅力。'),
        ),
        const Divider(),
        ListTile(
          title: const Text('雪纳瑞'),
          subtitle: const Text('个性勇敢,不掉毛,聪明独立更适合办公室驯养。'),
          trailing: Image.network(
            'https://gimg2.baidu.com/image_search'
            '/src=http%3A%2F%2Fci.xiaohongshu.com'
            '%2F812208d9-e14f-3491-92e0-d8826d38dd7b'
            '%3FimageView2%2F2%2Fw%2F1080%2Fformat'
            '%2Fjpg&refer=http%3A%2F%2Fci.xiaohongshu.com'
            '&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?'
            'sec=1725003450&t=45b81e18f49c4f12c97530ed14370aa5',
          ),
        ),
        const Divider(),
        ListTile(
          leading: Image.network(
            'https://i1.hdslb.com/bfs/face'
            '/0f93e69c24c049256b7f92472dc65cd0c0a04b37.jpg',
          ),
          title: const Text('柴犬'),
          subtitle: const Text('聪明,对主人看护,身体干净。'),
        ),
        const Divider(),
        ListTile(
          title: const Text('拉布拉多'),
          subtitle: const Text('性格温和,对主人忠心,外貌憨厚,比较容易驯养。'),
          trailing: Image.network(
            'https://img1.baidu.com/it'
            '/u=106284635,2156645854&fm=253'
            '&fmt=auto&app=138&f=JPEG?w=500&h=500',
          ),
        ),
        const Divider(),
        ListTile(
          leading: Image.network(
            'https://www.goupuzi.com/newatt'
            '/Mon_1902/1_180878_2d78897ad7d3bee.jpg',
          ),
          title: const Text('德牧'),
          subtitle: const Text('IQ高,较好训练,忠诚,善于整理头发。'),
        ),
        const Divider(),
        ListTile(
          title: const Text('金毛'),
          subtitle: const Text('待人友好,性情温和,接受指令,适合于工作犬。'),
          trailing: Image.network(
            'https://gimg2.baidu.com/image_search'
            '/src=http%3A%2F%2Fimg3.doubanio.com%2Fview'
            '%2Fnote%2Flarge%2Fpublic%2Fp38828385.jpg'
            '&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002'
            '&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?'
            'sec=1725003882&t=03bcffc445d47b6a8f4797a8ce252f84',
          ),
        ),
        const Divider(),
        ListTile(
          leading: Image.network(
            'https://gss0.baidu.com'
            '/-vo3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item'
            '/b58f8c5494eef01fff50eae7e9fe9925bc317d48.jpg',
          ),
          title: const Text('哈士奇'),
          subtitle: const Text('长得真漂亮,走路表情包,喂食比较少。'),
        ),
        const Divider(),
      ],
    );
  }
}

(2) 图片展示

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('图片展示')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: const EdgeInsets.all(10),
      children: <Widget>[
        Image.network(
          'https://pic.quanjing.com'
          '/x8/tv/QJ6754720830.jpg@%21350h',
        ),
        Container(
          padding: const EdgeInsets.fromLTRB(0, 1, 0, 0),
          height: 30,
          child: const Text(
            '大白斑蝶',
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 20),
          ),
        ),
        Image.network(
          'https://img1.baidu.com'
          '/it/u=2154124395,252693757&fm=253'
          '&fmt=auto&app=138&f=JPEG?w=800&h=1294',
        ),
        Container(
          padding: const EdgeInsets.fromLTRB(0, 1, 0, 0),
          height: 30,
          child: const Text(
            '玉带锦蛇蝶',
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 20),
          ),
        ),
        Image.network(
          'https://img1.baidu.com'
          '/it/u=1832276864,3519016632&fm=253'
          '&fmt=auto&app=138&f=JPEG?w=450&h=600',
        ),
        Container(
          padding: const EdgeInsets.fromLTRB(0, 1, 0, 0),
          height: 30,
          child: const Text(
            '蓝凤蝶',
            textAlign: TextAlign.center,
            style: TextStyle(fontSize: 20),
          ),
        ),
      ],
    );
  }
}

6-2 水平列表

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('水平列表')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      // 与ListView同层可自定义列表高度
      height: 150,
      child: ListView(
        // 水平列表
        scrollDirection: Axis.horizontal,
        padding: const EdgeInsets.all(10),
        children: <Widget>[
          Container(
            // 加horizontal则高度自适应,不加则宽度自适应,设置无效
            height: 150,
            width: 150,
            decoration: const BoxDecoration(color: Colors.lightBlue),
            child: Column(
              children: [
                SizedBox(
                  height: 110,
                  child: Image.network(
                    'https://wx4.sinaimg.cn/large'
                    '/006S7UvTly4gutt43wm3gj611u0o20yy02.jpg',
                    fit: BoxFit.cover,
                  ),
                ),
                const Text('上海'),
              ],
            ),
          ),
          Container(
            width: 150,
            decoration: const BoxDecoration(color: Colors.lightBlue),
            child: Column(
              children: [
                SizedBox(
                  height: 110,
                  child: Image.network(
                    'https://t10.baidu.com'
                    '/it/u=1911060544,216411802&fm=30&app=106'
                    '&f=JPEG?w=640&h=427&s=12A066A1D419EFCE323C08F1030050B2',
                    fit: BoxFit.cover,
                  ),
                ),
                const Text('广州'),
              ],
            ),
          ),
          Container(
            width: 150,
            decoration: const BoxDecoration(color: Colors.lightBlue),
            child: Column(
              children: [
                SizedBox(
                  height: 110,
                  child: Image.network(
                    'https://p4-q.mafengwo.net/s9/M00/97'
                    '/E1/wKgBs1fOHSOAUEwbAAdJRFPuN6s93.jpeg',
                    fit: BoxFit.cover,
                  ),
                ),
                const Text('北京'),
              ],
            ),
          ),
          Container(
            width: 150,
            decoration: const BoxDecoration(color: Colors.lightBlue),
            child: Column(
              children: [
                SizedBox(
                  height: 110,
                  child: Image.network(
                    'https://i0.hdslb.com/bfs/archive'
                    '/58a609e71eef228368bbeb0e7f3ba0e478be1cd6.jpg',
                    fit: BoxFit.cover,
                  ),
                ),
                const Text('重庆'),
              ],
            ),
          ),
          Container(
            width: 150,
            decoration: const BoxDecoration(color: Colors.lightBlue),
            child: Column(
              children: [
                SizedBox(
                  height: 110,
                  child: Image.network(
                    'https://img2.baidu.com/it'
                    '/u=3151136850,293696562&fm=253'
                    '&fmt=auto&app=138&f=JPEG?w=500&h=334',
                    fit: BoxFit.cover,
                  ),
                ),
                const Text('南京'),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

6-3 动态列表

# myflutter(项目名)目录结构如下
- lib/
  - res/
    - mydata.dart
- main.dart
- icon.dart

(1) mydata.dart

List listData = [
  {
    'title': 'Fly Word',
    'author': 'Isla',
    'imageUrl': 'https://wx4.sinaimg.cn/mw690'
      '/0079svP2gy1g43cj47tolj30go0go403.jpg',
  },
  {
    'title': 'Ten Clock',
    'author': 'Olivia',
    'imageUrl': 'https://wx1.sinaimg.cn/mw690'
      '/61bda0ecly1g3pioxcp4sj20go0got9u.jpg',
  },
  {
    'title': 'Candy Shop',
    'author': 'Daniel',
    'imageUrl': 'https://img0.baidu.com/it/u='
      '2325436244,4185116680&fm=253&fmt=auto?w=600&h=600',
  },
  {
    'title': 'Roman Holiday',
    'author': 'Benjamin',
    'imageUrl': 'https://img0.baidu.com/it/u=3366160927,'
      '634583723&fm=253&fmt=auto?w=600&h=600',
  },
  {
    'title': 'Late Autumn Bread',
    'author': 'Samuel',
    'imageUrl': 'https://img1.baidu.com/it/u=3308301908,'
      '3006671182&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
  },
];

(2) 自定义方法

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('自定义方法')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  // 自定义方法
  List<Widget> _initListData() {
    List<Widget> list = [];
    for (var i = 0; i <= 7; i++) {
      list.add(ListTile(title: Text('自定义方法---$i')));
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      // 调用自定义方法
      children: _initListData(),
    );
  }
}

(3) for动态循环

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

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('for动态循环')),
        body: MyApp(),
      ),
    ),
  );
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key) {
    print(listData);
  }

  List<Widget> _initListData() {
    List<Widget> tempList = [];
    for (var i = 0; i < listData.length; i++) {
      tempList.add(
        ListTile(
          leading: Image.network('${listData[i]["imageUrl"]}'),
          title: Text('${listData[i]["title"]}'),
          subtitle: Text('${listData[i]["author"]}'),
        ),
      );
    }
    return tempList;
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _initListData(),
    );
  }
}

(3) map动态循环

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

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('map动态循环')),
        body: MyApp(),
      ),
    ),
  );
}

class MyApp extends StatelessWidget {
  MyApp({Key? key}) : super(key: key) {
    print(listData);
  }

  List<Widget> _initListData() {
    var tempList = listData.map((value) {
      return ListTile(
        leading: Image.network('${value["imageUrl"]}'),
        title: Text('${value["title"]}'),
        subtitle: Text('${value["author"]}'),
      );
    });
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _initListData(),
    );
  }
}

(4) builder动态循环

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

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('builder动态循环')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    // 构造函数
    return ListView.builder(
      itemCount: listData.length,
      itemBuilder: (context, i) {
        return ListTile(
          leading: Image.network(listData[i]['imageUrl']),
          title: Text(listData[i]['title']),
          subtitle: Text(listData[i]['author']),
        );
      },
    );
  }
}

7 网格组件

  • GridView主要的三种方式:GridView.count、GridView.extent、GridView.builder。
  • 常用属性
    • scollDirection(滚动方法)、padding(内边距)、resolve(组件反向排序)。
    • crossAxisCount(一行的组件数量)、maxCrossAxisExtent(横轴子元素的最大长度)。
    • crossAxisSpacing(水平子组件之间间距)、mainAxisSpacing(垂直子组件之间间距)。
    • childAspectRatio(子组件宽高比例)、gridDelegate(控制布局主要用在GridView.builder里)。

7-1 count实现

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('count实现')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      // 一行显示5个图标
      crossAxisCount: 5,
      children: const [
        Icon(Icons.pedal_bike),
        Icon(Icons.home),
        Icon(Icons.ac_unit),
        Icon(Icons.search),
        Icon(Icons.settings),
        Icon(Icons.airport_shuttle),
        Icon(Icons.all_inclusive),
        Icon(Icons.beach_access),
        Icon(Icons.cake),
        Icon(Icons.circle),
      ],
    );
  }
}

7-2 extent实现

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('extent实现')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return GridView.extent(
      // 横轴子元素的最大长度
      maxCrossAxisExtent: 100,
      children: const [
        Icon(Icons.pedal_bike),
        Icon(Icons.home),
        Icon(Icons.ac_unit),
        Icon(Icons.search),
        Icon(Icons.settings),
        Icon(Icons.airport_shuttle),
        Icon(Icons.all_inclusive),
        Icon(Icons.beach_access),
        Icon(Icons.cake),
        Icon(Icons.circle),
      ],
    );
  }
}

7-3 常用属性实例

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('常用属性实例')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  List<Widget> _initGridViewData() {
    List<Widget> tempList = [];
    for (var i = 1; i < 16; i++) {
      tempList.add(
        Container(
          alignment: Alignment.center,
          decoration: const BoxDecoration(
            color: Colors.blue,
          ),
          child: Text(
            '第$i个元素',
            style: const TextStyle(fontSize: 20),
          ),
        ),
      );
    }
    return tempList;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      // 四周间距
      padding: const EdgeInsets.all(2),
      // 配置水平子组件之间的间距
      crossAxisSpacing: 2,
      // 配置垂直子组件之间的间距
      mainAxisSpacing: 2,
      // 一行显示5个图标,count实现
      crossAxisCount: 5,
      // 与extent实现属性相同
      // maxCrossAxisExtent: 100,
      // 宽高比
      childAspectRatio: 0.6,
      children: _initGridViewData(),
    );
  }
}

7-4 count动态列表

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

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('count动态列表')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  List<Widget> _initGridViewData() {
    var tempList = listData.map((value) {
      return Container(
        decoration: BoxDecoration(
          border: Border.all(color: Colors.black26),
        ),
        child: Column(
          children: [
            Image.network(value['imageUrl']),
            const SizedBox(height: 10),
            Text(
              value['title'],
              style: const TextStyle(fontSize: 13),
            ),
          ],
        ),
      );
    });
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      // 四周间距
      padding: const EdgeInsets.all(2),
      // 配置水平子组件之间的间距
      crossAxisSpacing: 2,
      // 配置垂直子组件之间的间距
      mainAxisSpacing: 2,
      // 一行显示3个图标,count实现
      crossAxisCount: 3,
      // 与extent实现属性相同
      // maxCrossAxisExtent: 100,
      // 宽高比
      childAspectRatio: 0.8,
      children: _initGridViewData(),
    );
  }
}

7-5 builder动态列表

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

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('builder动态列表')),
        body: const MyApp(),
      ),
    ),
  );
}

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

  Widget _initGridViewData(context, index) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black26),
      ),
      child: Column(
        children: [
          Image.network(listData[index]['imageUrl']),
          const SizedBox(height: 10),
          Text(
            listData[index]['title'],
            style: const TextStyle(fontSize: 13),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      // 四周间距
      padding: const EdgeInsets.all(2),
      // 传入参数长度
      itemCount: listData.length,

      // 配置水平子组件之间的间距
      // crossAxisSpacing: 2,
      // 配置垂直子组件之间的间距
      // mainAxisSpacing: 2,
      // 一行显示3个图标
      // crossAxisCount: 3,
      // 宽高比
      // childAspectRatio: 0.8,

      // 类似于count与extent实现的区别
      // gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
      //   crossAxisSpacing: 2,
      //   mainAxisSpacing: 2,
      //   crossAxisCount: 3,
      //   childAspectRatio: 0.8,
      // ),

      gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
        crossAxisSpacing: 2,
        mainAxisSpacing: 2,
        maxCrossAxisExtent: 150,
        childAspectRatio: 0.8,
      ),

      itemBuilder: _initGridViewData,
    );
  }
}

文章作者: bsf
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 bsf !
评 论
  目录