flutter组件

按钮组件

在这里插入图片描述

//按钮示例
class Buttonpage extends StatelessWidget {
  const Buttonpage({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(children: [
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          ElevatedButton(
              onPressed: () {
                print(1);
              },
              child: Text('普通按钮')),
          TextButton(
              onPressed: () {
                print(1);
              },
              child: Text('文本按钮')),
          OutlinedButton(
            style: ButtonStyle(
              side: WidgetStateProperty.all(
                BorderSide(
                  width: 1,
                  color: Colors.red
                )
              )
            ),
            onPressed: null, 
            child: Text('边框按钮')),
          IconButton(onPressed: null, icon: Icon(Icons.thumb_up))
        ],
      ),
      SizedBox(height: 20),
      Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton.icon(
            onPressed: () {},
            icon: Icon(Icons.send),
            label: Text('发送(图文按钮)'),
          ),
          TextButton.icon(
            onPressed: () {},
            icon: Icon(Icons.info),
            label: Text('消息(图文按钮)'),
          ),
        ],
      ),
      SizedBox(height: 20),
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          OutlinedButton.icon(
            onPressed: () {},
            icon: Icon(Icons.add),
            label: Text('增加(图文按钮)'),
          ),
          ElevatedButton(
            style: ButtonStyle(
              //背景颜色
              backgroundColor: WidgetStateProperty.all(Colors.red[50]),
              //文字颜色
              foregroundColor: WidgetStateProperty.all(Colors.black),
            ),
            onPressed: () {},
            child: Text('样式按钮'),
          ),
        ],
      ),
      SizedBox(height: 20),
      //修改宽高,圆角的按钮
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          SizedBox(
            width: 200,
            height: 60,
            child: ElevatedButton(
              style: ButtonStyle(
                shape: WidgetStateProperty.all(RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20))),
                //背景颜色
                backgroundColor: WidgetStateProperty.all(Colors.red[50]),
                //文字颜色
                foregroundColor: WidgetStateProperty.all(Colors.black),
              ),
              onPressed: () {},
              child: Text('自定义宽高,圆角按钮'),
            ),
          )
        ],
      ),
      SizedBox(height: 20),
      //自适应宽的按钮
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          Expanded(
              flex: 1,
              child: Container(
                margin: EdgeInsets.all(20),
                height: 60,
                child: ElevatedButton(
                  style: ButtonStyle(
                    //背景颜色
                    backgroundColor: WidgetStateProperty.all(Colors.red[50]),
                    //文字颜色
                    foregroundColor: WidgetStateProperty.all(Colors.black),
                  ),
                  onPressed: () {},
                  child: Text('自适应按钮'),
                ),
              ))
        ],
      )
    ]);
  }
}

Center组件
  • 可让子组件居中
Align组件
  • 可以调整子组件的位置
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.topLeft,
      child: new Text(
        "你好 flutter3",
        textDirection: TextDirection.ltr,
        style: TextStyle(
            color: Colors.red, fontSize: 30.0, fontWeight: FontWeight.w800),
      ),
    );
  }
}

在这里插入图片描述

Container容器组件
  • Container是flutter很常用的组件,类似html的div
  • 它可以设置width,height,padding,margin,border
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 这个是生成组件的快捷
    在这里插入图片描述
class MyContainer extends StatelessWidget {
  const MyContainer({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 250,
      height: 250,
      // 内容位置
      // alignment: Alignment.center,
      padding: EdgeInsets.all(24),
      // 仅仅配置几边
      margin: EdgeInsets.only(left: 30, top: 20),

      decoration: BoxDecoration(
          color: Colors.blue,
          // 圆角
          borderRadius: BorderRadius.circular(20),
          // 边框
          border: Border.all(color: Colors.black, width: 2),
          // 阴影
          boxShadow: [BoxShadow(color: Colors.black45, blurRadius: 20)]),
      child: Text(
        "你好 flutter子组件",
        textDirection: TextDirection.ltr,
        style: TextStyle(
            color: Colors.red, fontSize: 20.0, fontWeight: FontWeight.w800),
      ),
    );
  }
}

在这里插入图片描述

Text组件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Row水平布局组件

在这里插入图片描述

  • 宽高等于屏幕的高度
  • width:double.infinity
  • height:double.infinity
