Flutter

Flutter

入口方法

入口文件:flutter项目的lib目录里面都有一个main.dart这个文件就是flutter的入口文件

入口方法:

void main() {
  runApp(MyApp());
}
//简写如下
void main()=>runApp(MyApp());
//其中main方法是dart的入口方法。runApp方法是flutter的入口方法。MyApp是自定义的一个组件。

Container容器组件

allgnment:topCenter:顶部居中对齐 topleft:顶部左对齐 topRight:顶部右对齐 center: 水平垂直居中对齐 centerLeft:垂直居中水平居左对齐centerRight: 垂直居中水平居右对齐 bottomCenter底部居中对齐bottomLeft:底部居左对齐

bottomRight:底部居右对齐

margin:margin属性是表示Container与外部其他组件的距离

padding:padding就是Container的内边距,指Container边缘与Child之间的距离

transform:让Container容易进行一些旋转之类的transform

height:容器高度

width:容器宽度

child:容器子元素

Container组件是作为Center组件的child使用的,我们用它的decoration属性来修饰它,修饰的值是一个BoxDecoration(color: Colors.red)。

设置一下这个BoxDecoration

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(title:const Text("你好Flutter")),
      body: const MyApp(),
    ),
  ));
}

//代码块 statelessW
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        alignment: Alignment.bottomCenter, //配置Container容器内元素的方位
        width: 100,
        height: 100,
        //transform: Matrix4.translationValues(10, 0, 0),//位移
        transform: Matrix4.rotationZ(0.2),//旋转
        decoration: BoxDecoration(
            color: Colors.yellow,      //背景颜色
            border: Border.all(   //边框
                color:Colors.red,
                width:2
            ),
            borderRadius: BorderRadius.circular(10),//配置圆角
            boxShadow: const[    //配置阴影效果
              BoxShadow(
                  color: Colors.black,
                  blurRadius: 10.0
              )
            ],
            //LinearGradient 背景线性渐变 RadialGradient径向渐变
            gradient: const LinearGradient(
                colors: [
                  Colors.red,Colors.yellow
                ]
            )
        ),
        child:const Text("你好Flutter",style:TextStyle(
            color: Colors.white
        ),),
      ),
    );
  }
}

color-填充颜色
border-边界线
borderRadius-边界线弧度,设置圆角
boxShadow-设置阴影
gradient-设置渐变

使用container创建一个按钮 👇

import 'package:flutter/material.dart';
void main() {
  runApp(
      MaterialApp(
          home: Scaffold(
              appBar: AppBar(title:const Text("你好Flutter")),
              body: Column(
                children: [
                  MyButton()
                ],
              )
          ))
  );
}
class MyButton extends StatelessWidget {
  const MyButton({super.key});

  
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      width: 200,
      height: 40,
      //margin: const EdgeInsets.all(10),  //四周margin
      margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
      padding: const EdgeInsets.all(4), //与里面元素间距
      decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(10)
      ),
      child: const Text("按钮",style: TextStyle(
          color: Colors.white,
          fontSize:20
      )),
    );
  }
}
class MyButton extends StatelessWidget {
  const MyButton({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        width: 200,
        height: 40,
        margin: const EdgeInsets.fromLTRB(0, 20, 0, 0),
        decoration: BoxDecoration(
            color: Colors.blue, borderRadius: BorderRadius.circular(10)),
        child: Text(
          "按钮",
          style: TextStyle(color: Colors.white, fontSize: 20),
        ));
  }
}

Text组件

import 'package:flutter/material.dart';
void main() {
  runApp(
      MaterialApp(
          home: Scaffold(
              appBar: AppBar(title:const Text("你好Flutter")),
              body: const Column(
                children: [
                  MyText()
                ],
              )
          ))
  );
}
class MyText extends StatelessWidget {
  const MyText({super.key});

  
  Widget build(BuildContext context) {
    return Container(
        width: 200,
        height: 200,
        margin:const EdgeInsets.fromLTRB(0, 40, 0, 0),
        decoration: const BoxDecoration(
            color:Colors.yellow
        ),
        child: const Text("你好我是Flutter你好我是Flutter你好我是Flutter",
          textAlign: TextAlign.left,
          overflow: TextOverflow.ellipsis,   //溢出显示几个点
          maxLines: 1,      //一行
          style: TextStyle(
              fontSize: 20,   //字体
              fontWeight: FontWeight.w900,//加粗
              color: Colors.red,
              fontStyle: FontStyle.italic,  //倾斜
              letterSpacing: 2,   //字间距
              decoration: TextDecoration.underline,  //字下划线
              decorationColor: Colors.black,   //下划线颜色
              decorationStyle: TextDecorationStyle.dashed  //虚线
          ),//TextStyle
        )//Text
    );//Container
  }
}

Tex组件的几个的属性
style-设置字体样式
fontSize-字号,就是设置字体大小的
fontWeight-自重,就是设置字体粗细的
fontStyle-样式,有normal和italic,就是直体和斜体的区别
letterSpacing-字符的间距
decoration: TextDecoration.underline-设置下划线
decorationStyle: TextDecorationStyle.dashed-设置下划线为虚线
decorationColor: Colors.blue-设置下划线颜色
textAlign-对齐方式
maxline-最大行数
overflow: TextOverflow.ellipsis - 溢出、显示省略号

