「 Flutter」Container、Image 和 ListView 控件

1,278 阅读3分钟

这是我参与11月更文挑战的14天,活动详情查看:2021最后一次更文挑战

Container 控件

Container widget 可以用来创建一个可见的矩形元素。 Container 可以使用 BoxDecoration 来进行装饰,如背景,边框,或阴影等。 Container 还可以设置外边距、内边距和尺寸的约束条件等。另外,Container可以使用矩阵在三维空间进行转换。

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: Text('Hello Flutter'),
        alignment: Alignment.topCenter,
        height: 300.0,
        width: 300.0,
        decoration: BoxDecoration(
          color: Colors.yellow,
          border: Border.all(
            color: Colors.blue,
            width: 2.0,
          ),
        ),
      ),
    );
  }
}

Image 控件

图片控件是显示图像的控件,常用 Image.asset 导入本地图片、Image.network 导入网络图片。

引入网络图片

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300,
        height: 300,
        decoration: BoxDecoration(
          color: Colors.yellow,
        ),
        child: Image.network(
          "https://flutter.cn/static/4ea7d7f5f72649f0bcec.png",
          alignment: Alignment.topLeft,
          // color: Colors.blue,
          // colorBlendMode: BlendMode.luminosity,
          fit: BoxFit.contain,
          repeat: ImageRepeat.repeat,
        ),
      ),
    );
  }
}

实现图片的圆角

  1. 使用 BoxDecoration 实现
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
          width: 300,
          height: 300,
          decoration: BoxDecoration(
            color: Colors.yellow,
            borderRadius: BorderRadius.circular(150),
            image: DecorationImage(
              image: NetworkImage(
                  "https://flutter.cn/static/4ea7d7f5f72649f0bcec.png"),
              fit: BoxFit.contain,
              repeat: ImageRepeat.repeat,
            ),
          )),
    );
  }
}

BB19ED0A483C41B4D0BA138AA1B99908.jpg

  1. 使用 ClipOval 实现
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: ClipOval(
          child: Image.network(
            "https://flutter.cn/static/4ea7d7f5f72649f0bcec.png",
            height: 200,
            width: 200,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

引入本地图片

  1. 新建三个目录

    项目根目录\images\(2.0x/3.0x/4.0x)

  2. 将图片放入images和这三个文件夹中

  3. 配置 pubspec.yaml 文件

    在 flutter 下配置 assets:

flutter:
  uses-material-design: true
  assets:
    - images/1.jpg
    - images/2.0x/1.jpg
    - images/3.0x/1.jpg
  1. 在代码中使用
class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        child: ClipOval(
          child: Image.asset(
            "images/1.jpg",
            height: 200,
            width: 200,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

F867710C812C1D60EF516F4FF348F0BF.jpg

ListView 控件

垂直列表

列表默认为垂直列表:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: EdgeInsets.all(10),
      children: <Widget>[
        // 数组里可以放其他 Widget
        ListTile(
          // 设置前置图标
          leading: Icon(
            Icons.settings,
            // 改变图标样式
            color: Colors.yellow,
            size: 30,
          ),
          title: Text(
            '点亮你的Vue技术栈,万字Nuxt.js实践笔记来了',
            // 设置字体
            style: TextStyle(
              fontSize: 16,
            ),
          ),
          subtitle: Text('作为一位 Vuer(vue开发者),如果还不会这个框架,那么你的 Vue 技术栈还没被点亮'),
          // 设置后置图标
          trailing: Icon(Icons.sentiment_satisfied_sharp),
        ),
        ListTile(
          title: Text('如何用 docker 打造前端开发环境'),
          subtitle: Text('如何使用 docker 打造前端开发环境 docker 的用法很多,除了可以用来部署项目,还可'),
        ),
        ListTile(
          title: Text('如何做前端Code Review'),
          subtitle: Text('向互联网大厂学习,从代码格式、代码错误、代码习惯、代码优化四个角度进行前端Co'),
        ),
      ],
    );
  }
}

24607F48A0966429F7126A1F4092189B.jpg

水平列表

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 240,
      child: ListView(
        // 配置方向,默认为垂直列表
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          Container(
            width: 180,
            color: Colors.yellow,
          ),
          Container(
            width: 180,
            color: Colors.orange,
            // 列表嵌套
            child: ListView(
              children: <Widget>[
                Image.network(
                  "https://flutter.cn/static/4ea7d7f5f72649f0bcec.png",
                ),
                Image.network(
                  "https://flutter.cn/static/4ea7d7f5f72649f0bcec.png",
                ),
              ],
            ),
          ),
          Container(
            width: 180,
            color: Colors.red,
          ),
        ],
      ),
    );
  }
}

动态列表

动态列表可以动态循环数据。

class HomeContent extends StatelessWidget {
  // 自定义私有方法
  List<Widget> _getData() {
    List<Widget> list = [];
    for (var i = 0; i < 20; i++) {
      list.add(ListTile(
        title: Text('this is list $i'),
      ));
    }
    return list;
  }

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

使用外部数据:

// lib/res/listData.dart
List listData = [
  {
    "title": "4 年经验裸辞 2 个月,40 场面试、一路的心态变化及经验总结",
    "author": "天明夜尽",
    "imgUrl":
        "https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/78e7025d384846e9b0314a53a2adab36~tplv-k3u1fbpfcp-zoom-crop-mark:1304:1304:1304:734.awebp?",
  },
  {
    "title": "[万字总结]我还在正确的道路上么?2021年一个前端新人的半年学习工作总结",
    "author": "速冻鱼",
    "imgUrl":
        "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e4a813587ec84152b243c3d54323d01e~tplv-k3u1fbpfcp-zoom-crop-mark:1304:1304:1304:734.awebp?",
  }
];

// lib/main.dart
import 'res/listData.dart';
...
class HomeContent extends StatelessWidget {
  // 自定义私有方法
  List<Widget> _getData() {
    var tempList = listData.map((value) {
      return ListTile(
        leading: Image.network(value["imgUrl"]),
        title: Text(value["title"]),
        subtitle: Text(value["author"]),
      );
    });
    return tempList.toList();
  }

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

使用 ListView.builder:

class HomeContent extends StatelessWidget {
  List<Widget> _getData() {
    var tempList = listData.map((value) {
      return ListTile(
        leading: Image.network(value["imgUrl"]),
        title: Text(value["title"]),
        subtitle: Text(value["author"]),
      );
    });
    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: this._getData().length,
      itemBuilder: (context, index) {
        return this._getData()[index];
      },
    );
  }
}

等价于:

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: listData.length,
      itemBuilder: (context, index) {
        return ListTile(
          leading: Image.network(listData[index]["imgUrl"]),
          title: Text(listData[index]["title"]),
          subtitle: Text(listData[index]["author"]),
        );
      },
    );
  }
}

5FBDACC0767BDCB57E259B0629E00DE0.jpg