class MyRow extends StatelessWidget {
  const MyRow({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 500,
      height: 700,
      color: Colors.black12,
      child: Row(
        //水平布局位置
        mainAxisAlignment:MainAxisAlignment.spaceBetween,
        children: [
          Container(
            width: 100,
            height: 100,
            color: Colors.red,
            child: Icon(
              Icons.home,
              color: Colors.white,
              size: 40,
            ),
          ),
          Container(
            width: 100,
            height: 100,
            color: const Color.fromARGB(255, 89, 49, 129),
            child: Icon(
              Icons.search,
              color: Colors.white,
              size: 40,
            ),
          ),
          Container(
            width: 100,
            height: 100,
            color: const Color.fromARGB(255, 89, 196, 178),
            child: Icon(
              Icons.send,
              color: Colors.white,           
            ),
          )
        ],
      ),
    );
  }
}
Column垂直布局组件
  • 属性和Row属性基本一致
class MyColumn extends StatelessWidget {
  const MyColumn({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 500,
      height: 700,
      color: Colors.black12,
      child: Column(
        // 水平布局位置
        mainAxisAlignment:MainAxisAlignment.spaceBetween,
        // 次轴布局
        crossAxisAlignment:CrossAxisAlignment.center,
        children: [
          Container(
            width: 100,
            height: 100,
            color: Colors.red,
            child: Icon(
              Icons.home,
              color: Colors.white,
              size: 40,
            ),
          ),
          Container(
            width: 100,
            height: 100,
            color: const Color.fromARGB(255, 89, 49, 129),
            child: Icon(
              Icons.search,
              color: Colors.white,
              size: 40,
            ),
          ),
          Container(
            width: 100,
            height: 100,
            color: const Color.fromARGB(255, 89, 196, 178),
            child: Icon(
              Icons.send,
              color: Colors.white,           
            ),
          )
        ],
      ),
    );
  }
}

在这里插入图片描述

ListView可滚动的列表组件
  • 导入字体图标后需执行flutter pub get,确保字体文件被正确引入到项目
  • 如何导入图标
  • 将.ttf文件放入项目中
  • pubspec.yaml文件中处理一下
  fonts:
  - family: jiqiren
    fonts:
      - asset: assets/jiqiren.ttf
  • 新建myIconsFont.dart文件
import 'package:flutter/material.dart';

class MyIcons{
  static const IconData jiqiren =IconData(
    0xe60c,
    fontFamily: 'MyIcons',
    matchTextDirection: true
  );
}

class MyListView extends StatelessWidget {
  const MyListView({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 500,
      height: 700,
      color: Colors.black12,
      child: ListView(
        children: [
          ListTile(
            leading: Icon(MyIcons.jiqiren,color:Colors.blue),
            title: Text("我的"),
          ),
          Divider(),
          ListTile(
            title: Text("机器右边箭头图标"),
            trailing: Icon(Icons.chevron_right_sharp),
          ),
          Divider(),
        ],
      ),
    );
  }
}

padding组件
  • 作用就是给 child内容加padding值
  • 比Container组件占用内存更小
  • 属性:
  • padding
  • child
// padding组件
// 方式1,不用padding组件
class pagePadding extends StatelessWidget {
  const pagePadding({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(32),
      child: const Text("你好flutter"),
    );
  }
}
class pagePadding2 extends StatelessWidget {
  const pagePadding2({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(32),
      child: const Text("你好flutter"),
    );
  }
}
GridView网格布局组件

在这里插入图片描述

三种实现方式
  • GridView.count实现网格布局
  • GridView.exent实现网格布局
  • GridView.builder实现动态网格布局

在这里插入图片描述

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "万物互联",
      theme: ThemeData(
        primaryColor: Colors.blue,
      ),
      home:
          Scaffold(appBar: AppBar(title: const Text('网格系统')), body: twoPage()),
    );
  }
}

// 方式1 GridView.count
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    // crossAxisCount主轴数量
    return GridView.count(crossAxisCount: 3, children: [
      Icon(Icons.pedal_bike),
      Icon(Icons.pedal_bike),
      Icon(Icons.pedal_bike),
      Icon(Icons.pedal_bike),
      Icon(Icons.pedal_bike),
      Icon(Icons.pedal_bike),
      Icon(Icons.pedal_bike)
    ]);
  }
}

// 方式2 GridView.extent
class twoPage extends StatelessWidget {
  const twoPage({super.key});

