【Flutter学习笔记】9.7 动画过渡组件

参考资料:《Flutter实战·第二版》9.7 动画过渡组件


“动画过渡组件”指的是在Widget属性发生变化时会执行过渡动画的组件,其最明显的一个特征就是会在内部管理一个AnimationControllercontroller定义了过渡动画的时长,而animation对象的定义过程中会指明动画的曲线、添加监听,通过Tween对象指明动画的区间起止值。

9.7.1 自定义动画过渡组件

要实现一个AnimatedDecoratedBox,它可以在decoration属性发生变化时,从旧状态变成新状态的过程可以执行一个过渡动画。想要实现一个外观改变过渡的组件,首先需要定义一个Stateful Widget,并提供需要输入的参数,包含、子Widget、曲线样式等,完整的实现代码如下:

import 'dart:ui';

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

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

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

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'TEAL WORLD'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(
          widget.title,
          style: TextStyle(
              color: Colors.teal.shade800, fontWeight: FontWeight.w900),
        ),
        actions: [
          ElevatedButton(
            child: const Icon(Icons.refresh),
            onPressed: () {
              setState(() {});
            },
          )
        ],
      ),
      body: const AnimatedTestRoute(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(
          Icons.add_box,
          size: 30,
          color: Colors.teal[400],
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

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

  
  AnimatedTestRouteState createState() => AnimatedTestRouteState();
}

class AnimatedTestRouteState extends State<AnimatedTestRoute> with SingleTickerProviderStateMixin {
  Color _decorationColor = Colors.blue;
  var duration = const Duration(seconds: 1);
  
  Widget build(BuildContext context) {
    return AnimatedDecoratedBox1(
      duration: duration,
      decoration: BoxDecoration(color: _decorationColor),
      child: TextButton(
        onPressed: () {
          setState(() {
            _decorationColor = Colors.red;
          });
        },
        child: const Text(
          "AnimatedDecoratedBox",
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }
}

class AnimatedDecoratedBox1 extends StatefulWidget {
  const AnimatedDecoratedBox1({
    Key? key,
    required this.decoration,
    required this.child,
    this.curve = Curves.linear,
    required this.duration,
    this.reverseDuration,
  }) : super(key: key);

  final BoxDecoration decoration;
  final Widget child;
  final Duration duration;
  final Curve curve;
  final Duration? reverseDuration;

  
  AnimatedDecoratedBox1State createState() => AnimatedDecoratedBox1State();
}

class AnimatedDecoratedBox1State extends State<AnimatedDecoratedBox1>
    with SingleTickerProviderStateMixin {
  
  AnimationController get controller => _controller;
  late AnimationController _controller;

  Animation<double> get animation => _animation;
  late Animation<double> _animation;

  late DecorationTween _tween;

  
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        return DecoratedBox(
          decoration: _tween.animate(_animation).value,
          child: child,
        );
      },
      child: widget.child,
    );
  }

  
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: widget.duration,
      reverseDuration: widget.reverseDuration,
      vsync: this,
    );
    _tween = DecorationTween(begin: widget.decoration);
    _updateCurve();
  }

  void _updateCurve() {
    _animation = CurvedAnimation(parent: _controller, curve: widget.curve);
  }

  
  void didUpdateWidget(AnimatedDecoratedBox1 oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.curve != oldWidget.curve) _updateCurve();
    _controller.duration = widget.duration;
    _controller.reverseDuration = widget.reverseDuration;
    //正在执行过渡动画
    if (widget.decoration != (_tween.end ?? _tween.begin)) {
      _tween
        ..begin = _tween.evaluate(_animation)
        ..end = widget.decoration;

      _controller
        ..value = 0.0
        ..forward();
    }
  }

  
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

