Flutter AspectRatio、Card 卡片组件

1,351 阅读6分钟

一、Flutter AspectRatio 组件

  1. AspectRatio 的作用是根据设置调整子元素 child 的宽高比。
  2. AspectRatio 首先会在布局限制条件允许的范围内尽可能的扩展,widget 的高度是由宽 度和比率决定的,类似于 BoxFit 中的 contain,按照固定比率去尽量占满区域。
  3. 如果在满足所有限制条件过后无法找到一个可行的尺寸,AspectRatio 最终将会去优先 适应布局限制条件,而忽略所设置的比率。
属性说明
aspectRatio宽高比,最终可能不会根据这个值去布局, 具体则要看综合因素,外层是否允许按照这 种比率进行布局,这只是一个参考值
child子组件
margin外边距
ShapeCard 的阴影效果,默认的阴影效果为圆角的 长方形边。

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef061871d5494611808361f3b6424182~tplv-k3u1fbpfcp-zoom-1.image

/*
 * @Description: Flutter AspectRatio、Card 卡片组件
 * @Version: 0.1
 * @Autor: wangmiao
 * @Date: 2021-05-31 23:14:53
 * @LastEditors: wangmiao
 * @LastEditTime: 2021-05-31 23:27:20
 */
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: LayoutDemo(),
    ));
  }
}

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      // 宽高比,最终可能不会根据这个值去布局, 具体则要看综合因素,外层是否允许按照这 种比率进行布局,这只是一个参考值
      child: AspectRatio(
        aspectRatio: 2.0 / 1.0,
        child: Container(
          color: Colors.red,
        ),
      ),
    );
  }
}

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dbad5e49a7ba4f20913f071eabfc7c75~tplv-k3u1fbpfcp-zoom-1.image

/*
 * @Description: Flutter AspectRatio、Card 卡片组件
 * @Version: 0.1
 * @Autor: wangmiao
 * @Date: 2021-05-31 23:14:53
 * @LastEditors: wangmiao
 * @LastEditTime: 2021-05-31 23:29:37
 */
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: LayoutDemo(),
    ));
  }
}

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      // 宽高比,最终可能不会根据这个值去布局, 具体则要看综合因素,外层是否允许按照这 种比率进行布局,这只是一个参考值
      child: AspectRatio(
        aspectRatio: 3.0 / 1.0,
        child: Container(
          color: Colors.red,
        ),
      ),
    );
  }
}

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7468a60b66814a14b510d4c024b93a78~tplv-k3u1fbpfcp-zoom-1.image

/*
 * @Description: Flutter AspectRatio、Card 卡片组件
 * @Version: 0.1
 * @Autor: wangmiao
 * @Date: 2021-05-31 23:14:53
 * @LastEditors: wangmiao
 * @LastEditTime: 2021-05-31 23:47:21
 */
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: LayoutDemo(),
    ));
  }
}

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Card(
          margin: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              ListTile(
                title: Text(
                  "甘雨",
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text("高级秘书"),
              ),
              ListTile(
                title: Text("电话:110"),
              ),
              ListTile(
                title: Text("生    日:12月2日"),
              ),
              ListTile(
                title: Text("命之座:仙麟座"),
              ),
              ListTile(
                title: Text("地址:月海亭"),
              )
            ],
          ),
        ),
        Card(
          margin: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              ListTile(
                title: Text(
                  "优菈·劳伦斯",
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text("浪花骑士"),
              ),
              ListTile(
                title: Text("电话:120"),
              ),
              ListTile(
                title: Text("生    日:10月25日"),
              ),
              ListTile(
                title: Text("命之座:浪沫座"),
              ),
              ListTile(
                title: Text("地址:西风骑士团"),
              )
            ],
          ),
        ),
        Card(
          margin: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              ListTile(
                title: Text(
                  "刻晴",
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text("七星之玉衡、变革之星、霆霓快雨"),
              ),
              ListTile(
                title: Text("电话:119"),
              ),
              ListTile(
                title: Text("生    日:11月20日"),
              ),
              ListTile(
                title: Text("命之座:金紫定垂座"),
              ),
              ListTile(
                title: Text("地址:璃月七星之玉衡星"),
              )
            ],
          ),
        )
      ],
    );
  }
}

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0bf92e35c96947f3af395e1c71a49ff8~tplv-k3u1fbpfcp-zoom-1.image