图片组件

1.图片组件介绍

通过Image组件来加载并显示图片Image的数据源可以是asset,文件,内存以及网络。

Image.asset,本地图片

Image.network,远程图片

Image组件属性描述

属性名类型说明
imageImageProviderImage显示区域的宽度和高度设置
width/hei ghtdoubleImage显示区域的宽度和高度设置
fitBoxfit图片填充模式
colorColor图片颜色
colorBlendModeBlendMode在对图片进行手动处理的时候,可能会用到图片混合如改变图片的颜色。此属性可以对颜色进行混合处理。
alignmentAlignment控制图片的摆放位置
repeatImageRepeat设置图片重复模式
centerSliceRect当图片需要被拉伸时使用
matchTextDirectionbooI该属性与Directionlity配合使用
gaplessPlaybackbool当ImageProvide发生变化后,重新加载图片的过程中,原图片的展示是否保留

BoxFit取值描述

取值描述
Boxfit.fill全图显示,显示可能拉伸,充满
Boxfit.contain全图显示,显示原比例,不需充满
Boxfit. cover显示可能拉伸,可能裁剪,充满
BoxFit.fitWidth显示可能拉伸,可能裁剪,宽度充满
BoxFit.fitHeight显示可能拉伸,可能裁剪,高度充满
Boxfit.none原始大小
BoxFit.scaleDown效果和BoxFit.contain差不多,但是此属性不允许显示超过源图片大小,即可小不可大

2.加载远程图片

Image.network(src)

import 'package:flutter/material.dart';
void main() {
  runApp(
      MaterialApp(
          home: Scaffold(
              appBar: AppBar(title:const Text("你好Flutter")),
              body: const MyAPP()
       ) ),
  );
}
class MyAPP extends StatelessWidget {
  const MyAPP({super.key});

  
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300,
        height: 300,
        decoration: const BoxDecoration(
          color: Colors.green,
        ),
        child:Image.network("https://www.itying.com/themes/itying/images/ionic4.png",
          fit: BoxFit.contain,)
        ),
      );
  }
}

3.Container实现圆角图片

//3.Container实现圆角图片
import 'package:flutter/material.dart';
void main() {
  runApp(
      MaterialApp(
          home: Scaffold(
              appBar: AppBar(title:const Text("你好Flutter")),
              body: Column(
                children:const[
                    MyApp(),
                    SizedBox(height:20,),
                    Circular()
                ],
              )
       ) ,
  ));
}
class MyAPP extends StatelessWidget {
  const MyAPP({super.key});

  
  Widget build(BuildContext context) {
    return Center(
      child: Container(
          margin:EdgeInsets.fromLTRB(0,40,0,0),
          width: 300,
          height: 300,
          decoration: const BoxDecoration(
          color: Colors.green,
        ),
        child:Image.network("https://www.itying.com/themes/itying/images/ionic4.png",
          fit: BoxFit.contain,)
        ),
      );
  }
}
//实现一个圆形图片
class Circular extends StatelessWidget {
  const Circular({super.key});

  
  Widget build(BuildContext context) {
    return Container(
          width: 300,
          height: 300,
          decoration: const BoxDecoration(
              color: Colors.green,
              borderRadius:BorderRadius.circular(75),//圆角
              image:DecorationImage(
                image:NetworkImage("https://www.itying.com/themes/itying/images/ionic4.png",
                                   fit:BoxFit.cover
        )
        ),
      );
  }
}

4.CliOval实现圆角图片

5.本地图片

创建Images文件夹,配置文件修改

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

  
  Widget build(BuildContext context) {
    return Container(
        width: 300,
        height: 300,
        decoration: const BoxDecoration(
              color: Colors.green,
            ),
        child:Image.asset("images/a.jpeg",fit:BoxFit.cover), 
      );
  }
}

自定义图标

ICON定义

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text("Flutter ICON")),
        body: const MyHomePage(),
      ),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    return const Column(
      children: [
        SizedBox(height: 20,),
        Icon(
          Icons.home,
          size: 40,
          color: Colors.red,),
        SizedBox(height: 20,),
        Icon(
          Icons.settings
          ),
        SizedBox(height: 20,),
        Icon(
          Icons.search),
        SizedBox(height: 20,),
        Icon(
          Icons.personal_injury_outlined
          ),

      ],
    );
  }
}

!(C:\Users\86180\Pictures\Screenshots\屏幕截图 2023-08-06 184241.png)

页面布局

padding组件:

上下左右都有间距

import 'package:flutter/material.dart';

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

//代码块 statelessW
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text("Flutter App")),
        body: const HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return const IconContainer();
  }
}
//自定义IconContainer
class IconContainer extends StatelessWidget {
  const IconContainer({super.key});

  
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      height: 120,
      width: 120,
      color: Colors.red,
      child: const Icon(Icons.home,color:Colors.white,size: 28,),
    );
  }
}
import 'package:flutter/material.dart';

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