Flutter中,动画的产生是伴随Widget重构的,animation的值是一直变化的,但是只有Widget重建时UI界面才会随之变化。
初始化阶段,在使用AnimatedDecoratedBox组件的位置定义了样式类型和执行时长,传入组件后initState()方法中定义_controller_tween对象,随后定义_animation,此时动画还没有执行,且_tween的结束样式还没有定义。
然后通过build()方法构建UI界面,传入定义好的_animation对象并通过_tween.animate()方法取值设置盒子颜色,因为此时动画没执行,所以盒子是静止蓝色的。child元素是一个按钮,其按下时能够改变传入参数_decorationColor,使其变为红色。didUpdateWidget()方法在build()结束后会被调用进行一次重新构建(似乎是由鼠标hover引起的,暂时原因不明),但当前的参数并没有变化,而且widget.decoration的值还是蓝色,因此界面没有任何变化。通过在控制台打印信息可以印证该结论:
在这里插入图片描述
按钮还没有按下时(此时_tween.end==null_tween.begin为初始值),条件if (widget.decoration != (_tween.end ?? _tween.begin))不成立,不进行动画触发;
按钮按下时,由于AnimatedDecoratedBox的外部参数发生了变化,触发了didUpdateWidget()方法,此时上面的条件就成立了,也因此设置好了起止状态并开始了插值动画。动画进行时,子Widget(按钮)会不断的重新build,从控制台打印信息可以观察这一现象:

AnimatedDecoratedBox initState - decoration = BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3)))
AnimatedDecoratedBox build
Child build! - animated color = BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - decoration color = BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - begin=BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - end=null
didUpdateWidget
AnimatedDecoratedBox build
Child build! - animated color = BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - decoration color = BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - begin=BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - end=null
didUpdateWidget
AnimatedDecoratedBox build
Child build! - animated color = BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - decoration color = BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336))) - begin=BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - end=BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336)))
Child build! - animated color = BoxDecoration(color: Color(0xff2295f1)) - decoration color = BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336))) - begin=BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - end=BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336)))
...
Child build! - animated color = BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336))) - decoration color = BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336))) - begin=BoxDecoration(color: MaterialColor(primary value: Color(0xff2196f3))) - end=BoxDecoration(color: MaterialColor(primary value: Color(0xfff44336)))

应该注意的是,一般定义动画组件对象的方法都是内部定义controller和animation对象,只应用控制动画播放、反向播放等逻辑即可,其起止状态已知;但起止状态需要动作触发、且需要外部参数的组件,需要获取到终止状态才能进行动画。
上面例子的最终效果如图所示:
在这里插入图片描述
但上面的代码中,_controller的管理以及_tween的更新代码是可以通用的,Flutter中提供了已经封装好的基类ImplicitlyAnimatedWidget可以帮我们轻松地实现上述功能。AnimationController的管理就在ImplicitlyAnimatedWidgetState类中。如果要封装动画,要分别继承ImplicitlyAnimatedWidgetImplicitlyAnimatedWidgetState类。下面将介绍如何使用这两个类来实现同样的变色按钮。
首先继承ImplicitlyAnimatedWidget类,构造函数需要定义好要传入的参数和子Widget,父类中已经定义好了curvedurationreverseDuration这三个属性,其中duration为必传参数,curve的初始值为线性渐变:

class AnimatedDecoratedBox extends ImplicitlyAnimatedWidget {
  const AnimatedDecoratedBox({
    Key? key,
    required this.decoration,
    required this.child,
    Curve curve = Curves.linear,
    required Duration duration,
  }) : super(
          key: key,
          curve: curve,
          duration: duration,
        );
  final BoxDecoration decoration;
  final Widget child;

  
  _AnimatedDecoratedBoxState createState() {
    return _AnimatedDecoratedBoxState();
  }
}

其次,状态对象继承AnimatedWidgetBaseState(该类继承自ImplicitlyAnimatedWidgetState类)类。其中实现了build()forEachTween()两个方法,build()中直接通过animation的值构建每个动画帧内的子Widget,而forEachTween()则用来定义Tween对象的起止值。终止值是通过参数获取的,但初始值是有两种情况的:

  1. AnimatedDecoratedBox首次build,此时直接将其decoration值置为起始状态,和上面的描述相同 。
  2. AnimatedDecoratedBox的decoration更新时,则起始状态需要设置成当前的_tween.evaluate(_animation)值,显然这可能是一个在变化中的值。这个很难想,什么时候decoration会更新。首先只有当didUpdateWidget()触发的时候才会进行判断,也就是此刻外部传入的decoration发生了变化。无论在动画结束还是动画进行中,当终止状态发生改变时,要重新设置起点并开始动画。

