首页 > 其他分享 >flutter基础

flutter基础

时间:2024-06-06 17:55:10浏览次数:28  
标签:动画 return Text 基础 controller child 组件 flutter

创建的flutter项目

image
组件Material Design
Flutter中无状态组件(StatelessWidget)和有状态组件

App结构内容

image

点击查看代码
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget{
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: 'Flutter Demo',
      home:Home(),
    );
  }
}

class Home extends StatelessWidget{
  const Home({super.key});
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('首页'),
        leading:Icon(Icons.menu) ,
        actions: [
          Icon(Icons.settings)
        ],
        elevation: 0.0,
        centerTitle: true,
      ),
      body: HelloFlutter(),
    );
  }
}

class HelloFlutter extends StatelessWidget{
  const HelloFlutter({super.key});
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: Center(
        child: Text(
          'hello flutter',
          textDirection: TextDirection.ltr
          )
        )
      );
  }
}
flutter文件样式都是通过组件进行修正的 TEXT组件的应用&&RichText和TextSpan来给不同文本添加样式
点击查看代码
Column(
      children: [
        Text(
          "Flutter 是谷歌开发的一款开源、免费的,基于 Dart 语言的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生应用。",
          textDirection: TextDirection.ltr,
          style: TextStyle(
            fontSize: 30,
            color: Colors.red,
            fontWeight: FontWeight.w500,
            fontStyle: FontStyle.italic,
            decoration: TextDecoration.lineThrough,
            decorationColor: Colors.blue,
            // fontFamily: 'SourceSansPro',
          ),
          textAlign: TextAlign.left,
          maxLines: 3,
          overflow: TextOverflow.ellipsis,
          textScaleFactor: 1.5,
        ),
        RichText(
          text: TextSpan(
            text: "Hello",
            style: TextStyle(
              fontSize: 40,
              color: Color.fromARGB(255, 0, 0, 255)
            ),
            children: [
              TextSpan(
                text: "Flutter",
                style: TextStyle(
                  fontSize: 40,
                  color: Color.fromRGBO(255, 0, 0, 0.5)
                ),
              ),
              TextSpan(
                text: "你好世界",
                style: TextStyle(
                  fontSize: 30,
                  color: Color.fromARGB(0xFF, 0x00, 0xFF, 0x00)
                ),
              )
            ]
          ),
        )
      ],
    )