//代码块 statelessW
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text("Flutter App")),
        body: const HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return  IconContainer(Icons.home,);
  }
}
//自定义IconContainer
// ignore: must_be_immutable
class IconContainer extends StatelessWidget {
  Color color;
   IconData icon;
   IconContainer(this.icon,{Key?key,this.color=Colors.red}) : super(key: key);
  
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      height: 120,
      width: 120,
      color: color,
      child:  Icon(icon,color:Colors.white,size: 28,),
    );
  }
}
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return  Row(
      children: [
        IconContainer(Icons.home),
        IconContainer(Icons.search,color:Colors.yellow ,),
        IconContainer(Icons.abc_outlined,color: Colors.orange,),
      ],
    );
  }
}

//自定义IconContainer
// ignore: must_be_immutable
class IconContainer extends StatelessWidget {
  Color color;
  IconData icon;
  IconContainer(this.icon, {Key? key, this.color = Colors.red})
      : super(key: key);
  
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      height: 120,
      width: 120,
      color: color,
      child: Icon(
        icon,
        color: Colors.white,
        size: 28,
      ),
    );
  }
}

Row组件

import 'package:flutter/material.dart';

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

//代码块 statelessW
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text("Flutter App")),
        body: const HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.black12,
      child: Row(
        //外部没有Container  行是自适应的
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
        children: [
          IconContainer(Icons.home),
          IconContainer(Icons.search),
          IconContainer(
            Icons.ac_unit_sharp,
            color: Colors.orange,
          ),
        ],
      ),
    );
  }
}

//自定义IconContainer
// ignore: must_be_immutable
class IconContainer extends StatelessWidget {
  Color color;
  IconData icon;
  IconContainer(this.icon, {Key? key, this.color = Colors.red})
      : super(key: key);
  
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment.center,
      height: 120,
      width: 120,
      color: color,
      child: Icon(
        icon,
        color: Colors.white,
        size: 28,
      ),
    );
  }
}

Column组件

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: double.infinity,
      color: Colors.black12,
      child: Column(//列是自适应的
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: CrossAxisAlignment.start,//start在左边,end在右边
        children: [
          IconContainer(Icons.home),
          IconContainer(Icons.search),
          IconContainer(
            Icons.ac_unit_sharp,
            color: Colors.orange,
          ),
        ],
      ),
    );
  }
}

弹性布局:Flex Expanded

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return Flex(
      direction: Axis.horizontal, //水平效果,同Row设置效果,vertical:列的效果,同Column
      children: [
        Expanded(
          flex: 1,
          child: IconContainer(Icons.home), //加上Expanded组件后,元素设置宽度是没有效果的
        ),
        Expanded(
          flex: 2,
          child: IconContainer(
            Icons.ac_unit_sharp,
            color: Colors.orange,
          ),
        ),
      ],
    );
  }
}
//左边自适应,右边固定宽度
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          flex: 1,
          child: IconContainer(Icons.home), //加上Expanded组件后,元素设置宽度是没有效果的
        ),
        IconContainer(
          Icons.ac_unit_sharp,
          color: Colors.orange,
        ),
      ],
    );
  }
}
import 'package:flutter/material.dart';

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

//代码块 statelessW
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(title: const Text("Flutter App")),
        body: const HomePage(),
      ),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Container(
          width: double.infinity,
          height: 200,
          color: Colors.black,
        ),
        Row(
          children: [
            Expanded(
              flex: 2,
              child: SizedBox(
                  height: 180,
                  child: Image.network(
                    "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
                    fit: BoxFit.cover,
                  )),
            ),
            Expanded(
                flex: 1,
                child: SizedBox(
                  height: 180,
                  child: Column(
                    children: [
                      Expanded(
                          flex: 1,
                          child: SizedBox(
                            width: double.infinity,
                            child: Image.network(
                              "https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/01/0E/ChMkJ1bKwaOINj39AA0G_ijASO0AALGbQOq5P0ADQcW115.jpg",
                              fit: BoxFit.cover,
                            ),
                          )),
                      Expanded(
                          flex: 2,
                          child: SizedBox(
                            width: double.infinity,
                            child: Image.network(
                              "https://desk-fd.zol-img.com.cn/t_s960x600c5/g5/M00/02/06/ChMkJlbKyeCIC-SBABiE33zZm4wAALITwH7uzwAGIT3484.jpg",
                              fit: BoxFit.cover,
                            ),
                          ))
                    ],
                  ),
                )),
          ],
        )
      ],
    );
  }
}

stack堆叠

  1. class HomePage extends StatelessWidget {
      const HomePage({Key? key}) : super(key: key);
    
      
      Widget build(BuildContext context) {
        return Stack(
          //堆叠
          children: [
            Container(
              height: 400,
              width: 300,
              color: Colors.red,
            ),
            Container(
              height: 200,
              width: 200,
              color: Colors.yellow,
            ),
            const Text("你好flutter")
          ],
        );
      }
    }
    
    

Flutter Stack Positioned

Stack组件中结合Positioned组件也可以控制每个子元素的显示位置