继承AnimatedWidgetBaseState的代码如下:

class _AnimatedDecoratedBoxState
    extends AnimatedWidgetBaseState<AnimatedDecoratedBox> {
  late DecorationTween _decoration = DecorationTween(begin: widget.decoration);

  
  Widget build(BuildContext context) {
    return DecoratedBox(
      decoration: _decoration.evaluate(animation),
      child: widget.child,
    );
  }

  
  void forEachTween(TweenVisitor<dynamic> visitor) {
    _decoration = visitor(
      _decoration,
      widget.decoration,
      (value) => DecorationTween(begin: value),
    ) as DecorationTween;
  }
}

初始化时,通过(value) => DecorationTween(begin: value)构建Tween对象,只有起始值。而中间如果_decoration有变化,则更新起始值。其中visitor的定义如下:

 Tween<T> visitor(
   Tween<T> tween, //当前的tween,第一次调用为null
   T targetValue, // 终止状态
   TweenConstructor<T> constructor,//Tween构造器,在上述三种情况下会被调用以更新tween
 );

实现效果依然和之前一样:
在这里插入图片描述
为了验证上面的第二点,可以做一个小实验,可以在调用 AnimatedDecoratedBox组件的地方再设计一个按钮,用于改变当前decoration参数的值,假设这里点击后decoration会变为绿色。当按钮颜色变化中或者变化结束时可以点击按钮观察颜色,这样就能判断“不同初始值”的含义了:

