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
StatelessWidget
和StatefulWidget
是flutter
的基础组件,日常开发中自定义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 库中的按钮都有如下相同点:
- 按下时都会有“水波动画”。
- 有一个
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(),],);}
}
获取输入内容
获取输入内容有两种方式:
- 定义两个变量,用于保存用户名和密码,然后在onChange触发时,各自保存一下输入内容。
- 通过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
TextFormField
比TextField
多了一些属性,其中 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解析服务配置文件,systemd为ubuntu下system and service配置目录 step 1——修改resolved.conf参数 管理员权限打开 /systemd/resolved.conf sudo nano /etc/systemd/resolved.conf修改如下: # 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 接口时,如何正确工作在非阻塞模式下? 3. TOE 使能及使用注意事项 4. TOE 模式下使用 socket 接口时的注意事项 1. 为什么UDP接收或发送会丢包? 用户态应用程序在接收 UDP 数据时࿰…...

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

leetcode 122. 买卖股票的最佳时机 II
2023.7.29 把整体利润拆分成每天的利润,将股票值想象成一个折线图,将所有上升的值相加即可。 代码: class Solution { public:int maxProfit(vector<int>& prices) {int ans 0;for(int i1; i<prices.size(); i){if(prices[i]-…...
代理模式:控制访问的设计模式
代理模式:控制访问的设计模式 什么是代理模式? 代理模式是一种常见的设计模式,它允许通过代理对象来控制对真实对象的访问。代理模式的主要目的是在不改变原始对象的情况下,提供额外的功能或控制访问。 为什么要使用代理模式&a…...
2020/7/30
Educational Codeforces Round 143 (Rated for Div. 2)\C_Tea_Tasting.cpp //题意:有n种茶,n个人,第i种茶有 a[i]的量,第i个人一次能喝 b[i], 第i个人从第i种茶开始往前喝,求每个人最多能喝多少茶。 //思路ÿ…...

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

Linux学成之路(基础篇0(二十三)MySQL服务(主从MySQL服务和读写分离——补充)
目录 一、MySQL Replication概述 优点 异步复制(Asynchronous repication) 全同步复制(Fully synchronous replication) 半同步复制(Semisynchronous replication) 三、MySQL支持的复制 四、部署主从…...

spring启动流程 (6完结) springmvc启动流程
SpringMVC的启动入口在SpringServletContainerInitializer类,它是ServletContainerInitializer实现类(Servlet3.0新特性)。在实现方法中使用WebApplicationInitializer创建ApplicationContext、创建注册DispatcherServlet、初始化ApplicationContext等。 SpringMVC…...

设计模式-中介者模式在Java中使用示例-客户信息管理
场景 欲开发客户信息管理窗口界面,界面组件之间存在较为复杂的交互关系:如果删除一个客户, 要在客户列表(List)中删掉对应的项,客户选择组合框(ComboBox)中客户名称也将减少一个; 如果增加一个客户信息,…...
14443-1-doc
介绍 ISO/IEC 14443 是描述 ISO/IEC 7810 中定义的身份证参数以及此类卡在国际交换中的使用的一系列国际标准之一。 ISO/IEC 14443 的这一部分描述了感应卡的物理特性。 ISO/IEC 14443 的这一部分并不排除在卡上纳入其他标准技术,例如资料性附录 A 中引用的技术。非…...

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

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

【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?
文章目录 前言声明和初始化扩容时机源码分析go1.17go1.18内存对齐 总结 前言 在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice)。 切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装…...

【数据结构】顺序表(SeqList)(增、删、查、改)详解
一、顺序表的概念和结构 1、顺序表的概念: 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。 2、顺序表的结构: (1)静态顺序表:使…...

[golang gin框架] 42.Gin商城项目-微服务实战之后台Rbac微服务角色增删改查微服务
一.重构后台Rbac用户登录微服务功能 上一节讲解了后台Rbac微服务用户登录功能以及Gorm数据库配置单独抽离,Consul配置单独抽离,这一节讲解后台Rbac微服务角色增删改查微服务功能,Rbac微服务角色增删改查微服务和后台Rbac用户登录微服务是属于…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...