/*
 * @Description: Flutter AspectRatio、Card 卡片组件
 * @Version: 0.1
 * @Autor: wangmiao
 * @Date: 2021-05-31 23:14:53
 * @LastEditors: wangmiao
 * @LastEditTime: 2021-06-01 00:45:06
 */
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: LayoutDemo(),
    ));
  }
}

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Card(
          margin: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              AspectRatio(
                aspectRatio: 16 / 9,
                child: Image.network(
                  "https://oss.wangmiaozero.cn/img/44A95A20-9530-4B0C-9197-73433A27FFCF.png",
                  fit: BoxFit.cover,
                ),
              ),
              ListTile(
                leading: ClipOval(
                  child: Image.network(
                    "https://oss.wangmiaozero.cn/img/44A95A20-9530-4B0C-9197-73433A27FFCF.png",
                    fit: BoxFit.cover,
                    width: 60,
                    height: 60,
                  ),
                ),
              ),
              ListTile(
                title: Text(
                  "甘雨",
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text("高级秘书"),
              ),
              ListTile(
                title: Text("电话:110"),
              ),
              ListTile(
                title: Text("生    日:12月2日"),
              ),
              ListTile(
                title: Text("命之座:仙麟座"),
              ),
              ListTile(
                title: Text("地址:月海亭"),
              )
            ],
          ),
        ),
        Card(
          margin: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              AspectRatio(
                aspectRatio: 20 / 50,
                child: Image.network(
                  "https://oss.wangmiaozero.cn/userPicList/20210530/3c48ebb0-c0a9-11eb-a2fa-996d8e7fcbf2.JPG",
                  fit: BoxFit.cover,
                ),
              ),
              ListTile(
                leading: ClipOval(
                  child: Image.network(
                    "https://oss.wangmiaozero.cn/userPicList/20210530/3c48ebb0-c0a9-11eb-a2fa-996d8e7fcbf2.JPG",
                    fit: BoxFit.cover,
                    width: 60,
                    height: 60,
                  ),
                ),
              ),
              ListTile(
                title: Text(
                  "优菈·劳伦斯",
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text("浪花骑士"),
              ),
              ListTile(
                title: Text("电话:120"),
              ),
              ListTile(
                title: Text("生    日:10月25日"),
              ),
              ListTile(
                title: Text("命之座:浪沫座"),
              ),
              ListTile(
                title: Text("地址:西风骑士团"),
              )
            ],
          ),
        ),
        Card(
          margin: EdgeInsets.all(10),
          child: Column(
            children: <Widget>[
              AspectRatio(
                aspectRatio: 20 / 50,
                child: Image.network(
                  "https://oss.wangmiaozero.cn/img/77453B29-95CF-4B4F-9C57-F3F1FA6A97BE.png",
                  fit: BoxFit.cover,
                ),
              ),
              ListTile(
                leading: ClipOval(
                  child: Image.network(
                    "https://oss.wangmiaozero.cn/img/77453B29-95CF-4B4F-9C57-F3F1FA6A97BE.png",
                    fit: BoxFit.cover,
                    width: 60,
                    height: 60,
                  ),
                ),
              ),
              ListTile(
                title: Text(
                  "刻晴",
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text("七星之玉衡、变革之星、霆霓快雨"),
              ),
              ListTile(
                title: Text("电话:119"),
              ),
              ListTile(
                title: Text("生    日:11月20日"),
              ),
              ListTile(
                title: Text("命之座:金紫定垂座"),
              ),
              ListTile(
                title: Text("地址:璃月七星之玉衡星"),
              )
            ],
          ),
        )
      ],
    );
  }
}

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0e5a03f49b5d418da58ae0fd012144b7~tplv-k3u1fbpfcp-zoom-1.image

data/listData.dart

