当前位置: 首页 > news >正文

Flutter-基础Widget

Flutter页面-基础Widget

文章目录

  • Flutter页面-基础Widget
    • Widget
      • Stateless Widget
      • Stateful Widget
        • State生命周期
    • 基础widget
      • 文本显示
        • Text
        • RichText
        • DefaultTextStyle
      • 图片显示
        • FlutterLogo
        • Icon
        • Image
          • Iamge.asset
          • Image.file
          • Image.network
          • Image.memory
        • CircleAvatar
        • FadeInImage
      • 按钮
        • RaisedButton
        • FlatButton
        • OutlineButton
        • IconButton
      • 输入框
        • 焦点控制
        • 获取输入内容
        • TextFormField

​ 在Flutter中,几乎所有的对象都是一个 Widget,与原生开发中的 控件不同的是,Flutter中的 widget的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector widget、用于应用主题数据传递的 Theme等等。由于Flutter主要就是用于构建用户界面的,所以,在大多数时候,可以认为widget就是一个控件,不必纠结于概念。

​ Widget的功能是“描述一个UI元素的配置数据”,Widget其实并不是表示最终绘制在设备屏幕上的显示元素,而只是显示元素的一个配置数据。实际上,Flutter中真正代表屏幕上显示元素的类是Element,也就是说Widget只是描述Element的一个配置。一个Widget可以对应多个Element,这是因为同一个Widget对象可以被添加到UI树的不同部分,而真正渲染时,UI树的每一个节点都会对应一个Element对象。

Widget

StatelessWidgetStatefulWidgetflutter的基础组件,日常开发中自定义Widget都是选择继承这两者之一。也是在往后的开放中,我们最多接触的Widget:

  • StatelessWidget:无状态的,展示信息,面向那些始终不变的UI控件;

  • StatefulWidget:有状态的,可以通过改变状态使得 UI 发生变化,可以包含用户交互(比如弹出一个 dialog)。

在实际使用中,Stateless与Stateful的选择需要取决于这个 Widget 是有状态还是无状态,简单来说看界面是否需要更新。

Stateless Widget

​ StatelessWidget用于不需要维护状态的场景,它通常在build方法中通过嵌套其它Widget来构建UI,在构建过程中会递归的构建其嵌套的Widget。

BuildContext表示构建widget的上下文,它是操作widget在树中位置的一个句柄,它包含了一些查找、遍历当前Widget树的一些方法。每一个widget都有一个自己的context对象。

import 'package:flutter/material.dart';void main() => runApp(StatelessApp());class StatelessApp extends StatelessWidget {///在build方法中通过嵌套其它Widget来构建UI,在构建过程中会递归的构建其嵌套的WidgetWidget build(BuildContext context) {//嵌套 MaterialApp:封装了应用程序实现Material Design所需要的一些widgetreturn MaterialApp(title: "Widget演示", //标题,显示在recent时候的标题//主页面//Scaffold : Material Design布局结构的基本实现。home: Scaffold(//ToolBar/ActionBarappBar: AppBar(title: Text("Widget")),body: Text("Hello,Flutter!"),));}
}

Material Design:

一种设计语言,Material Design 于2014年的 Google I/O 首次亮相,是谷歌推出的全新的设计语言。说白了,就是一种设计风格。

Stateful Widget

​ StatefulWidget是动态的,添加了一个新的接口createState()用于创建和Stateful widget相关的状态State,它在Stateful widget的生命周期中可能会被多次调用。

​ 当State被改变时,可以手动调用其setState()方法通知Flutter framework状态发生改变,Flutter framework在收到消息后,会重新调用其build方法重新构建widget树,从而达到更新UI的目的。

class StatefulState extends State<StatefulApp> {int _i;///当Widget第一次插入到Widget树时会被调用,对于每一个State对象,Flutter framework只会调用一次该回调void initState() {super.initState();_i = 1;}Widget build(BuildContext context) {return MaterialApp(title: "Widget演示",theme: ThemeData(),home: Scaffold(appBar: AppBar(title: Text("Widget")),body: RaisedButton(onPressed: () {//修改状态,setState会重新调用build更新uisetState(() {_i++;});},child: Text("Hello,Flutter! $_i"),),));}
}

State生命周期

​ State类除了build之外还提供了很多方法能够让我们重写,这些方法会在不同的状态下由Flutter调起执行,所以这些方法我们就称之为生命周期方法。