设置自定义字体 1.在[网上](https://fonts.google.com/ "网上")找到字体文件,下载放到项目中 2.在pubspec.yaml中声明字体 3.在MaterialAPP的theme中设置整个应用的默认字体```theme: ThemeData(fontFamily: 'SourceSansPro')``` 常用组件Text、Icon、Color 布局组件Container、线性布局(Column、Row)、弹性布局(Flex和Expanded配套),流式布局(Wrap可换行),层级布局(Stack-类似z-index、Positioned、NetworkImage(网络图片组件)) 应用需要能够联网的配置 在AndroidManifest.xml文件中 `````` 允许访问http协议
<application
	android:usesCleartextTraffic="true">
</application>

Button组件
TextButton(文本按钮)、ElevatedButton(凸起按钮)、OutlinedButton(轮廓按钮)
ButtonStyle()函数用于改变按钮样式,示例如下,其中边框用side,阴影用elevation,边框形状用shape,可给按钮全局设置主题

style: ButtonStyle(
              textStyle: MaterialStateProperty.all(
                TextStyle(
                  fontSize: 30
                )
              ),
              foregroundColor: MaterialStateProperty.resolveWith((states) {
                if (states.contains(MaterialState.pressed)) {
                  // 按下按钮时的前景色
                  return Colors.red;
                }
                // 默认状态的颜色
                return Colors.blue;
              }),
              backgroundColor: MaterialStateProperty.resolveWith((states) {
                if (states.contains(MaterialState.pressed)) {
                  // 按下按钮时的前景色
                  return Colors.yellow;
                }
                // 默认状态的颜色
                return Colors.white;
              }),
              shadowColor: MaterialStateProperty.all(Colors.yellow),
              elevation: MaterialStateProperty.all(20),
              side: MaterialStateProperty.all(
                BorderSide(
                  color: Colors.green,
                  width: 2,
                )
              ),
              // 声明按钮形状
              shape: MaterialStateProperty.all(
                StadiumBorder(
                  side: BorderSide(
                    color: Colors.green,
                    width: 2,
                  )
                )
              ),
              // 设置按钮大小
              minimumSize: MaterialStateProperty.all(Size(200, 100)),
              // 设置水波纹的颜色
              overlayColor: MaterialStateProperty.all(Colors.purple),
            )

图片组件加载本地图片需要在pubspec.yaml的flutter部分添加图片配置

列表组件

1.ingleChildScrollView

          scrollDirection: Axis.horizontal,//设置水平方向
          padding: EdgeInsets.all(10),//设置内外编剧
		  //利用list组件的generate方法批量生成元素
		  children: List.generate(
              100, 
              (index) => OutlinedButton(
                onPressed: () {},
                child: Text('按钮$index')
              ),
            )

2.ListView
默认构造函数和命名构造函数来生成list
常用ListView.builder()函数来生成列表
2.GridView网格布局
一种是指定子元素的列数,另一种是子元素的默认宽度
Scroll的组件的physics属性(确定可滚动控价的物理特性)
material.dart 提供了 Android 风格的组件;而 Cupertino 提供了 iOS 风格的组件。
判断是安卓环境还是IOS环境

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:io';

if (Platform.isIOS) {
      // 加载 iOS 风格的组件
    } else if (Platform.isAndroid) {
      // 加载 Android 风格的组件
    }

第三方组件

dio
image
发送请求代码

  void getIpAddress() async {
    try {
      final url = "https://httpbin.org/ip";
      Response response = await Dio().get(url);
      String ip = response.data['origin'];
      print(ip);
    } catch (e) {
      print(e);
    }
  }
}

flutter_swiper
shared_preferences是一个本地数据缓存库,类似AsyncStorage
增删改查操作
大概率使用在状态组件上

状态管理

StatefulWidget(状态组件)
image
状态组件的基本代码

class MyState extends StatefulWidget {
  @override
  _MyStateState createState() => _MyStateState();//继承的抽象类,抽象方法必须实现
}

class _MyStateState extends State<MyState> {
  int _num = 0;

  void _increment() {
    setState(() {
      _num++;
    });
  }

  void _decrement() {
    setState(() {
      _num--;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          ElevatedButton(
            onPressed: _decrement, 
            child: Text('-')
          ),
          Padding(
            padding: EdgeInsets.all(20),
            child: Text('$_num')
          ),
          ElevatedButton(
            onPressed: _increment, 
            child: Icon(Icons.add)
          )
        ],
      )
    );
  }
}

DataTable表格组件是一个有状态的组件,通过setState((){})来更改状态,例如让表格通过DataColumn中的onSort方法来进行排序

DataColumn(
              label: Text('年龄'),
              numeric: true,
              onSort: (int columnIndex, bool asscending) {
                setState(() {
                  _sortAscending = asscending;
                  if (asscending) {
                    data.sort((a, b) => a.age.compareTo(b.age));
                  } else {
                    data.sort((a, b) => b.age.compareTo(a.age));
                  }
                });
              }
            ),

数据中的字段可通过一个类进行声明

class User {
  String name;
  int age;
  bool selected;
  User(this.name, this.age, {this.selected = false});
}