  @override
  Widget build(BuildContext context) {
    // maxCrossAxisExtent,横轴每个子元素最大长度
    return GridView.extent(
        maxCrossAxisExtent: 140,
        crossAxisSpacing: 20, //水平widget之间间距
        mainAxisSpacing: 20, //垂直widget之间间距
        padding: EdgeInsets.all(10),
        childAspectRatio: 0.8, //宽高比例
        children: [
          Icon(Icons.pedal_bike),
          Icon(Icons.pedal_bike),
          Icon(Icons.pedal_bike),
          Icon(Icons.pedal_bike),
          Icon(Icons.pedal_bike),
          Icon(Icons.pedal_bike),
          Icon(Icons.pedal_bike)
        ]);
  }
}
// 方式3 GridView.builder
class threePage extends StatelessWidget {
  const threePage({super.key});
  static const listData = [
    {"title": "one", "img": "http://tian-ji.sunyay.cn:9999/uploads/82.png"},
    {"title": "two", "img": "http://tian-ji.sunyay.cn:9999/uploads/82.png"},
    {"title": "three", "img": "http://tian-ji.sunyay.cn:9999/uploads/82.png"}
  ];
  Widget _initThreeList(context, index) {
    //循环数组2
    return Container(
        alignment: Alignment.center,
        decoration: BoxDecoration(
            color: const Color.fromARGB(255, 44, 145, 133),
            border: Border.all(color: Colors.black12)),
        child: Column(
          children: [
            Image.network(listData[index]["img"]!),
            const SizedBox(height: 10),
            Text(
              listData[index]["title"]!,
              style: TextStyle(fontSize: 18),
            )
          ],
        ));
  }

  @override
  Widget build(BuildContext context) {
    // SliverGridDelegateWithFixedCrossAxisCount,相当于GridView.count
    return GridView.builder(
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisSpacing: 20,
          mainAxisSpacing: 20,
          crossAxisCount: 2,//必传
          childAspectRatio: 0.8, //宽高比例
        ),
        itemCount: listData.length,//必传
        itemBuilder: _initThreeList);
  }
}
// 方式3 GridView.builder
class fourPage extends StatelessWidget {
  const fourPage({super.key});
  static const listData = [
    {"title": "one", "img": "http://tian-ji.sunyay.cn:9999/uploads/82.png"},
    {"title": "two", "img": "http://tian-ji.sunyay.cn:9999/uploads/82.png"},
    {"title": "three", "img": "http://tian-ji.sunyay.cn:9999/uploads/82.png"}
  ];
  Widget _initThreeList(context, index) {
    //循环数组2
    return Container(
        alignment: Alignment.center,
        decoration: BoxDecoration(
            color: const Color.fromARGB(255, 44, 145, 133),
            border: Border.all(color: Colors.black12)),
        child: Column(
          children: [
            Image.network(listData[index]["img"]!),
            const SizedBox(height: 10),
            Text(
              listData[index]["title"]!,
              style: TextStyle(fontSize: 18),
            )
          ],
        ));
  }

  @override
  Widget build(BuildContext context) {
    // SliverGridDelegateWithMaxCrossAxisExtent,相当于GridView.extent
    return GridView.builder(
        gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
          crossAxisSpacing: 20,
          mainAxisSpacing: 20,
          maxCrossAxisExtent: 120,//必传
          childAspectRatio: 0.8, //宽高比例
        ),
        itemCount: listData.length,
        itemBuilder: _initThreeList);
  }
}

在这里插入图片描述

动态渲染示例1
// 示例
class allPage extends StatelessWidget {
  const allPage({super.key});
  // 循环数组1
  List<Widget> _initList() {
    List<Widget> tempList = [];
    for (var i = 0; i < 12; i++) {
      tempList.add(Container(
        alignment: Alignment.center,
        decoration: BoxDecoration(color: Colors.blue),
        child: Text(
          "${i}元素",
          style: TextStyle(fontSize: 20),
        ),
      ));
    }
    return tempList;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
        crossAxisCount: 3,
        crossAxisSpacing: 20, //水平widget之间间距
        mainAxisSpacing: 20, //垂直widget之间间距
        padding: EdgeInsets.all(10),
        childAspectRatio: 0.6, //宽高比例
        children: _initList());
  }
}

在这里插入图片描述