import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatefulWidget {_MyAppState createState() => _MyAppState();
}class _MyAppState extends State<MyApp> {bool isShowChild;///当Widget第一次插入到Widget树时会被调用,对于每一个State对象,Flutter framework只会调用一次该回调void initState() {super.initState();isShowChild = true;debugPrint("parent initState......");}///初始化时,在initState()之后立刻调用///当依赖的InheritedWidget rebuild,会触发此接口被调用void didChangeDependencies() {super.didChangeDependencies();debugPrint("parent didChangeDependencies......");}///绘制界面,当setState触发的时候会再次被调用Widget build(BuildContext context) {debugPrint("parent build......");return MaterialApp(home: Scaffold(body: Center(child: RaisedButton(onPressed: () {setState(() {isShowChild = !isShowChild;});},child: isShowChild ? Child() : Text("演示移除Child"),)),),);}///状态改变的时候会调用该方法,比如调用了setStatevoid didUpdateWidget(MyApp oldWidget) {super.didUpdateWidget(oldWidget);debugPrint("parent didUpdateWidget......");}///当State对象从树中被移除时,会调用此回调void deactivate() {super.deactivate();debugPrint('parent deactivate......');}///当State对象从树中被永久移除时调用;通常在此回调中释放资源void dispose() {super.dispose();debugPrint('parent dispose......');}
}class Child extends StatefulWidget {_ChildState createState() => _ChildState();
}class _ChildState extends State<Child> {Widget build(BuildContext context) {debugPrint("child build......");return Text('lifeCycle');}void initState() {super.initState();debugPrint("child initState......");}///初始化时,在initState()之后立刻调用///当依赖的InheritedWidget rebuild,会触发此接口被调用void didChangeDependencies() {super.didChangeDependencies();debugPrint("child didChangeDependencies......");}///父widget状态改变的时候会调用该方法,比如父节点调用了setStatevoid didUpdateWidget(Child oldWidget) {super.didUpdateWidget(oldWidget);debugPrint("child didUpdateWidget......");}///当State对象从树中被移除时,会调用此回调void deactivate() {super.deactivate();debugPrint('child deactivate......');}///当State对象从树中被永久移除时调用;通常在此回调中释放资源void dispose() {super.dispose();debugPrint('child dispose......');}
}

执行的输出结果显示为:

  • 运行到显示
I/flutter (22218): parent initState......
I/flutter (22218): parent didChangeDependencies......
I/flutter (22218): parent build......
I/flutter (22218): child initState......
I/flutter (22218): child didChangeDependencies......
I/flutter (22218): child build......
  • 点击按钮会移除Child
I/flutter (22218): parent build......
I/flutter (22218): child deactivate......
I/flutter (22218): child dispose......
  • 将MyApp的代码由 child: isShowChild ? Child() : Text("演示移除Child"),改为 child: Child(),点击按钮时
I/flutter (22765): parent build......
I/flutter (22765): child didUpdateWidget......
I/flutter (22765): child build......

从这些实验中能够得出State的生命周期为:

在这里插入图片描述

基础widget

文本显示

Text

Text是展示单一格式的文本Widget(Android TextView)。

import 'package:flutter/material.dart';///
/// main方法 调用runApp传递Widget,这个Widget成为widget树的根
void main() => runApp(TextApp());///
/// 1、单一文本Text
///
//创建一个无状态的Widget
class TextApp extends StatelessWidget {Widget build(BuildContext context) {//封装了应用程序实现Material Design所需要的一些widgetreturn MaterialApp(title: "Text演示", //标题,显示在recent时候的标题//主页面//Scaffold : Material Design布局结构的基本实现。home: Scaffold(//ToolBar/ActionBarappBar: AppBar(title: Text("Text")),body: Text("Hello,Flutter"),),);}
}

在使用Text显示文字时候,可能需要对文字设置各种不同的样式,类似Android的 android:textColor/Size

在Flutter中也拥有类似的属性

Widget _TextBody() {return Text("Hello,Flutter",style: TextStyle(//颜色color: Colors.red,//字号 默认14fontSize: 18,//粗细fontWeight: FontWeight.w800,//斜体fontStyle: FontStyle.italic,//underline:下划线,overline:上划线,lineThrough:删除线decoration: TextDecoration.lineThrough,decorationColor: Colors.black,//solid:实线,double:双线,dotted:点虚线,dashed:横虚线,wavy:波浪线decorationStyle: TextDecorationStyle.wavy),);
}class TextApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: "Text演示", home: Scaffold(appBar: AppBar(title: Text("Text")),body: _TextBody(),),);}
}