通过写一个方法来获取表格所有行数据

 List<User> data = [
    User('张三', 18),
    User('张三丰', 218, selected: true),
    User('张翠山', 30),
    User('张无忌', 60),
  ];
  List _getUserRows() {
    List<DataRow> dataRows = [];
    for (int i = 0; i < data.length; i++) {
      dataRows.add(
        DataRow(
          selected: data[i].selected,
          onSelectChanged: (selected) {
            setState(() {
              data[i].selected = selected;
            });
          },
          cells: [
            DataCell(Text('${data[i].name}')),
            DataCell(Text('${data[i].age}')),
            DataCell(Text('男')),
            DataCell(Text('---')),
          ]
        )
      );
    }

    return dataRows;
  }

生命周期

无状态组件只有build,无所谓生命周期
image
didUpdateWidget是例如组件主题更换时触发的生命周期函数
didChangeDependencies是当组件A和B都依赖于某数据时,组件B改变了这一数据,组件A就会触发这一生命周期函数,使用数据共享组件InheritedWidget
组件就是Dart类,可通过构造函数的方式,进行跨组件的状态参数传递
InheritedWidget生命的状态数据可以在需要使用状态的InheritedWidget后代组件中,访问InheritedWidget状态数据

class MyCounter extends StatefulWidget {
  MyCounter({Key key}) : super(key: key);

  @override
  _MyCounterState createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> {
  @override
  Widget build(BuildContext context) {
    // 使用 InheritedWidget 中的共享数据
    return Text(ShareDataWidget.of(context).num.toString());
  }
}

// 数据共享组件
class ShareDataWidget extends InheritedWidget {
  final int num;
  final Widget child;

  ShareDataWidget({Key key, this.child, @required this.num}) : super(key: key, child: child);

  static ShareDataWidget of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
  }

  @override
  bool updateShouldNotify(ShareDataWidget oldWidget) {
    return true;
  }
}

第三方组价Provider
观察者跟watch类似,跨组件的状态管理,放在根组件全局
使用
image

路由与导航

匿名路由

          onPressed: () {
            return Navigator.push(
              context, 
              MaterialPageRoute(builder: (context) => Product())
            );
          }, 
		  onPressed: () => Navigator.pop(context), 

命名路由
image
命名路由的跳转onPressed: () => Navigator.pushNamed(context, 'product')
动态路由
命名路由和动态路由互斥
image

在组件中通过构造函数获取到传来的id,并且路由跳转的时候pushName方法的第二个参数加上'/'
命名路由传参
image
image
Drawer导航就是抽屉菜单,通过左滑或者右滑可以显示,在Scaffold中进行配置
BottomNavigationBar
定义状态组件,声明菜单和页面,Scaffold中的body动态,在Scaffold中声明bottomNavigationBar组件
Tab导航
form组件
Switch Checkbox Radio TextField 日历,时间选择器,Form
创建表单首先创建表单唯一键,唯一键中有验证方法,提交表单,和重置方法等

动画

补间动画
定义开始点到结束点、时间线,由系统计算开始点到结束点形成动画效果。例如透明度从0到1
拟物动画
对真实世界的行为进行建模,例如弹簧,重力,抛物线等
Animation(动画对象) 值(具体属性字段,例如透明度从0到1)和动画状态(开始、执行期间,执行完成)
AnimationController(动画控制器)抽象类,含有动画执行时间,执行最大小值,控制动画的方法等,最重要的是vsync(作用防止动画页面切换到后台时消耗不必要的资源)包含Ticker对象,获取到Ticker对象是获取每一帧刷新的通知
Tweens(插值器,补间动画)职责是定义从输入范围到输出范围的映射
Curves (常用的动画曲线即动画的执行速度)
动画步骤,初始化一个动画控制器,有时间,有vsync,有value(可以不指定值),第二步指定动画的曲线和取值范围是对value的约束,执行动画把动画渲染到组件上,渲染进程是vsync中的Ticker发起的,Ticker向组件发通知让组件一帧一帧执行动画效果
image