动态渲染示例2
// 示例
class allPage extends StatelessWidget {
  const allPage({super.key});
  //数组2
  List<Widget> _initGridList() {
    List listData = [
      {"title": "one", "img": "http://tian-ji.xxxx.cn:9999/uploads/82.png"},
      {"title": "two", "img": "http://tian-ji.xxxx.cn:9999/uploads/82.png"},
      {"title": "three", "img": "http://tian-ji.xxxx.cn:9999/uploads/82.png"}
    ];
    //循环数组2
    var tempList2 = listData.map((value) {
      return Container(
          alignment: Alignment.center,
          decoration: BoxDecoration(
              color: const Color.fromARGB(255, 44, 145, 133), border: Border.all(color: Colors.black12)),
          child: Column(
            children: [
              Image.network(value["img"]),
              const SizedBox(height: 10),
              Text(
                value["title"],
                style: TextStyle(fontSize: 18),
              )
            ],
          ));
    });
    // tempList2返回的类似(1,2,4)
    return tempList2.toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
        crossAxisCount: 3,
        crossAxisSpacing: 20, //水平widget之间间距
        mainAxisSpacing: 20, //垂直widget之间间距
        padding: EdgeInsets.all(10),
        childAspectRatio: 0.6, //宽高比例
        children: _initGridList());
  }
}

在这里插入图片描述

弹性布局(Flex Expanded)
  • flex组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用row或column会方便
  • row和column都继承flex,参数基本相同
    在这里插入图片描述
class Flexpage extends StatelessWidget {
  const Flexpage({super.key});

  @override
  Widget build(BuildContext context) {
    return Flex(
        // 水平还是垂直
        direction: Axis.horizontal,
        // Expanded 主要用于在 Row、Column 或 Flex 等布局组件中按比例分配剩余空间
        children: [
          Expanded(flex: 1, child: Icon(Icons.pedal_bike)),
          Expanded(flex: 2, child: Icon(Icons.pedal_bike))
        ]);
  }
}
// 示例
class Flexallpage extends StatelessWidget {
  const Flexallpage({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Container(
          width: double.infinity,
          height: 200,
          color: Colors.black,
        ),
        const SizedBox(height: 5),
        Row(
          children: [
            Expanded(
                flex: 2,
                child: Container(
                  height: 180,
                  color: Colors.amber,
                  child: Image.network(
                    'http://tian-ji.sunyay.cn:9999/uploads/82.png',
                    fit: BoxFit.cover,
                  ),
                )),
            Expanded(
                flex: 1,
                child: Container(
                  height: 180,
                  color: Colors.red[200],
                  child: Column(
                    children: [
                      Expanded(
                          flex: 1,
                          child: SizedBox(
                            width: double.infinity,
                            child: Image.network(
                              'http://tian-ji.xxxx.cn:9999/uploads/my.png',
                              fit: BoxFit.cover,
                            ),
                          )),
                      const SizedBox(height: 5),
                      Expanded(
                          flex: 1,
                          child: Image.network(
                            'http://tian-ji.xxxx.cn:9999/uploads/my.png',
                            fit: BoxFit.cover,
                          )),
                    ],
                  ),
                ))
          ],
        )
      ],
    );
  }
}

Stack层叠组件,Stack和Positioned定位布局
  • 获取宽高的另一种方法
// 获取设备的宽高
final size = MediaQuery.of(context).size;

在这里插入图片描述
在这里插入图片描述

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "万物互联",
      theme: ThemeData(
        primaryColor: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(title: const Text('网格系统')), body: Stackallpage()),
    );
  }
}

//stack层叠布局
class Stackpage extends StatelessWidget {
  const Stackpage({super.key});

  @override
  Widget build(BuildContext context) {
    // alignment是相当于外层的层叠位置
    return Stack(
      alignment: Alignment.center,
      children: [
        Container(
          height: 200,
          width: 200,
          color: Colors.red,
        ),
        Container(
          height: 100,
          width: 100,
          color: Colors.yellow,
        ),
        Text('乞力马扎罗'),
      ],
    );
  }
}

class Stackallpage extends StatelessWidget {
  const Stackallpage({super.key});