属性说明
top子元素距离顶部的距离
bottom子元素距离底部的距离
bottomleft子元素距离左侧的距离
bottomright子元素距离右侧的距离
bottomchild子组件
width组件的高度(注意:宽度和高度必须是固定值,没法使用double.infinity)
height子组件的高度
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Container(
      height: 400,
      width: 300,
      color: Colors.red,
      child: Stack(//注意:相对于外部容器进行定位 如果没有外部容器就相对于整个屏幕进行定位
        children: [
          Positioned(
            left: 10,
            bottom: 10,
            child: Container(
              height: 200,
              width: 200,
              color: Colors.yellow,
            ),
          ),
          const Positioned(right: 0, bottom: 190, child: Text("你好flutter"))
        ],
      ),
    );
  }
}
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    final size = MediaQuery.of(context).size;
    return Stack(
      children: [
        ListView(
          padding: const EdgeInsets.only(top: 50),
          children: const [
            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")),
          ],
        ),
        Positioned(
            left: 0,
            top: 0,
            width: size.width,//配置子元素的宽度和高度  无法使用double.infinity
            height: 44,//配置子元素的宽度和高度 
            child: Row(
              children: [
                Expanded(
                    flex: 1,
                    child: Container(
                      alignment: Alignment.center,
                      height: 44,
                      color: Colors.black,
                      child: const Text(
                        "二级导航",
                        style: TextStyle(color: Colors.white),
                      ),
                    ))
              ],
            ))
      ],
    );
  }
}

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

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    //final size = MediaQuery.of(context).size;
    return const Stack(
      children: [
        Align(
          alignment: Alignment.topLeft,
          child: Text("收藏"),
        ),
        Align(
          alignment: Alignment.topRight,
          child: Text("购买"),
        )
      ],
    );
  }
}
class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    //final size = MediaQuery.of(context).size;
    return Container(
      width: 300,
      height: 300,
      color: Colors.red,
      child: const Align(
        alignment: Alignment(1, 1),
        child: Text("你好Flutter"),
      ),
    );
  }
}

AspectRatio

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

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    //final size = MediaQuery.of(context).size;
    return AspectRatio(
      aspectRatio: 2 / 1,//宽高比
      child: Container(
        color: Colors.red,
      ),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    //final size = MediaQuery.of(context).size;
    return ListView(children: const [
      Card(
          // shape: RoundedRectangleBorder(
          //     borderRadius: BorderRadius.circular(10)
          //   ),      //圆角
          elevation: 10,     //阴影深度
          margin: EdgeInsets.all(10),//外边距
          child: Column(children: [
            ListTile(
              title: Text("张三", style: TextStyle(fontSize: 28)),
              subtitle: Text("高级软件工程师"),//副标题
            ),
            Divider(),        //两个view之间的分割线
            ListTile(
              title: Text(
                "电话:xxxxxxxxxxxx",
              ),
            ),
            ListTile(
              title: Text(
                "地址:xxxxxxxxxxxx",
              ),
            )
          ])),
      SizedBox(
        height: 20,
      ),
      Card(
          elevation: 10,
          child: Column(children: [
            ListTile(
              title: Text("李四", style: TextStyle(fontSize: 28)),
              subtitle: Text("flutter高级软件工程师"),
            ),
            Divider(),
            ListTile(
              title: Text(
                "电话:xxxxxxxxxxxx",
              ),
            ),
            ListTile(
              title: Text(
                "地址:xxxxxxxxxxxx",
              ),
            )
          ])),
    ]);
  }
}

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

  
  Widget build(BuildContext context) {
    //获取设备的宽度和高度
    //final size = MediaQuery.of(context).size;
    return ListView(
      children: [
        Card(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
          elevation: 20,
          margin: const EdgeInsets.all(10),
          child: Column(
            children: [
              AspectRatio(
                aspectRatio: 16 / 9,
                child: Image.network(
                  "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
                  fit: BoxFit.cover,
                ),
              ),
              const ListTile(
                title: Text("xxxxxxxx"),
                subtitle: Text("xxxxxxxxx"),
              )
            ],
          ),
        ),
        Card(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
          elevation: 20,
          margin: const EdgeInsets.all(10),
          child: Column(
            children: [
              AspectRatio(
                aspectRatio: 16 / 9,
                child: Image.network(
                  "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
                  fit: BoxFit.cover,
                ),
              ),
              const ListTile(
                title: Text("xxxxxxxx"),
                subtitle: Text("xxxxxxxxx"),
              )
            ],
          ),
        )
      ],
    );
  }
}

Card(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
          elevation: 20,
          margin: const EdgeInsets.all(10),
          child: Column(
            children: [
              AspectRatio(
                aspectRatio: 16 / 9,
                child: Image.network(
                  "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
                  fit: BoxFit.cover,
                ),
              ),
              ListTile(   //设置圆形图片方法一
                leading: ClipOval(
                  child: Image.network(
                    "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
                    fit: BoxFit.cover,
                    height: 40,
                    width: 40,
                  ),
                ),
                title: const Text("xxxxxxxx"),
                subtitle: const Text("xxxxxxxxx"),
                // const ListTile(    //设置圆形图片方法二
                //   leading: CircleAvatar(
                //     backgroundImage: NetworkImage("https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0")),
                //   title:  Text("xxxxxxxx"),
                //   subtitle:  Text("xxxxxxxxx"),
                // )
              )
            ],
          ),
        ),