class _AnimationDemoState extends State<AnimationDemo> with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation animation;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    // 1.创建 AnimationController
    controller = AnimationController(
      duration: Duration(milliseconds: 400),
      vsync: this
    );

    // 2.1 声明动画曲线
    animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);

    // 2.2 设置动画值的范围
    animation = Tween(begin: 50.0, end: 400.0).animate(controller);

    // 3. 监听动画
    animation.addListener(() {
      print(animation.value);
      setState(() {
        
      });
    });

    // 4. 执行动画
    // controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
       child: Column(
         children: [
           ElevatedButton(
             onPressed: () {
               controller.forward();
             }, 
             child: Text('放大')
           ),
           ElevatedButton(
             onPressed: () {
               controller.reverse();
             }, 
             child: Text('缩小')
           ),
           ElevatedButton(
             onPressed: () {
               animation.addStatusListener((status) {
                 if (status == AnimationStatus.completed) {
                   // 反向执行动画
                   controller.reverse();
                 } else if (status == AnimationStatus.dismissed) {
                   // 正向执行动画
                   controller.forward();
                 }
               });
               controller.forward();
             }, 
             child: Text('重复')
           ),
           ElevatedButton(
             onPressed: () {
               controller.stop();
             }, 
             child: Text('停止')
           ),
           Icon(
             Icons.favorite,
             color: Colors.red,
             size: animation.value
           ),
           Opacity(
             opacity: controller.value,
             child: Text('Hello World')
           )
         ],
       ),
    );
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    controller.dispose();
  }
}

交织动画
交织动画需要给每段动画设置时间间隔(在curve处使用Interval)
Transform.translate()平移 Transform函数对组件进行矩阵变换

点击查看代码
class _AnimationDemoState extends State<AnimationDemo> with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation animation;
  Animation sizeAnimation;
  Animation colorAnimation;
  Animation rotationAnimation;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    // 1. 创建 AnimationController
    controller = AnimationController(
      duration: Duration(seconds: 3),
      vsync: this,
    );

    // 2. 创建动画
    animation = CurvedAnimation(
      parent: controller, 
      curve: Interval(0.0, 0.5)
    )..addListener(() {
      setState(() {
        
      });
      });

    // 3. 让动画反复运行
    animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        // 反向执行动画
        controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        // 正向执行动画
        controller.forward();
      }
    });

    // 4. 设置其他动画
    sizeAnimation = Tween(begin: 0.0, end: 200.0).animate(animation);
    colorAnimation = ColorTween(begin: Colors.yellow, end: Colors.red)
      .animate(CurvedAnimation(
        parent: controller, 
        curve: Interval(0.5, 0.8, curve: Curves.bounceIn)
      ))
      ..addListener(() { 
        setState(() {
          
        });
      });

    rotationAnimation = Tween(begin: 0.0, end: 2*pi).animate(
      CurvedAnimation(
        parent: controller, 
        curve: Interval(0.8, 1.0, curve: Curves.easeIn)
      )
    );
  }

  @override
  Widget build(BuildContext context) {
    return Center(
       child: Column(
         children: [
           ElevatedButton(
             onPressed: () {
               controller.forward();
             }, 
             child: Text('重复')
           ),
           ElevatedButton(
             onPressed: () {
               controller.stop();
             }, 
             child: Text('停止')
           ),
Opacity(
  opacity: controller.value,
  child: Transform.rotate(
    angle: rotationAnimation.value,
    child: Container(
      width: sizeAnimation.value,
      height: sizeAnimation.value,
      color: colorAnimation.value
    )
  )
)
         ],
       ),
    );
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    controller.dispose();
  }
}

Hero动画
Hero动画来实现跨页面的动画效果
在页面A定义起始Hero组件,声明tag
在页面B定义目标Hero组件,绑定相同的tag
应用场景,点击图片全屏显示

国际化

组件国际化,文本国际化

多主题配置

标签:动画,return,Text,基础,controller,child,组件,flutter
From: https://www.cnblogs.com/zhixy/p/18224936