  @override
  Widget build(BuildContext context) {
    // 获取设备的宽高
    final size = MediaQuery.of(context).size;
    // alignment是相当于外层的层叠位置
    return Container(
        height: double.infinity,
        width: double.infinity,
        color: Colors.red,
        child: Stack(
          children: [
            ListView(
              //上边距
              padding: const EdgeInsets.only(top: 50),
              children: [
                ListTile(title: Text('数据列表0')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
                ListTile(title: Text('数据列表1')),
              ],
            ),
            Row(children: [
              Expanded(
                  flex: 1,
                  child: Container(
                    alignment: Alignment.center,
                    height: 44,
                    color: Colors.amber[100],
                    child: Text('tab1'),
                  )),
              Expanded(
                  flex: 1,
                  child: Container(
                    alignment: Alignment.center,
                    height: 44,
                    color: Colors.amber[100],
                    child: Text('tab2'),
                  ))
            ]),
            // Positioned定位必须要有宽高
            Positioned(
              left: 0,
              bottom: 0,
              width: size.width,
              height: 80,
              // height: size.height,
              child: Container(
                height: 100,
                width: 100,
                color: Colors.yellow,
              ),
            ),
          ],
        ));
  }
}

Stack与Align组合
  • Align组件可以调整子组件的位置
  • Stack组件中结合Align组件可以控制每个子元素的显示位置
    在这里插入图片描述
class StackAlignAllpage extends StatelessWidget {
  const StackAlignAllpage({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
        //不生效
        // children: [
        //   Align(
        //     alignment: Alignment.topLeft,
        //     child: Text("订单管理"),
        //   ),
        //   Align(
        //     alignment: Alignment.topLeft,
        //     child: Text("个人首页"),
        //   )
        // ],
        //生效
        children: [
          Container(
            width: double.infinity,
            height: 40,
            child: Stack(
              children: [
                Align(
                  alignment: Alignment.topLeft,
                  child: Text("订单管理"),
                ),
                Align(
                  alignment: Alignment.topRight,
                  child: Text("个人首页"),
                )
              ],
            ),
          ),
          SizedBox(
            width: double.infinity,
            height: 40,
            child: Stack(
              children: [
                Align(
                  alignment: Alignment.topLeft,
                  child: Text("订单管理"),
                ),
                Align(
                  alignment: Alignment.topRight,
                  child: Text("个人首页"),
                )
              ],
            ),
          ),
          SizedBox(
            //SizedBox作为容器给Positioned指定宽高
            width: double.infinity,
            height: 40,
            child: Stack(
              children: [
                Positioned(
                  left: 10,
                  child: Text("订单管理"),
                ),
                Positioned(
                  right: 10,
                  child: Text("个人首页"),
                )
              ],
            ),
          ),
        ]);
  }
}

AspectRatio组件 Card CircleAvatar组件
  • AspectRatio的作用是调整子元素child的宽高比
//AspectRatio调整子元素宽高比
class AspectRatiopage extends StatelessWidget {
  const AspectRatiopage({super.key});

  @override
  Widget build(BuildContext context) {
    //设置宽高比2:1
    return AspectRatio(
      aspectRatio: 2 / 1,
      child: Container(
        color: Colors.red[100],
      ),
    );
  }
}
Card 组件
  • 卡片组件块,具有圆角和阴影
    在这里插入图片描述
    在这里插入图片描述
// 卡片组件
class Cardpage extends StatelessWidget {
  const Cardpage({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Card(
          //阴影
          elevation: 10,
          //颜色
          color: Colors.amber[100],
          //边距
          margin: EdgeInsets.all(24),
          //圆角
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
          child: Column(
            children: [
              ListTile(
                title: Text(
                  '一级标题',
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text('二级标题'),
              ),
              Divider(),
              ListTile(
                title: Text(
                  '一级标题',
                  style: TextStyle(fontSize: 28),
                ),
                subtitle: Text('二级标题'),
              ),
            ],
          ),
        )
      ],
    );
  }
}

//卡片示例
class CardAllpage extends StatelessWidget {
  const CardAllpage({super.key});

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
          ),
          margin: EdgeInsets.all(24),
          child: Column(
            children: [
              AspectRatio(
                  aspectRatio: 16 / 9,
                  child: Image.network(
                      'http://tian-ji.sunyay.cn:9999/uploads/my.png',
                      fit: BoxFit.cover)),
              ListTile(
                leading: ClipOval(
                  child: Image.network(
                    'http://tian-ji.sunyay.cn:9999/uploads/my.png',
                    fit: BoxFit.cover,
                    width: 40,
                    height: 40,
                  ),
                ),
                title: Text('一级标题'),
                subtitle: Text('副标题'),
              )
            ],
          ),
        ),
        Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(12),
          ),
          margin: EdgeInsets.all(24),
          child: Column(
            children: [
              AspectRatio(
                  aspectRatio: 16 / 9,
                  child: Image.network(
                      'http://tian-ji.sunyay.cn:9999/uploads/my.png',
                      fit: BoxFit.cover)),
              ListTile(
                leading: CircleAvatar(
                    radius: 20,
                    backgroundImage: NetworkImage(
                        ('http://tian-ji.sunyay.cn:9999/uploads/my.png'))),
                title: Text('一级标题'),
                subtitle: Text('副标题'),
              )
            ],
          ),
        )
      ],
    );
  }
}