import 'dart:ui';

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

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

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

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'TEAL WORLD'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(
          widget.title,
          style: TextStyle(
              color: Colors.teal.shade800, fontWeight: FontWeight.w900),
        ),
        actions: [
          ElevatedButton(
            child: const Icon(Icons.refresh),
            onPressed: () {
              setState(() {});
            },
          )
        ],
      ),
      body: const AnimatedTestRoute(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(
          Icons.add_box,
          size: 30,
          color: Colors.teal[400],
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

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

  
  AnimatedTestRouteState createState() => AnimatedTestRouteState();
}

class AnimatedTestRouteState extends State<AnimatedTestRoute> with SingleTickerProviderStateMixin {
  Color _decorationColor = Colors.blue;
  var duration = const Duration(seconds: 2);
  
  Widget build(BuildContext context) {
    return Row(children: [
      Expanded(child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          AnimatedDecoratedBox(
            duration: duration,
            decoration: BoxDecoration(color: _decorationColor),
            child: TextButton(
              onPressed: () {
                setState(() {
                  _decorationColor = Colors.red;
                });
              },
              child: const Text(
                "AnimatedDecoratedBox",
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
          const SizedBox(height: 20.0,),
          TextButton(onPressed: (){setState(() {
            _decorationColor = Colors.green;
          });}, child: const Text("Change Color!"))
        ],
      ))
    ],);
  }
}

class AnimatedDecoratedBox extends ImplicitlyAnimatedWidget {
  const AnimatedDecoratedBox({
    Key? key,
    required this.decoration,
    required this.child,
    Curve curve = Curves.linear,
    required Duration duration,
  }) : super(
    key: key,
    curve: curve,
    duration: duration,
  );
  final BoxDecoration decoration;
  final Widget child;

  
  AnimatedDecoratedBoxState createState() {
    return AnimatedDecoratedBoxState();
  }
}

class AnimatedDecoratedBoxState
    extends AnimatedWidgetBaseState<AnimatedDecoratedBox> {
  late DecorationTween _decoration = DecorationTween(begin: widget.decoration);

  
  Widget build(BuildContext context) {
    return DecoratedBox(
      decoration: _decoration.evaluate(animation),
      child: widget.child,
    );
  }

  
  void forEachTween(TweenVisitor<dynamic> visitor) {
    _decoration = visitor(
      _decoration,
      widget.decoration,
          (value) => DecorationTween(begin: value),
    ) as DecorationTween;
  }
}

为了便于观察,我们可以把duration设置为2s,此时,如果在按钮完全变成红色后,点击下面的按钮,颜色就会从红色变成绿色:
在这里插入图片描述
如果在变色过程中点击下面的按钮,就会从蓝红中间的某个过渡色再花上2s变成绿色:
在这里插入图片描述

9.7.2 Flutter预置的动画过渡组件

Flutter SDK中也预置了很多动画过渡组件,实现方式和大都和AnimatedDecoratedBox差不多:

组件名功能
AnimatedPadding在padding发生变化时会执行过渡动画到新状态
AnimatedPositioned配合Stack一起使用,当定位状态发生变化时会执行过渡动画到新的状态。
AnimatedOpacity在透明度opacity发生变化时执行过渡动画到新状态
AnimatedAlign当alignment发生变化时会执行过渡动画到新的状态。
AnimatedContainer当Container属性发生变化时会执行过渡动画到新的状态。
AnimatedDefaultTextStyle当字体样式发生变化时,子组件中继承了该样式的文本组件会动态过

可以通过下面的示例代码来查看具体运行效果:

import 'package:flutter/material.dart';

class AnimatedWidgetsTest extends StatefulWidget {
  const AnimatedWidgetsTest({Key? key}) : super(key: key);

  
  _AnimatedWidgetsTestState createState() => _AnimatedWidgetsTestState();
}

class _AnimatedWidgetsTestState extends State<AnimatedWidgetsTest> {
  double _padding = 10;
  var _align = Alignment.topRight;
  double _height = 100;
  double _left = 0;
  Color _color = Colors.red;
  TextStyle _style = const TextStyle(color: Colors.black);
  Color _decorationColor = Colors.blue;
  double _opacity = 1;

  
  Widget build(BuildContext context) {
    var duration = const Duration(milliseconds: 400);
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          ElevatedButton(
            onPressed: () {
              setState(() {
                _padding = 20;
              });
            },
            child: AnimatedPadding(
              duration: duration,
              padding: EdgeInsets.all(_padding),
              child: const Text("AnimatedPadding"),
            ),
          ),
          SizedBox(
            height: 50,
            child: Stack(
              children: <Widget>[
                AnimatedPositioned(
                  duration: duration,
                  left: _left,
                  child: ElevatedButton(
                    onPressed: () {
                      setState(() {
                        _left = 100;
                      });
                    },
                    child: const Text("AnimatedPositioned"),
                  ),
                )
              ],
            ),
          ),
          Container(
            height: 100,
            color: Colors.grey,
            child: AnimatedAlign(
              duration: duration,
              alignment: _align,
              child: ElevatedButton(
                onPressed: () {
                  setState(() {
                    _align = Alignment.center;
                  });
                },
                child: const Text("AnimatedAlign"),
              ),
            ),
          ),
          AnimatedContainer(
            duration: duration,
            height: _height,
            color: _color,
            child: TextButton(
              onPressed: () {
                setState(() {
                  _height = 150;
                  _color = Colors.blue;
                });
              },
              child: const Text(
                "AnimatedContainer",
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
          AnimatedDefaultTextStyle(
            child: GestureDetector(
              child: const Text("hello world"),
              onTap: () {
                setState(() {
                  _style = const TextStyle(
                    color: Colors.blue,
                    decorationStyle: TextDecorationStyle.solid,
                    decorationColor: Colors.blue,
                  );
                });
              },
            ),
            style: _style,
            duration: duration,
          ),
          AnimatedOpacity(
            opacity: _opacity,
            duration: duration,
            child: TextButton(
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.blue)),
              onPressed: () {
                setState(() {
                  _opacity = 0.2;
                });
              },
              child: const Text(
                "AnimatedOpacity",
                style: TextStyle(color: Colors.white),
              ),
            ),
          ),
          AnimatedDecoratedBox1(
            duration: Duration(
                milliseconds: _decorationColor == Colors.red ? 400 : 2000),
            decoration: BoxDecoration(color: _decorationColor),
            child: Builder(builder: (context) {
              return TextButton(
                onPressed: () {
                  setState(() {
                    _decorationColor = _decorationColor == Colors.blue
                        ? Colors.red
                        : Colors.blue;
                  });
                },
                child: const Text(
                  "AnimatedDecoratedBox toggle",
                  style: TextStyle(color: Colors.white),
                ),
              );
            }),
          )
        ].map((e) {
          return Padding(
            padding: const EdgeInsets.symmetric(vertical: 16),
            child: e,
          );
        }).toList(),
      ),
    );
  }
}