相关文章

  • python 基础习题5 --- 海龟画图系列
    1.  画出一个半径为100的圆,背景色和画笔颜色自己定义,如下图:importturtleastt.speed(10)t.bgcolor("black")t.pencolor("red")t.pensize(2)radius=100t.penup()t.goto(0,-100)t.down()t.circle(radius)t.penup()t.done()答案 2. 用循环画出五个同......
  • 金蝶云星空在原有简单账表的基础上加上自定义字段
    以采购订单执行明细表为例,在原有基础上加上下面的两个字段产业链备注:F_TXBE_CYL_Notes产业链物料明细ID:F_TXBE_CYL_MateriaID1、首先打开采购订单执行明细表过滤界面找到显示隐藏列中的字段合集 新增字段:产业链备注:F_TXBE_CYL_Notes产业链物料明细ID:F_TXBE_CYL_MateriaID2......
  • 版图基础知识
    版图总结 目录版图设计一、LDE二、版图floorplan三、走线相关四、可靠性设计版图验证一、CalibreDRC二、CalibreLVS版图设计一、LDE(layoutdependenteffect)当工艺制程进入深亚微米之后,一些二级效应对器件性能的影响变得越来越突出。其中与layout强相关的有WPE......
  • 【深度学习基础】池化层
    池化层(PoolingLayer)在卷积神经网络(CNN)中常用于计算机视觉任务,但在自然语言处理(NLP)任务中也有广泛的应用。池化层在NLP任务中可以帮助提取重要特征,降低数据维度,减少计算量,增强模型的泛化能力。本文将介绍池化层在NLP任务中的应用,并提供一个具体的代码示例。1.什么是池化层......
  • 【深度学习基础】模型文件介绍
    目录简介文件概述config.jsonmodel_state.pdparamsspecial_tokens_map.jsontokenizer_config.jsonvocab.txt文件内容解析如何查看和使用这些文件示例代码简介本文档详细介绍了深度学习训练过程中生成的关键文件,及其在模型加载和推理中的作用。这些文件包括模型配置文件......
  • 组播基础原理描述
    组播基本概念组播组组播组使用一个IP组播地址标识。任何用户主机(或其他接收设备),加入一个组播组,就成为了该组成员,可以识别并接收以该IP组播地址为目的地址的IP报文。组播源以组播组地址为目的地址,发送IP报文的信源称为组播源。一个组播源可以同时向多个组播组发......
  • Unity VR 零基础开发之 Pico4 MR
    一、新建Unity2021.3.37 3D工程二、切换到Android安卓平台1、点击Unity编辑器左上角的Flie后,选择BuildSetting选项。2、弹出弹窗后,点击Android选项,然后再点击SwitchPlatform按钮切换成安卓平台。3、切换完成后Android选项后面会显示unity图标。三、官网下载PicoSDK......
  • 代码审计——基础(JAVAWEB)
    JAVAWEB目录JAVAWEBServlet技术JavaWeb概述Servelt与Servlet容器Servlet概念TomcatWeb程序结构Servlet容器响应客户请求的过程ServletConfig接口ServletConfig接口方法ServletContext接口HTTPHttp协议解析(报文详解)Http请求头Post和Get区别Http响应头HttpServletRequestHttpServ......
  • 西湖大学赵世钰老师【强化学习的理论基础】02基本概念
    文章目录概念介绍state(状态)Action(动作)Statetransition(状态转移)Policy(策略)reward(奖励)Trajectory(轨迹)andreturnDiscountedreturn(折扣回报)Episode(回合)一般是有终止点的轨迹Markovdecisionprocess(MDP)-一个对应三个单词的过程要素马尔可夫的过程概念介绍例子:网格......
  • 好书推荐-人工智能数学基础
    本书以零基础讲解为宗旨,面向学习数据科学与人工智能的读者,通俗地讲解每一个知识点,旨在帮助读者快速打下数学基础。全书分为4篇,共17章。其中第1篇为数学知识基础篇,主要讲述了高等数学基础、微积分、泰勒公式与拉格朗日乘子法;第2篇为数学知识核心篇,主要讲述了线性......