/*
 * @Description: 
 * @Version: 0.1
 * @Autor: wangmiao
 * @Date: 2021-05-22 23:05:31
 * @LastEditors: wangmiao
 * @LastEditTime: 2021-06-01 00:40:10
 */
List listData = [
  {
    "title": 'Candy Shop',
    "author": 'Mohamed Chahin',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/3eb6ace0-bb02-11eb-a2fa-996d8e7fcbf2.png',
  },
  {
    "title": 'Childhood in a picture',
    "author": 'Google',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/5fa52800-bb02-11eb-a2fa-996d8e7fcbf2.png',
  },
  {
    "title": 'Alibaba Shop',
    "author": 'Alibaba',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/8fd34b10-bb02-11eb-8ed9-85db6b05a7c2.png',
  },
  {
    "title": 'Candy Shop',
    "author": 'Mohamed Chahin',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/b96d9f70-bb02-11eb-a2fa-996d8e7fcbf2.png',
  },
  {
    "title": 'Tornado',
    "author": 'Mohamed Chahin',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/1c79c350-bb03-11eb-8ed9-85db6b05a7c2.png',
  },
  {
    "title": 'Undo',
    "author": 'Mohamed Chahin',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/39116770-bb03-11eb-a2fa-996d8e7fcbf2.png',
  },
  {
    "title": 'white-dragon',
    "author": 'Mohamed Chahin',
    "description":
        'Flutter is Google’s mobile UI framework for crafting high-quality native experiences on iOS and Android in record time. Flutter works with existing',
    "imageUrl":
        'https://oss.wangmiaozero.cn/userPicList/20210522/c34d6f60-bb03-11eb-8ed9-85db6b05a7c2.png',
  }
];

main.dart

/*
 * @Description: Flutter AspectRatio、Card 卡片组件
 * @Version: 0.1
 * @Autor: wangmiao
 * @Date: 2021-05-31 23:14:53
 * @LastEditors: wangmiao
 * @LastEditTime: 2021-06-01 00:42:53
 */
import 'package:flutter/material.dart';
import 'data/listData.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: LayoutDemo(),
    ));
  }
}

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
        children: listData.map((value) {
      return Card(
        margin: EdgeInsets.all(10),
        child: Column(
          children: <Widget>[
            AspectRatio(
              aspectRatio: 20 / 9,
              child: Image.network(
                value["imageUrl"],
                fit: BoxFit.cover,
              ),
            ),
            ListTile(
              leading: CircleAvatar(
                backgroundImage: NetworkImage(value["imageUrl"]),
              ),
              title: Text(value["title"]),
              subtitle: Text(value["description"],
                  maxLines: 1, overflow: TextOverflow.ellipsis),
            ),
          ],
        ),
      );
    }).toList());
  }
}

Vscode 调试 Flutter 项目

1、Vscode 中打开 flutter 项目进行开发 2、运行 Flutter 项目

flutter run

关于命令上的提示,我就简单说明一下:

  • r 键:- 重新载入代码运行 (点击后热加载,也就算是重新加载吧)
  • R 键:- 重新运行(会重新编译)
  • o 键:- 切换 Android / iOS 模式(真机(Android系统)不会显示这条信息,虚拟机的话会显示关于 o 的命令。但是 o 命令对真机(Android系统)依然有效 (切换 android 和 ios 的预览模式)
  • h - 更详细的帮助信息
  • p 键:- 显示网格,这个可以很好的掌握布局情况,工作中很有用。
  • d 键:- 将应用和开发环境分离,设备上可以独立使用。
  • q 键:- 退出,会将设备上的应用一同退出。(退出调试预览模式)
  • flutter build apk (flutter build 默认会包含 --release选项)打包android
  • flutter doctor 运行以下命令查看是否需要安装其它依赖项来完成安装
  • flutter run 运行
  • flutter clean 清理
  • flutter create <project name> 命令可以直接初始化一个项目
  • flutter devices 如果需要连接 真机 or 虚拟机,那么就需要通过 flutter devices 来检查设备信息。

Vscode 默认连不上第三方模拟器解决方案 cd 到对应夜神模拟器D:\Program Files\Nox\bin目录 然后运行

nox_adb.exe connect 127.0.0.1:62001