在这里插入图片描述
在这里插入图片描述
已有的过渡组件,可以直接通过定义参数的方式进行设置,而完全无需担心动画相关逻辑的维护,为开发带来了极大的便利。通过自定义组件,可以更深入地理解动画过渡组件的实现原理,以达到更为复杂的动画过渡效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/474692.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux学习之C/C++文件操作底层调用及原理

前言&#xff1a;我们都知道&#xff0c;我们学习的C/C是无法直接与底层硬件进行交互的&#xff0c;所有需要与底层硬件的交互都是通过操作系统作为中介完成的&#xff0c;那Linux到底是怎么做到的呢&#xff1f;接下来我们将揭开它神秘的面纱。 目录 一&#xff0c;操作系统…

全平台7合一万能DIY小程序源码系统 带完整的安装代码包以及安装搭建教程

在当下的小程序市场中&#xff0c;虽然已有众多开发工具和服务平台&#xff0c;但很多用户仍然面临着开发难度大、功能不齐全、定制性差等问题。小编给大家分享一款全平台7合一万能DIY小程序源码系统。该系统旨在解决用户在小程序开发过程中的痛点&#xff0c;提供一站式的小程…

WordPress Plugin NotificationX插件 SQL注入漏洞复现(CVE-2024-1698)

0x01 产品简介 WordPress和WordPress plugin都是WordPress基金会的产品。WordPress是一套使用PHP语言开发的博客平台。该平台支持在PHP和MySQL的服务器上架设个人博客网站。 0x02 漏洞概述 WordPress plugin NotificationX是一个应用插件。2.8.2版本及之前 存在安全漏洞,该…

飞腾+FPGA+AI电力行业智能数据采集与分析网闸解决方案

行业痛点: 安全物联网闸在监控平台中的具体作用&#xff1a;35KV变电站是煤矿的动力核心&#xff0c;采矿人员上下井、煤炭提升输送、矿井通风等核心设备均依靠变电站提供电源。监控中心及时掌握变电站的运行状态对煤矿的安全生产非常重要。如若外部通过监控网络来控制变电站会…

Hyper Casual FX

此包包含&#xff1a; 五彩纸屑-2种 灰尘 - 1 种 闪光灯 - 8 种类型 闪耀 - 3 种类型 闪亮 - 1 种 水-2种 它可以在没有任何设置的情况下开箱即用 下载&#xff1a;​​Unity资源商店链接资源下载链接 效果图&#xff1a;

C语言编程实现文件加解密

目录 1. OpenSSL导入程序项目2. 编写加解密程序1. 程序代码2. 命令行传参3. 文件的读写4. 加解密中的细节 1. OpenSSL导入程序项目 下载并安装OpenSSL&#xff0c;下载地址打开VS&#xff0c;创建控制台应用 记得配置文件位置 右键项目名称&#xff0c;找到属性&#xff0c;并…

MySQL面试复习记录

一、mysql文章地址汇总 以下均为蓝云飘飘的文章&#xff1a; MySQL数据库&#xff08;一&#xff09;_写出sql语句,列出薪资比‘王海涛’的薪资高的所有员工,显示姓名,薪资-CSDN博客 MySQL数据库&#xff08;二&#xff09;_sql里的性别是什么代表-CSDN博客 ★★★★★ My…

(基础)AJAX概念和axios使用、URL、请求方法和数据提交、HTTP协议、接口、form-serialize插件

AJAX概念和axios使用 AJAX概念 AJAX就是使用XMLHttpRequest对象与服务器通信&#xff0c;它可以使用JSON、XML、HTML和text文本等格式发送和接收数据&#xff0c;AJAX最吸引人的就是它的异步特性&#xff0c;也就是说它可以在不重新刷新页面的情况下与服务器通信&#xff0c;…

Effect:由渲染本身引起的副作用