圆形头像组件
  • 方式1
              ListTile(
                leading: ClipOval(
                  child: Image.network(
                    'http://tian-ji.sunyay.cn:9999/uploads/my.png',
                    fit: BoxFit.cover,
                    width: 40,
                    height: 40,
                  ),
                ),
                title: Text('一级标题'),
                subtitle: Text('副标题'),
              )
  • 方式2
  • CircleAvatar不提供边框的属性
  • 如果非要实现边框,可以将其包裹在更大的CircleAvatar中
  ListTile(
                leading: CircleAvatar(
                    radius: 20,
                    backgroundImage: NetworkImage(
                        ('http://tian-ji.sunyay.cn:9999/uploads/my.png'))),
                title: Text('一级标题'),
                subtitle: Text('副标题'),
              )
Wrap布局组件
  • Wrap可以实现流布局,单行的Wrap和Row一样,单列的wrap和colum一样
  • 但Row和colum是单行单列的
  • Wrap突破了这个限制,mainAxis上空间不足的时候,则向crossAxis上扩展显示
    在这里插入图片描述
    在这里插入图片描述
//布局组件
class Button extends StatelessWidget {
  String text; //按钮文字
  void Function()? onPressed; //按钮方法
  Button(this.text, {super.key, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      child: Text(text),
      style: ButtonStyle(
        backgroundColor:
            WidgetStateProperty.all(Color.fromARGB(244, 255, 244, 244)),
        foregroundColor: WidgetStateProperty.all(Colors.black45),
      ),
    );
  }
}

class WrapPage extends StatelessWidget {
  const WrapPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: EdgeInsets.all(20),
        child: ListView(
          children: [
            Row(
              children: [
                Text('热搜', style: Theme.of(context).textTheme.titleLarge)
              ],
            ),
            const Divider(),
            Wrap(
              alignment: WrapAlignment.start,
              spacing: 10, //主轴间距
              runSpacing: 10, //垂直间距
              // direction: Axis.vertical,
              children: [
                Button(
                  '第1集',
                  onPressed: () {
                    print('Button Clicked');
                  },
                ),
                Button(
                  '第2集',
                  onPressed: () {
                    print('Button Clicked');
                  },
                ),
                Button(
                  '第3集',
                  onPressed: () {
                    print('Button Clicked');
                  },
                ),
                Button(
                  '第4集',
                  onPressed: () {
                    print('Button Clicked');
                  },
                ),
                Button(
                  '第5集',
                  onPressed: () {
                    print('Button Clicked');
                  },
                ),
                Button(
                  '第6集',
                  onPressed: () {
                    print('Button Clicked');
                  },
                ),
              ],
            ),
            SizedBox(
              height: 10,
            ),
            Row(
              children: [
                Text('历史记录', style: Theme.of(context).textTheme.titleLarge)
              ],
            ),
            Column(
              children: [
                ListTile(title: const Text("搜索记录1")),
                Divider(),
                ListTile(title: const Text("搜索记录2")),
              ],
            ),
            SizedBox(
              height: 40,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                OutlinedButton.icon(
                    style: ButtonStyle(
                      foregroundColor: WidgetStateProperty.all(Colors.black45)
                    ),
                    onPressed: () {},
                    icon: Icon(Icons.delete),
                    label: Text('删除所有的历史记录')),
              ],
            )
          ],
        ));
  }
}
flutter动画详解
  • photo_view预览动画
  • 使图像能够通过用户手势(例如捏合,旋转,和拖动)进行缩放和平移
  • 第三方插件地址:https:pub.dev/packages/photo_view

步骤1,pubspec.yaml文件导入

  • dev_dependencies下 photo_view: ^0.15.0
    在这里插入图片描述
单张图片查看
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';

class HeroImage extends StatefulWidget {
  final Map arguments;
  const HeroImage({super.key, required this.arguments});

  @override
  State<HeroImage> createState() => _HeroImageState();
}

//单张图片预览
class _HeroImageState extends State<HeroImage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // InkWell增加点击事件,点击空白出关闭预览图片
        body: InkWell(
      onTap: () {
        Navigator.pop(context);
      },
      child: Hero(
          tag: widget.arguments['picurl'],
          child: PhotoView(
            imageProvider: NetworkImage(widget.arguments['picurl']),
          )),
    ));
  }
}

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