RichText

如果需要显示更为丰富样式的文本(比如一段文本中文字不同颜色),可以使用RichText或者Text.rich

Widget _RichTextBody() {var textSpan = TextSpan(text: "Hello",style: TextStyle(color: Colors.red),children: [TextSpan(text: "Flu", style: TextStyle(color: Colors.blue)),TextSpan(text: "uter", style: TextStyle(color: Colors.yellow)),],);//Text.rich(textSpan);return RichText(text: textSpan);
}

DefaultTextStyle

​ 在widget树中,文本的样式默认是可以被继承的,因此,如果在widget树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式。相当于在Android中定义 Theme

Widget _DefaultStyle(){DefaultTextStyle(//设置文本默认样式style: TextStyle(color:Colors.red,fontSize: 20.0,),textAlign: TextAlign.start,child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[Text("Hello Flutter!"),Text("Hello Flutter!"),Text("Hello Flutter!",style: TextStyle(inherit: false, //不继承默认样式color: Colors.grey),),],),);
}

图片显示

“图文”:有文字显示Widget,又怎么少的了图片呢。

FlutterLogo

​ 这个Widget用于显示Flutter的logo…

Widget flutterLogo() {return FlutterLogo(//大小size: 100,//logo颜色 默认为 Colors.bluecolors: Colors.red,//markOnly:只显示logo,horizontal:logo右边显示flutter文字,stacked:logo下面显示文字style: FlutterLogoStyle.stacked,//logo上文字颜色textColor: Colors.blue,);
}

Icon

主要用于显示内置图标的Widget

Widget icon() {return Icon(//使用预定义Material icons// https://docs.flutter.io/flutter/material/Icons-class.htmlIcons.add,size: 100,color: Colors.red);
}

Image

显示图片的Widget。图片常用的格式主要有bmp,jpg,png,gif,webp等,Android中并不是天生支持gif和webp动图,但是这一特性在flutter中被很好的支持了。

方式解释
Image()使用ImageProvider提供图片,如下方法本质上也是使用的这个方法
Image.asset加载资源图片
Image.file加载本地图片文件
Image.network加载网络图片
Image.memory加载内存图片
Iamge.asset

在工程目录下创建目录,如:assets,将图片放入此目录。打开项目根目录:pubspec.yaml

在这里插入图片描述

return MaterialApp(title: "Image演示",home: Scaffold(appBar: AppBar(title: Text("Image")),body: Image.asset("assets/banner.jpeg"),),);
Image.file

在sd卡中放入一张图片。然后利用path_provider库获取sd卡根目录(Dart库版本可以在:https://pub.dartlang.org/packages查询)。

在这里插入图片描述

注意权限

class ImageState extends State<ImageApp> {Image image;void initState() {super.initState();getExternalStorageDirectory().then((path) {setState(() {image = Image.file(File("${path.path}${Platform.pathSeparator}banner.jpeg"));});});}Widget build(BuildContext context) {return MaterialApp(title: "Image演示",home: Scaffold(appBar: AppBar(title: Text("Image")),body: image,),);}
}
Image.network

直接给网络地址即可。

Flutter 1.0,加载https时候经常出现证书错误。必须断开AS打开app

Image.memory
Future<List<int>> _imageByte() async {String path = (await getExternalStorageDirectory()).path;return await File("$path${Platform.pathSeparator}banner.jpeg").readAsBytes();
}class ImageState extends State<ImageApp> {Image image;void initState() {super.initState();_imageByte().then((bytes) {setState(() {image = Image.memory(bytes);});});}Widget build(BuildContext context) {return MaterialApp(title: "Image演示",home: Scaffold(appBar: AppBar(title: Text("Image")),body: image,),);}
}

fit属性相当于android中的scaletype,定义如下:

fit说明效果
BoxFit.fill填充,忽略原有的宽高比,填满为止[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Rnxejq9-1690637402334)(图片/基础Widget_Image_Fill.png)]
BoxFit.contain包含,不改变原有比例让容器包含整个图片,容器多余部分填充背景[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q33jpCMX-1690637402335)(图片/基础Widget_Image_Contain.png)]
BoxFit.cover覆盖,不改变原有比例,让图片充满整个容器,图片多余部分裁剪[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RawRtrsg-1690637402335)(图片/基础Widget_Image_Cover.png)]
BoxFit.fitWidth横向图片填充[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x2CnXYnj-1690637402335)(图片/基础Widget_Image_FitWidth.png)]
BoxFit.fitHeight纵向图片填充[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zu8quSyE-1690637402336)(图片/基础Widget_Image_FitHeight.png)]
BoxFit.none原始大小居中[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tnW2XX4w-1690637402336)(图片/基础Widget_Image_none.png)]
BoxFit.scaleDown图片大小小于容器事相当于none,图片大小大于容器时缩小图片大小实现contain[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IDbz5R3F-1690637402336)(图片/基础Widget_Image_ScaleDown.png)]