按钮

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

  
  Widget build(BuildContext context) {
    return ListView(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            ElevatedButton(
                onPressed: () {
                  print("ElevatedButton");
                },
                child: const Text("普通按钮")),
            TextButton(onPressed: () {}, child: const Text("文本按钮")),
            const OutlinedButton(onPressed: null, child: Text("边框的按钮")),
            IconButton(onPressed: () {}, icon: const Icon(Icons.thumb_up))
          ],
        ),
        const SizedBox(
          height: 20,
        ),
        Row(
          //图标按钮
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            ElevatedButton.icon(
                onPressed: () {},
                icon: const Icon(Icons.send),
                label: const Text("发送")),
            TextButton.icon(
                onPressed: () {},
                icon: const Icon(Icons.add),
                label: const Text("增加")),
            OutlinedButton.icon(
                onPressed: () {},
                icon: const Icon(Icons.info),
                label: const Text("消息")),
          ],
        ),
        Row(
          //设置图标按钮及颜色
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            ElevatedButton(
                style: ButtonStyle(
                    backgroundColor:
                        MaterialStateProperty.all(Colors.red), //按钮颜色
                    foregroundColor:
                        MaterialStateProperty.all(Colors.black)), //文字图标颜色
                onPressed: () {
                  print("ElevatedButton");
                },
                child: const Text("普通按钮"))
          ],
        ),
        const SizedBox(
          height: 20,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Container(
              height: 60,
              width: 140,
              child: ElevatedButton(onPressed: () {}, child: const Text("大按钮")),
            ),
            SizedBox(
              height: 40,
              width: 100,
              child: ElevatedButton.icon(
                  onPressed: () {},
                  icon: const Icon(Icons.search),
                  label: const Text("搜索")),
            )
          ],
        ),
        const SizedBox(
          height: 20,
        ),
        Row(
          children: [
            Expanded(
                flex: 1,
                child: Container(
                    margin: const EdgeInsets.all(20),   //设置边距
                    height: 40,
                    child: ElevatedButton(
                      onPressed: () {},
                      style: ButtonStyle(
                          backgroundColor:
                              MaterialStateProperty.all(Colors.red),
                          foregroundColor:
                              MaterialStateProperty.all(Colors.white)),
                      child: const Text("登录"),
                    )))
          ],
        )
      ],
    );
  }
}

圆角及圆形按钮

Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            ElevatedButton(
                style: ButtonStyle(
                    shape: MaterialStateProperty.all(//圆角
                        RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(12)))),
                onPressed: () {},
                child: const Text("圆角")),
            SizedBox(
              height: 80,
              width: 80,
              child: ElevatedButton(
                  style: ButtonStyle(
                      shape: MaterialStateProperty.all(//圆形
                          const CircleBorder(
                    side: BorderSide(width: 2, color: Colors.yellow), //边框
                  ))),
                  onPressed: () {},
                  child: const Text("圆角")),
            )
          ],
        ),

设置按钮边框

Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            OutlinedButton(
                style: ButtonStyle(side: MaterialStateProperty.all(//修改边框颜色
                    const BorderSide(width: 1, color: Colors.red))),
                onPressed: () {},
                child: const Text("带边框的按钮"))
          ],
        )

Wap按钮组件

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

  
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(10),
      child: Wrap(
        alignment: WrapAlignment.center, //居中显示  end居右显示
        spacing: 10, //水平间距*
        runSpacing: 10, //垂直间距*
        //direction: Axis.vertical,  //垂直排列
        children: [
          Button("第1课", onPressed: () {}),
          Button("第2课", onPressed: () {}),
          Button("第3课", onPressed: () {}),
          Button("第4课", onPressed: () {}),
          Button("第5课", onPressed: () {}),
          Button("第6课", onPressed: () {}),
          Button("第7课", onPressed: () {}),
          Button("第8课", onPressed: () {}),
          Button("第9课", onPressed: () {}),
          Button("第10课", onPressed: () {}),
          Button("第11课", onPressed: () {}),
          Button("第12课", onPressed: () {}),
          Button("第13课", onPressed: () {}),
          Button("第14课", onPressed: () {}),
          Button("第15课", onPressed: () {}),
          Button("第16课", onPressed: () {}),
          Button("第17课", onPressed: () {}),
          Button("第18课", onPressed: () {}),
          Button("第19课", onPressed: () {}),
          Button("第20课", onPressed: () {}),
        ],
      ),
    );
  }
}

//自定义按钮组件
// ignore: must_be_immutable
class Button extends StatelessWidget {
  String text; //按钮的文字
  void Function()? onPressed; //方法
  Button(this.text, {Key? key, required this.onPressed}) : super(key: key);

  
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all(Colors.white),
          foregroundColor: MaterialStateProperty.all(Colors.black45)),
      onPressed: onPressed,
      child: Text(text),
    );
  }
}