React 组件中的两种逻辑类型&#xff1a; 渲染逻辑代码 位于组件的顶层&#xff0c;接收 props 和 state&#xff0c;进行转换&#xff0c;返回屏幕上看到的 JSX&#xff0c;只计算不做其他任何事情&#xff1b;事件处理程序 嵌套在组件内部的函数&#xff0c;由特定的用户操作…

【timm笔记1】

1. 安装timm pip install timm2. 打印模型 import timm# 获取并打印所有可用的预训练模型名称 available_models = timm.list_models() # 打印出所有的模型 print(available_models)# 打印所有包含"resnet"字符的模型名称 resnet_models = timm.list_models(*resne…

2024年03月 Discourse 3.3.0.beta1 版本的更新

在这个版本的更新中 Discourse 完成了 Ember 5 版本的升级和更新。 Ember.js是一个用于创建 web 应用的 开源JavaScript MVC 框架&#xff0c;采用基于字符串的Handlebars 模板&#xff0c;支持双向绑定、观察者模式、计算属性&#xff08;依赖其他属性动态变化&#xff09;、…

Oracle数据库冷备份(实例)

冷备份 1、 select file#,name,bytes/1024/1024 mb from v$datafile; 2 、缩减 便于copy alter database datafile 2 resize 100m;show parameter spfilecreate undo tablespace u2 datafile /u01oracle/oradata/qq/u2.dbf size 2m autoextend on; //建新的 alter system…

为prj添加kconfig支持

为prj添加kconfig支持 KConfig是一个配置系统&#xff0c;它允许用户和开发者通过配置文件/配置界面选择需要的编译选项。目前大量的项目都有用到该配置系统&#xff08;linux、u-boot、rt-thread、esp-idf/adf、zephyr等&#xff09;&#xff0c;可以说是一个项目的构建系统中…

代码随想录阅读笔记-字符串【实现 strStr()】

题目 实现 strStr() 函数。 给定一个 haystack 字符串和一个 needle 字符串&#xff0c;在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在&#xff0c;则返回 -1。 示例 1: 输入: haystack "hello", needle "ll" 输出:…

可应用于工业控制器,新能源充电桩等众多涉及RS232通讯的产品的国产芯片——D3232,性价比高,交货周期短

D3232芯片主要用于工控主板、工业控制器、程序烧录下载器、仿真器、新能源充电桩等众多涉及RS232通讯的产品。 二、基本特性 D3232芯片由两个线路驱动器、两个线路接收器和双电荷泵电路组成&#xff0c;具有HBM>15kV、CDM>2kV的ESD保护能力&#xff0c;并且接收端输入电压…

javaweb遇到的servlet问题,jar包问题

有时候会遇到这种问题&#xff0c;有的地方会报红 这是因为这个找不到这个包&#xff0c;这个项目缺少jar包 在tomcat9之前还不是Jakarta这个名字&#xff0c;我的运行环境与服务器是jdk17与tomcat10 解决方法&#xff1a; 在项目结构中&#xff0c;找到模块&#xff0c;再…

HTTP Error 400. The request hostname is invalid.

异常信息 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd"> <HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV"Content-Type" Content"text/html;…

数据库系统概论-第15章 内存数据库管理系统

用内存的数据库&#xff0c;场景接触较少&#xff0c;不细看。 15.1 概述 15.2 内存数据库的发展历程 15.3 内存数据库的特性 15.4 内存数据库的关键技术 15.5 小结

实测国内AI大模型问答效果

随着ChatGPT热度的攀升&#xff0c;越来越多的公司也相继推出了自己的AI大模型。按照github工程awesome-LLMs-In-China所列举的&#xff0c;现如今国内AI大模型已达243个&#xff0c;比较著名的有文心一言、通义千问等。各大应用也开始内置AI玩法&#xff0c;如抖音的AI特效。下…

深度学习-2.9梯度不稳定和Glorot条件

梯度不稳定和Glorot条件 一、梯度消失和梯度爆炸 对于神经网络这个复杂系统来说&#xff0c;在模型训练过程中&#xff0c;一个最基础、同时也最常见的问题&#xff0c;就是梯度消失和梯度爆炸。 我们知道&#xff0c;神经网络在进行反向传播的过程中&#xff0c;各参数层的梯…