CircleAvatar

主要用来显示用户的头像,任何图片都会被剪切为圆形。

CircleAvatar(//图片提供者 ImageProviderbackgroundImage: AssetImage("assets/banner.jpeg"),//半径,控制大小radius: 50.0,);

FadeInImage

当使用默认Image widget显示图片时,您可能会注意到它们在加载完成后会直接显示到屏幕上。这可能会让用户产生视觉突兀。如果最初显示一个占位符,然后在图像加载完显示时淡入,我们可以使用FadeInImage来达到这个目的!

 image =  FadeInImage.memoryNetwork(placeholder: kTransparentImage,image: 'https://flutter.io/images/homepage/header-illustration.png',);

按钮

Material widget库中提供了多种按钮Widget如RaisedButton、FlatButton、OutlineButton等,它们都是直接或间接对RawMaterialButton的包装定制,所以他们大多数属性都和RawMaterialButton一样。所有Material 库中的按钮都有如下相同点:

  1. 按下时都会有“水波动画”。
  2. 有一个onPressed属性来设置点击回调,当按钮按下时会执行该回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。

RaisedButton

"漂浮"按钮,它默认带有阴影和灰色背景

RaisedButton(child: Text("normal"),onPressed: () => {},)

FlatButton

扁平按钮,默认背景透明并不带阴影

FlatButton(child: Text("normal"),onPressed: () => {},
)

OutlineButton

默认有一个边框,不带阴影且背景透明。

OutlineButton(child: Text("normal"),onPressed: () => {},
)

IconButton

可点击的Icon

IconButton(icon: Icon(Icons.thumb_up),onPressed: () => {},
)

按钮外观可以通过其属性来定义,不同按钮属性大同小异

const FlatButton({...   this.onPressed, //按钮点击回调this.textColor, //按钮文字颜色this.disabledTextColor, //按钮禁用时的文字颜色this.color, //按钮背景颜色this.disabledColor,//按钮禁用时的背景颜色this.highlightColor, //按钮按下时的背景颜色this.splashColor, //点击时,水波动画中水波的颜色this.colorBrightness,//按钮主题,默认是浅色主题 this.padding, //按钮的填充this.shape, //外形 this.child, //按钮的内容
})FlatButton(onPressed: () => {},child: Text("Raised"),//蓝色color: Colors.blue,//水波splashColor: Colors.yellow,//深色主题,这样文字颜色会变成白色colorBrightness: Brightness.dark,//圆角按钮shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
)

RaisedButton,默认配置有阴影,因此在配置RaisedButton 时,拥有一系列 elevation 属性的配置

const RaisedButton({...this.elevation = 2.0, //正常状态下的阴影this.highlightElevation = 8.0,//按下时的阴影this.disabledElevation = 0.0,// 禁用时的阴影...
}

输入框

import 'package:flutter/material.dart';void main() => runApp(Demo1());class Demo1 extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: "Demo1",home: Scaffold(appBar: AppBar(title: Text("登录"),),//线性布局,垂直方向body: Column(children: <Widget>[TextField(//自动获得焦点autofocus: true,decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",prefixIcon: Icon(Icons.person)),),TextField(//隐藏正在编辑的文本obscureText: true,decoration: InputDecoration(labelText: "密码",hintText: "您的登录密码",prefixIcon: Icon(Icons.lock)),),],),),);}
}

这个效果非常的“系统”,我们可能大多数情况下需要将下划线更换为矩形边框,这时候可能就需要组合widget来完成:

//容器 设置一个控件的尺寸、背景、margin 
Container(margin: EdgeInsets.all(32),child: TextField(keyboardType: TextInputType.emailAddress,decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",prefixIcon: Icon(Icons.person),border: InputBorder.none //隐藏下划线)),//装饰decoration: BoxDecoration(// 边框浅灰色,宽度1像素border: Border.all(color: Colors.red[200], width: 1.0),//圆角borderRadius: BorderRadius.circular(5.0),),)

焦点控制

​ FocusNode: 与Widget绑定,代表了这个Widget的焦点

​ FocusScope: 焦点控制范围

​ FocusScopeNode:控制焦点

class _TextFocusState extends State<TextFocusWidget> {FocusNode focusNode1 = new FocusNode();FocusNode focusNode2 = new FocusNode();void _listener() {debugPrint("用户名输入框焦点:${focusNode1.hasFocus}");}void initState() {super.initState();//监听焦点状态改变事件focusNode1.addListener(_listener);}void dispose() {super.dispose();focusNode1.dispose();focusNode2.dispose();}Widget build(BuildContext context) {return Column(children: <Widget>[TextField(autofocus: true,//关联焦点focusNode: focusNode1,//设置键盘动作为: 下一步textInputAction: TextInputAction.next,//点击下一步执行回调onEditingComplete: () {//获得 context对应UI树的焦点范围 的焦点控制器FocusScopeNode focusScopeNode = FocusScope.of(context);//将焦点交给focusNode2focusScopeNode.requestFocus(focusNode2);},decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",prefixIcon: Icon(Icons.person)),),TextField(//隐藏正在编辑的文本obscureText: true,focusNode: focusNode2,decoration: InputDecoration(labelText: "密码",hintText: "您的登录密码",prefixIcon: Icon(Icons.lock)),),custom(),],);}
}

获取输入内容

获取输入内容有两种方式:

  1. 定义两个变量,用于保存用户名和密码,然后在onChange触发时,各自保存一下输入内容。
  2. 通过controller直接获取。

onChange获得输入内容:

TextField(onChanged: (s) => debugPrint("ssss:$s"),)

controller获取:

定义一个controller:

//定义一个controller
TextEditingController _unameController=new TextEditingController();

然后设置输入框controller:

TextField(controller: _unameController, //设置controller...
)

通过controller获取输入框内容

debugPrint(_unameController.text)

TextFormField

TextFormFieldTextField多了一些属性,其中 validator用于设置验证回调。在单独使用时与TextField没有太大的区别。当结合From,利用From可以对输入框进行分组,然后进行一些统一操作(验证)

class _TextFocusState extends State<TextFocusWidget> {//全局keyGlobalKey<FormState> _key = GlobalKey<FormState>();Widget build(BuildContext context) {return Form(//类似 idkey: _key,child: Column(children: <Widget>[TextFormField(autofocus: true,decoration: InputDecoration(labelText: "用户名",hintText: "用户名或邮箱",icon: Icon(Icons.person)),// 校验用户名validator: (v) {return v.trim().length > 0 ? null : "用户名不能为空";}),TextFormField(decoration: InputDecoration(labelText: "密码",hintText: "您的登录密码",icon: Icon(Icons.lock)),// 校验用户名validator: (v) {return v.trim().length > 0 ? null : "密码不能为空";}),RaisedButton(onPressed: () {//Form所有TextFormField成功 返回trueif (_key.currentState.validate()) {}},child: Text("提交"),)],));}
}

相关文章:

Flutter-基础Widget

Flutter页面-基础Widget 文章目录 Flutter页面-基础WidgetWidgetStateless WidgetStateful WidgetState生命周期 基础widget文本显示TextRichTextDefaultTextStyle 图片显示FlutterLogoIconImageIamge.assetImage.fileImage.networkImage.memory CircleAvatarFadeInImage 按钮R…...

【数据分析专栏之Python篇】二、Jupyer Notebook安装配置及基本使用

文章目录 前言一、Jupter Notebook是什么1.1 简介1.2 组成部分1.3 Jupyter Notebook的主要特点 二、为什么使用Jupyter Notebook?三、安装四、Jupyter Notebok配置4.1 基本配置4.2 配置开机自启与后台运行4.3 开启代码自动补全 五、两种键盘输入模式5.1 编辑模式5.2 命令模式5…...

ubuntu22.04 DNSSEC(加密DNS服务) configuration

/etx/systemd/resolved.conf是ubuntu下DNS解析服务配置文件&#xff0c;systemd为ubuntu下system and service配置目录 step 1——修改resolved.conf参数 管理员权限打开 /systemd/resolved.conf sudo nano /etc/systemd/resolved.conf修改如下&#xff1a; # This file i…...

Qt 第一讲

登录框设置 #include "zuoye.h" #include "ui_zuoye.h"Zuoye::Zuoye(QWidget *parent): QWidget(parent), ui(new Ui::Zuoye) {ui->setupUi(this);//界面this->resize(540,420); //设置尺寸this->setFixedSize(540,420);//固定尺寸this->setS…...

IDEA 使用 maven 搭建 spring mvc

1. 创建项目 1.1 创建成功之后配置 Spring MVC 1.2 勾选 Spring MVC 2.更改配置文件 2.1 更改web.xml配置 更改为 <servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/</url-pattern></servlet-mapping>2.2 dispat…...

Hi3536网络应用调优

目录 1. 为什么UDP接收或发送会丢包? 2. 使用 socket 接口时&#xff0c;如何正确工作在非阻塞模式下&#xff1f; 3. TOE 使能及使用注意事项 4. TOE 模式下使用 socket 接口时的注意事项 1. 为什么UDP接收或发送会丢包? 用户态应用程序在接收 UDP 数据时&#xff0…...

spring拦截器 与统一格式

目录 前言模拟拦截器拦截器的实现原理什么是动态代理? 什么是静态代理静态代理与动态代理的区别两种常用的动态代理方式基于接口的动态代理基于类的动态代理 JDK Proxy 与 CGlib的区别 其他 统⼀访问前缀添加统⼀异常处理统⼀数据返回格式 前言 之前博客讲述了 , 关于SpringA…...

leetcode 122. 买卖股票的最佳时机 II

2023.7.29 把整体利润拆分成每天的利润&#xff0c;将股票值想象成一个折线图&#xff0c;将所有上升的值相加即可。 代码&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int ans 0;for(int i1; i<prices.size(); i){if(prices[i]-…...

代理模式:控制访问的设计模式

代理模式&#xff1a;控制访问的设计模式 什么是代理模式&#xff1f; 代理模式是一种常见的设计模式&#xff0c;它允许通过代理对象来控制对真实对象的访问。代理模式的主要目的是在不改变原始对象的情况下&#xff0c;提供额外的功能或控制访问。 为什么要使用代理模式&a…...

2020/7/30

Educational Codeforces Round 143 (Rated for Div. 2)\C_Tea_Tasting.cpp //题意&#xff1a;有n种茶&#xff0c;n个人&#xff0c;第i种茶有 a[i]的量&#xff0c;第i个人一次能喝 b[i], 第i个人从第i种茶开始往前喝&#xff0c;求每个人最多能喝多少茶。 //思路&#xff…...

图形编辑器开发:是否要像 Figma 一样上 wasm

大家好&#xff0c;我是前端西瓜哥。 wasm 拿来做 Web 端的图形编辑器貌似是不错的选择。 因为图形处理会有相当多无法利用到 WebGL GPU 加速的 CPU 密集的计算。比如对一条复杂贝塞尔曲线进行三角化&#xff0c;对多个图形进行复杂图形的布尔运算。 图形编辑器性能天花板 F…...

Linux学成之路(基础篇0(二十三)MySQL服务(主从MySQL服务和读写分离——补充)

目录 一、MySQL Replication概述 优点 异步复制&#xff08;Asynchronous repication&#xff09; 全同步复制&#xff08;Fully synchronous replication&#xff09; 半同步复制&#xff08;Semisynchronous replication&#xff09; 三、MySQL支持的复制 四、部署主从…...

spring启动流程 (6完结) springmvc启动流程

SpringMVC的启动入口在SpringServletContainerInitializer类&#xff0c;它是ServletContainerInitializer实现类(Servlet3.0新特性)。在实现方法中使用WebApplicationInitializer创建ApplicationContext、创建注册DispatcherServlet、初始化ApplicationContext等。 SpringMVC…...

设计模式-中介者模式在Java中使用示例-客户信息管理

场景 欲开发客户信息管理窗口界面&#xff0c;界面组件之间存在较为复杂的交互关系&#xff1a;如果删除一个客户&#xff0c; 要在客户列表(List)中删掉对应的项&#xff0c;客户选择组合框(ComboBox)中客户名称也将减少一个&#xff1b; 如果增加一个客户信息&#xff0c;…...

14443-1-doc

介绍 ISO/IEC 14443 是描述 ISO/IEC 7810 中定义的身份证参数以及此类卡在国际交换中的使用的一系列国际标准之一。 ISO/IEC 14443 的这一部分描述了感应卡的物理特性。 ISO/IEC 14443 的这一部分并不排除在卡上纳入其他标准技术&#xff0c;例如资料性附录 A 中引用的技术。非…...

SpringBoot的三层架构以及IOCDI

目录 一、IOC&DI入门 二、三层架构 数据库访问层 业务逻辑层 控制层 一、IOC&DI入门 在软件开发中&#xff0c;IOC&#xff08;Inversion of Control&#xff09;和DI&#xff08;Dependency Injection&#xff09;是密切相关的概念。 IOC&#xff08;控制反转&a…...

RabbitMQ部署指南

RabbitMQ部署指南 1.单机部署 我们在Centos7虚拟机中使用Docker来安装。 1.1.下载镜像 方式一&#xff1a;在线拉取 docker pull rabbitmq:3-management方式二&#xff1a;从本地加载 已经提供了镜像包&#xff1a; 上传到虚拟机中后&#xff0c;使用命令加载镜像即可&…...

【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?

文章目录 前言声明和初始化扩容时机源码分析go1.17go1.18内存对齐 总结 前言 在 Go 语言中&#xff0c;有一个很常用的数据结构&#xff0c;那就是切片&#xff08;Slice&#xff09;。 切片是一个拥有相同类型元素的可变长度的序列&#xff0c;它是基于数组类型做的一层封装…...

【数据结构】顺序表(SeqList)(增、删、查、改)详解

一、顺序表的概念和结构 1、顺序表的概念&#xff1a; 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组上完成数据的增删查改。 2、顺序表的结构&#xff1a; &#xff08;1&#xff09;静态顺序表&#xff1a;使…...

[golang gin框架] 42.Gin商城项目-微服务实战之后台Rbac微服务角色增删改查微服务

一.重构后台Rbac用户登录微服务功能 上一节讲解了后台Rbac微服务用户登录功能以及Gorm数据库配置单独抽离&#xff0c;Consul配置单独抽离&#xff0c;这一节讲解后台Rbac微服务角色增删改查微服务功能&#xff0c;Rbac微服务角色增删改查微服务和后台Rbac用户登录微服务是属于…...

项目篇:Echo论坛系统项目

一、登录注册模块 1、注册功能 1.1、注册流程图 1.2、注册代码 /*** 用户注册* param user* return Map<String, Object> 返回错误提示消息&#xff0c;如果返回的 map 为空&#xff0c;则说明注册成功*/public Map<String, Object> register(User user) {Map&l…...

数据可视化(2)

1.柱状图 #柱状图 #bar(x,height,width,*,aligncenter,**kwargs) #height柱子的高度&#xff0c;即y轴上的数据 #width数组的宽度&#xff0c;默认值0.8 #*表示后面的参数为匿名关键字&#xff0c;必须传入参数 #kwargs关键字参数x[1,2,3,4,5] height[random.randint(10,100)f…...

MD-MTSP:斑马优化算法ZOA求解多仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)

一、斑马优化算法ZOA 斑马优化算法&#xff08;Zebra Optimization Algorithm&#xff0c;ZOA&#xff09;Eva Trojovsk等人于2022年提出&#xff0c;其模拟斑马的觅食和对捕食者攻击的防御行为。斑马优化算法&#xff08;Zebra Optimization Algorithm&#xff0c;ZOA&#x…...

【笔试强训选择题】Day32.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01; 文章目录 前言 一、Da…...

抖音seo账号矩阵系统源码如何开发布局?

目录 一、 抖音SEO账号矩阵系统源码的开发布局步骤如下&#xff1a; 二。 开发部署源码 三、 开发部署功能设计 1. 短视频AI智能创作 2. 托管式账号管理: 3. 数据分析 4. 智能营销获客 四。 抖音seo源码开发部署交付技术文档包含 五。 开发代码展示&#xff1a; 一、 抖…...

vue项目cdn打包优化

0.用vue ui可以查看项目打包后的情况。 1.定义包的排除 let externals {axios: axios,element-ui: ELEMENT,echarts: echarts,} configureWebpack: {externals: externals }2.配置cdn包资源 // 配置 let cdn {css: [// element-ui csshttps://unpkg.com/element-ui/lib/th…...

Android 之 MediaPlayer 播放音频与视频

本节引言&#xff1a; 本节带来的是Android多媒体中的——MediaPlayer&#xff0c;我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件&#xff0c;通过该类&#xff0c;我们可以以最小的步骤来获取&#xff0c;解码 和播放音视频。它支持三种不同的…...

React中事件处理器的基本使用

在React中&#xff0c;为了提高性能&#xff0c;跨浏览器兼容性和开发体验&#xff0c;React实现了一套自己的事件机制&#xff0c;利用事件委托和合成事件的方式统一管理事件订阅和分发。 为了让组件能够响应用户的交互行为&#xff0c;React提供了一系列的事件处理器&#xf…...

RobotFramework

一、RobotFramework的简介和特点 1、关键字驱动&#xff1a; 把项目中的业务逻辑封装成一个一个的关键字&#xff0c;然后调用不同的关键字组成不同的业务 2、数据驱动 把测试数据放到excel&#xff1a;yaml文件中 通过改变文件中的数据去驱动测试用例执行 3、特点&#xff…...

【Matplotlib 绘制折线图】

使用 Matplotlib 绘制折线图 在数据可视化中&#xff0c;折线图是一种常见的图表类型&#xff0c;用于展示随着变量的变化&#xff0c;某个指标的趋势或关系。Python 的 Matplotlib 库为我们提供了方便易用的功能来绘制折线图。 绘制折线图 下面的代码展示了如何使用 Matplo…...

公司网站建设工作内容/一个新产品的营销方案

注意&#xff0c;这是公司内部一位同事整理的&#xff0c;我经过这位老兄(http://hi.csdn.net/fullsail)的同意&#xff0c;把他转到我的blog。原文英文地址&#xff1a; http://www.mvdirona.com/jrh/talksAndPapers/JamesRH_Lisa.pdf 网上应该只能找到(上)和(中)&#xff0c;…...

合肥做公司网站一般多少钱/怎么推广公司网站

虚拟存储需求背景&#xff1a; 虚拟存储是在这个非连续存储内存分配的基础上&#xff0c;可以把一部分内容放在外村里的做法 理想的存储器&#xff1a; 容量更大&#xff0c;速度更快&#xff0c;价格更便宜的非易失性存储器 交换技术&#xff1a; 增加正在运行或者需要运…...

windows10 wordpress/谷歌商店paypal下载官网

1.spring boot日志概述spring boot使用Commons Logging作为内部的日志系统&#xff0c;并且给Java Util Logging&#xff0c;Log4J2以及Logback都提供了默认的配置。如果使用了spring boot的Starters&#xff0c;那么默认会使用Logback用于记录日志。2.spring boot日志默认配置…...

网站做长尾词好还是单个词好/ai智能搜索引擎

作者&#xff1a;Flyingis 提升ArcGIS Server访问速度最佳的方式是Cache&#xff0c;将所有图层切片保存在服务器&#xff0c;客户端请求时直接访问cache好的图片&#xff0c;这里分为两种情况&#xff0c;一是所有图层都做cache&#xff0c;二是部分图层做cache&#xff0…...

企业网站的类型包括/长沙seo网站推广

谈判中最重要也是最艰难的一幕就是谈判中的较量&#xff0c;前期哪怕做了很多准备&#xff0c;如果在这个实际运作中把握不住&#xff0c;也往往前功尽弃。 现实生活中&#xff0c;我们基本上每天都在进行谈判&#xff0c;只不过是形式有所不同而已&#xff0c;谈判也往往涉及到…...

wordpress网址更换/杭州网站制作排名

哲学家就餐问题问题描述哲学家就餐问题(Dining philosophers problem)可以这样表述&#xff0c;假设有五位哲学家围坐在一张圆形餐桌旁&#xff0c;做以下两件事情之一&#xff1a;吃饭&#xff0c;或者思考。吃东西的时候&#xff0c;他们就停止思考&#xff0c;思考的时候也停…...