页面

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

  
  Widget build(BuildContext context) {
    return ListView(
      padding: const EdgeInsets.all(10),
      children: [
        Row(
          children: [
            Text(
              "热搜",
              style: Theme.of(context).textTheme.titleLarge,
            )
          ],
        ),
        const Divider(),
        Wrap(
          spacing: 10,
          runSpacing: 10,
          children: [
            Button("数学", onPressed: () {}),
            Button("语文", onPressed: () {}),
            Button("英语", onPressed: () {}),
            Button("生物", onPressed: () {}),
            Button("化学", onPressed: () {}),
            Button("物理", onPressed: () {}),
            Button("八年级", onPressed: () {}),
            Button("六年级", onPressed: () {}),
            Button("二年级", onPressed: () {}),
            Button("一年级", onPressed: () {}),
          ],
        ),
        const Divider(),
        const SizedBox(
          height: 10,
        ),
        Row(
          children: [
            Text(
              "历史记录",
              style: Theme.of(context).textTheme.titleLarge,
            )
          ],
        ),
        const Divider(),
        const Column(
          children: [
            ListTile(
              title: Text("物理"),
            ),
            Divider(),
            ListTile(
              title: Text("英语"),
            ),
            Divider(),
            ListTile(
              title: Text("测试题"),
            ),
            Divider(),
          ],
        ),
        const SizedBox(
          height: 40,
        ),
        Padding(
          padding: const EdgeInsets.all(40),
          child: OutlinedButton.icon(
            //在ListView中自适应
            style: ButtonStyle(
                foregroundColor: MaterialStateProperty.all(Colors.black45)),
            onPressed: () {},
            icon: const Icon(Icons.delete),
            label: const Text("清空历史记录"),
          ),
        )
      ],
    );
  }
}

//自定义按钮组件
// ignore: must_be_immutable
class Button extends StatelessWidget {
  String text; //按钮的文字
  void Function()? onPressed; //方法
  Button(this.text, {Key? key, required this.onPressed}) : super(key: key);

  
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all(Colors.white),
          foregroundColor: MaterialStateProperty.all(Colors.black45)),
      onPressed: onPressed,
      child: Text(text),
    );
  }
}

Flutter StatelessWidget,StatefulWidget

在Flutter中自定义组件其实就是一个类,这个类需要继承StatelessWidget/StatefulWidget.

StatelessWidget是无状态组件,状态不可变的widget

StatefulWidget是有状态组件,持有的状态可能在widget生命周期改变。

有状态组件

//有状态组件  如果我们想改变页面中的数据的话这个时候就需要用到StatefulWidget
class HomePage extends StatefulWidget {
  const HomePage({super.key});

  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _numCount = 0;
  
  Widget build(BuildContext context) {
    print(_numCount);
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flutter app"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              "$_numCount",
              style: Theme.of(context).textTheme.headlineLarge,
            ),
            const SizedBox(
              height: 100,
            ),
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    _numCount++;
                  });
                },
                child: const Text("增加"))
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _numCount++;
          });
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

动态列表,计数器

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final List<String> _list = [];
  //final只能赋一次值,定义数组可增加数组中数量
  //const定义时需确定值
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Flutter App")),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          //改变数据必须加上setStat
          setState(() {
            _list.add("我是一个新增的列表");
          });
        },
      ),
      body: ListView(
        children: _list.map((v) {
          return ListTile(
            title: Text(v),
          );
        }).toList(),
      ),
    );
  }
}

导航栏

属性名说明
itemsList底部导航条按钮集合
iconSizeicon
currrentIndex默认选中第几个
onTab选中变化回调函数
fixedColor选中的颜色
typeBottomNavigationBarType.fixed BottomNavigationBarType.shifting
DrawerHeader(
                  decoration: BoxDecoration(
                      //color: Colors.yellow,
                      image: DecorationImage(
                          image: NetworkImage(
                              "https://ts1.cn.mm.bing.net/th/id/R-C.eec02321ea106169d757f427b98b358d?rik=%2bgK43uKTPrZbCw&riu=http%3a%2f%2f00.minipic.eastday.com%2f20170823%2f20170823152907_d41d8cd98f00b204e9800998ecf8427e_4.jpeg&ehk=FsISayQ5Gjp%2boHXA8OW7nhrZdn2JEzUKk3lfW%2br0P70%3d&risl=&pid=ImgRaw&r=0"),
                          fit: BoxFit.cover)),
                  child: Column(
                    children: [
                      ListTile(
                        leading: CircleAvatar(
                          backgroundImage: NetworkImage(
                              "https://sc.68design.net/photofiles/201503/wvFUgWWHXH.jpg"),
                        ),
                        title: Text(
                          "张三",
                          style: TextStyle(color: Colors.red),
                        ),
                      ),
                      ListTile(
                        title: Text("邮箱:xxx@qq.com"),
                      )
                    ],
                  )),

Flutter UserAccountsDrawerHeader

属性描述
decoration设置顶部背景颜色
accountName账户名称
accountEmail账户邮箱
currentAccountPicture用户头像
otherAccountsPictures用来设置当前账户其他账户头像
margin

侧边栏(抽屉菜单)

drawer: Drawer(
        child: Column(children: [
          Row(children: [
            Expanded(
                flex: 1,
                child: UserAccountsDrawerHeader(
                  accountName: const Text("姓名"),
                  accountEmail: const Text("邮箱;@qq.com"),
                  otherAccountsPictures: [
                    //其他图片
                    Image.network(
                        "https://img.zcool.cn/community/0186025d143ecaa8012051cd9c2eb7.jpg@1280w_1l_2o_100sh.jpg"),
                    Image.network(
                        "https://img.zcool.cn/community/0186025d143ecaa8012051cd9c2eb7.jpg@1280w_1l_2o_100sh.jpg")
                  ],
                  currentAccountPicture: const CircleAvatar(
                    //头像
                    backgroundImage: NetworkImage(
                        "https://sc.68design.net/photofiles/201503/wvFUgWWHXH.jpg"),
                  ),
                  decoration: const BoxDecoration(
                      image: DecorationImage(
                          fit: BoxFit.cover,
                          image: NetworkImage(
                              "https://clubimg.club.vmall.com/data/attachment/forum/202006/03/210216pnzsu3qfkaq09pv2.jpg"))),
                ))
          ]),
          const ListTile(
            leading: CircleAvatar(
              child: Icon(Icons.people),
            ),
            title: Text("个人中心"),
          ),
          const Divider(),
          const ListTile(
            leading: CircleAvatar(
              child: Icon(Icons.settings),
            ),
            title: Text("系统设置"),
          ),
        ]),
      ),

TabBar属性

Stack(children: [
      Image.network(
          "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0"),
      Positioned(
        bottom: 20,
        left: 20,
        child: ClipOval(
          child: Image.network(
            "https://img95.699pic.com/photo/50086/3791.jpg_wh300.jpg!/fh/300/quality/90",
            fit: BoxFit.cover,
            height: 60,
            width: 60,
          ),
        ),
      ),
      Positioned(
          top: 10,
          right: 10,
          child: SizedBox(
            height: 30,
            width: 30,
            child: FloatingActionButton(
              backgroundColor: Colors.white12,
              child: const Icon(Icons.add),
              onPressed: () {},
            ),
          )),
    ]);
Column(children: [
            ListTile(
              leading: ClipOval(
                child: Image.network(
                  "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
                  fit: BoxFit.cover,
                  height: 40,
                  width: 40,
                ),
              ),
              title: const Text("张三", style: TextStyle(fontSize: 28)),
              subtitle: const Text("数学老师    七年级"), //副标题
            ),
            const Divider(), //两个view之间的分割线
            const ListTile(
              title: Text(
                "电话:xxxxxxxxxxxx",
              ),
            ),
            const ListTile(
              title: Text(
                "授课方式:课堂气氛较为活跃,讲课方式有趣",
              ),
            )
          ])),
      const SizedBox(
        height: 20,
      ),
Column(
      children: [
        Stack(children: [
          Image.network(
              "https://ts1.cn.mm.bing.net/th/id/R-C.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0"),
          Positioned(
            bottom: 20,
            left: 20,
            child: ClipOval(
              child: Image.network(
                "https://img95.699pic.com/photo/50086/3791.jpg_wh300.jpg!/fh/300/quality/90",
                fit: BoxFit.cover,
                height: 60,
                width: 60,
              ),
            ),
          ),
          Positioned(
              top: 10,
              right: 10,
              child: SizedBox(
                height: 30,
                width: 30,
                child: FloatingActionButton(
                  backgroundColor: Colors.white12,
                  child: const Icon(Icons.add),
                  onPressed: () {},
                ),
              )),
        ]),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            SizedBox(
              height: 40,
              width: 150,
              child: OutlinedButton(
                onPressed: () {},
                child: const Text("学生"),
              ),
            ),
            SizedBox(
              height: 40,
              width: 150,
              child: OutlinedButton(
                onPressed: () {},
                child: const Text("老师"),
              ),
            ),
          ],
        ),
       
      ],
    );
import 'package:flutter/material.dart';
import './pages/tabs.dart';
import './pages/search.dart';
import './pages/news.dart';
import './pages/form.dart';

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

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

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      //home: const Tabs(),
      initialRoute: "/",
      routes: {
        "/": (context) => const Tabs(),
        "/news": (context) => const NewsPage(),
        "/search": (context) => const SearchPage(),
        "/form": (context) => const FormPage(),
      },
    );
  }
}

路由跳转

普通路由跳转及传值

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

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        ElevatedButton(
            onPressed: () {
              //跳转路由
              Navigator.of(context)
                  .push(MaterialPageRoute(builder: (BuildContext context) {
                return const SearchPage();
              }));
            },
            child: const Text("基本路由跳转")),
       ],
    ));
  }
}
import 'package:flutter/material.dart';

class SearchPage extends StatefulWidget {
  const SearchPage({super.key});

  
  State<SearchPage> createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("搜索页面"),
      ),
      body: const Center(
        child: Text("搜索页面"),
      ),
    );
  }
}

PageView组件

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

void main() {runApp(const MyApp());
}
class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key); build(BuildContext context) {return MaterialApp(title: 'test',home: Scaffold(appBar: AppBar(title: const Text('key demo'),),body: const KeyDemo(),),);}
}

class KeyDemo extends StatefulWidget {const KeyDemo({Key? key}) : super(key: key);<StatefulWidget> createState() => _KeyDemo();
}

class _KeyDemo extends State<KeyDemo> {final List<ColorBlock> _list = [const ColorBlock(text: '1'),const ColorBlock(text: '2'),const ColorBlock(text: '3'),const ColorBlock(text: '4'),const ColorBlock(text: '5'),]; build(BuildContext context) {return Column(children: [..._list,ElevatedButton(onPressed: () {_list.removeAt(0);setState(() {});},child: const Text('删除'),)],);}
}

class ColorBlock extends StatefulWidget {final String text;const ColorBlock({Key? key, required this.text}) : super(key: key);<StatefulWidget> createState() => _ColorBlock();
}

class _ColorBlock extends State<ColorBlock> {final color = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1.0); build(BuildContext context) {return Container(width: double.infinity,height: 50,color: color,child: Text(widget.text),);}
} 

class GlobalKeyDemo extends StatefulWidget {const GlobalKeyDemo({Key? key}) : super(key: key);<StatefulWidget> createState() => _GlobalKeyDemo();
}

class _GlobalKeyDemo extends State<GlobalKeyDemo> {GlobalKey _globalKey = GlobalKey(); build(BuildContext context) {return Column(children: [ColorBlock(key: _globalKey,),ElevatedButton(onPressed: () {/// 通过GlobalKey可以访问组件ColorBlock的内部(_globalKey.currentState as _ColorBlock).setColor();setState(() {});},child: const Text('更新为红色'),)],);}
}

class ColorBlock extends StatefulWidget {const ColorBlock({Key? key}) : super(key: key);<StatefulWidget> createState() => _ColorBlock();
}

class _ColorBlock extends State<ColorBlock> {Color color = Colors.blue;setColor() {color = Colors.red;} build(BuildContext context) {return Container(width: double.infinity,height: 50,color: color,);}
} 

class ValueKey<T> extends LocalKey {
 const ValueKey(this.value);
 final T value;

 
 bool operator ==(Object other) { if (other.runtimeType != runtimeType) return false; return other is ValueKey<T> && other.value == value;
 }
} 

class ObjectKey extends LocalKey {const ObjectKey(this.value);final Object? value; operator ==(Object other) {if (other.runtimeType != runtimeType)return false;/// identical函数: 检查两个引用是否指向同一对象return other is ObjectKey&& identical(other.value, value);}/// ... 
} 

class UniqueKey extends LocalKey {UniqueKey(); toString() => '[#${shortHash(this)}]';
} 

Flutter动画

AnimatedList实现动画列表

AnimatedList 和 ListView 的功能大体相似,不同的是, AnimatedList 可以在列表中插入或删除节点时执行一个动画,在需要添加或删除列表项的场景中会提高用户体验.

AnimatedList 是一个 StatefulWidget,它对应的 State 类型为 AnimatedListState,添加和删除元素的方法位于 AnimatedListState 中:

void insertItem(int index, { Duration duration = _kDuration }); 
 
void removeItem(int index, AnimatedListRemovedItemBuilder builder, { Duration duration = _kDuration }) ;

AnimatedList常见属性:

属性描述
keyglobalKey fifinal globalKey = GlobalKey();
initialItemCount子元素数量
itemBuilder方法 ( BuildContext context, int index, Animation animation) {}

关于GlobalKey: 每个 Widget 都对应一个 Element ,我们可以直接对 Widget 进行操作,但是无法直接操作 Widget 对应的 Element 。而 GlobalKey 就是那把直接访问 Element 的钥匙。通过 GlobalKey可以获取到 Widget 对应的 Element 。

Stack(
  children: [
    //内置的动画
    PositionedTransition(
     //Tween 补间,表示一个区间值
      rect: RelativeRectTween(
        //初始位置
        begin: const RelativeRect.fromLTRB(x, y,.,.),
        //结束位置
        end: const RelativeRect.fromLTRB(endX,endY,.,.),
      ).animate(
        CurvedAnimation(
          parent: _controller,
          curve: Curves.elasticOut,
        ),
      ),
      child: null,
    ),
  ],
);
//拖动的时候不断更新动画,让他满足自己动画的标准
onPanUpdate: (details) {
  setState(() {
    x += details.delta.dx;
    y += details.delta.dy;
    endX = 0; \\或者靠右坐标
    endY=y;
  });
},
//拖动结束后开始动画
onPanEnd: (details) {
    _controller.forward();
},

Curves曲线值

属性
linear匀速的
decelerate匀减速
ease开始加速,后面减速
easeIn开始慢,后面快
easeOut开始快,后面慢
easeInOut开始慢,然后加速,最后再减速
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值