Flutter 实现验证码输入框学习
学习flutter代码 实现一个用于输入验证码的自定义组件,它允许用户输入固定长度的验证码,并在输入完成时触发回调。
前置知识点学习
TextStyle
`TextStyle` 是 Flutter 中用于定义文本样式的类。它提供了一组属性来控制文本的外观,如字体大小、颜色、粗细、字间距等。`TextStyle` 是 Flutter 应用中处理文本样式的核心部分,通过它可以实现丰富的文本展示效果。
`TextStyle` 的主要属性
1.`color`: 设置文本的颜色。可以使用 `Colors` 类提供的颜色常量或自定义颜色。
2.`fontSize`: 设置文本的字号大小,以逻辑像素为单位。
3.`fontWeight`: 定义文本的粗细程度。可以使用 `FontWeight` 枚举,如 `FontWeight.bold`。
4.`fontStyle`: 设置文本的样式(正常或斜体)。可以使用 `FontStyle` 枚举,如 `FontStyle.italic`。
5.`letterSpacing`: 设置字母之间的间距。
6.`wordSpacing`: 设置单词之间的间距。
7.`fontFamily`: 指定文本所使用的字体系列。可以是系统字体,也可以是自定义字体。
8.`backgroundColor`: 文本的背景颜色。
9.`decoration`: 为文本添加装饰,如下划线、上划线或删除线。可以使用 `TextDecoration` 枚举。
10.`decorationColor`: 文本装饰的颜色。
11.`decorationStyle`: 定义装饰线的样式,如实线、虚线等。可以使用 `TextDecorationStyle` 枚举。
12.`height`: 行高,相对于字体大小的倍数。
示例代码
以下是一个使用 `TextStyle` 的示例,展示了如何应用各种样式属性:
import 'package:flutter/material.dart';class TextStyleExample extends StatelessWidget {const TextStyleExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('TextStyle Example'),),body: const Center(child: Text('Hello, Flutter!',style: TextStyle(color: Colors.blue,fontSize: 24.0,fontWeight: FontWeight.bold,fontStyle: FontStyle.italic,letterSpacing: 2.0,wordSpacing: 4.0,fontFamily: 'Roboto',decoration: TextDecoration.underline,decorationColor: Colors.red,decorationStyle: TextDecorationStyle.dashed,),),),);}}
代码解析
- 颜色与大小:`color: Colors.blue` 和 `fontSize: 24.0` 分别设置了文本的颜色和字号。
- 字体粗细与样式:使用 `fontWeight: FontWeight.bold` 使文本加粗,`fontStyle: FontStyle.italic` 设置为斜体。
- 字间距与单词间距:`letterSpacing: 2.0` 增加字母间距,`wordSpacing: 4.0` 增加单词间距。
- 字体系列:`fontFamily: 'Roboto'` 指定文本使用 Roboto 字体系列。
- 文本装饰:`decoration: TextDecoration.underline` 添加下划线,`decorationColor: Colors.red` 和 `decorationStyle: TextDecorationStyle.dashed` 分别设置装饰线的颜色和样式。
- 字体加载:当使用自定义字体时,确保在 `pubspec.yaml` 文件中正确配置字体资源,并在项目中包含字体文件。这将确保在所有平台上正确加载和显示自定义字体。
flutter:fonts:- family: Robotofonts:- asset: fonts/Roboto-Regular.ttf- asset: fonts/Roboto-Bold.ttfweight: 700
- 性能考虑:在大量文本或频繁更新文本样式的情况下,尽量减少不必要的样式变化,以提高性能。使用相同的 `TextStyle` 实例可以减少构建时间。
- 继承与覆盖:`TextStyle` 支持通过 `copyWith` 方法创建一个新的样式对象,可以在现有样式的基础上进行局部修改:
TextStyle baseStyle = TextStyle(fontSize: 20.0, color: Colors.black);
TextStyle newStyle = baseStyle.copyWith(color: Colors.red);
这在需要在不同部分稍微调整样式时非常有用。
- 样式优先级:如果 `TextStyle` 被应用于 `Text` 小部件,而 `Text` 小部件又嵌套在一个使用 `DefaultTextStyle` 的父小部件中,那么 `Text` 小部件的 `TextStyle` 将覆盖 `DefaultTextStyle` 的样式。
实际应用中的建议
- 使用主题:在大型应用中,使用 `ThemeData` 来统一管理文本样式,可以通过 `Theme.of(context).textTheme` 获取预定义的文本样式。这样可以保持应用风格的一致性。
Text('Themed Text',style: Theme.of(context).textTheme.headline6,
);
- 响应式设计:在处理需要适配不同屏幕尺寸的文本时,可以结合 `MediaQuery` 或使用 `flutter_screenutil` 这样的库,根据屏幕尺寸动态调整 `fontSize`。
- 国际化与本地化:在处理多语言支持时,确保字体和样式可以适应不同的字符集和语言特性。例如,某些语言可能需要更大的行高或不同的字体。
通过对 `TextStyle` 的深入理解,你可以在 Flutter 应用中创建美观、统一且响应式的文本展示效果。它是 Flutter UI 构建中不可或缺的一部分,熟练掌握它将帮助你更好地设计和实现高质量的用户界面。
ClipRRect
`ClipRRect` 是 Flutter 中的一个小部件,用于将其子组件裁剪为圆角矩形的形状。它非常适合在需要为组件添加圆角效果时使用,比如为图片、容器等添加圆角。`ClipRRect` 通过使用 `RRect`(圆角矩形)来定义裁剪的形状。
主要属性
1.`borderRadius`:
- 类型:`BorderRadius`
- 用于定义圆角的半径,可以指定每个角的圆角大小。
- 示例:`BorderRadius.circular(8.0)` 会为所有角设置 8.0 的圆角。
2.`clipBehavior`:
- 类型:`Clip`
- 定义裁剪行为。常用值包括 `Clip.none`、`Clip.hardEdge`、`Clip.antiAlias` 和 `Clip.antiAliasWithSaveLayer`。
- `Clip.antiAlias` 和 `Clip.antiAliasWithSaveLayer` 提供更平滑的边缘,但可能会影响性能。
3.`child`:
- 被裁剪的子组件。可以是任何类型的 Widget。
使用场景
- 应用圆角效果:为图片、按钮、容器等应用圆角效果。
- 嵌套裁剪:在需要复杂形状裁剪的场合,可以结合其他裁剪小部件(如 `ClipOval`)使用。
示例代码
下面是一个简单的 `ClipRRect` 使用示例,将一张图片裁剪为圆角矩形:
import 'package:flutter/material.dart';class ClipRRectExample extends StatelessWidget {const ClipRRectExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('ClipRRect Example'),),body: Center(child: ClipRRect(borderRadius: BorderRadius.circular(16.0),child: Image.asset("static/demo.png",width: 200,height: 200,fit: BoxFit.cover,),),),);}
}
代码解析
- `borderRadius`: 使用 `BorderRadius.circular(16.0)` 为图片的四个角应用了 16.0 的圆角。
- `child`: 包含了一张通过网络加载的图片。`ClipRRect` 将这张图片裁剪成带有圆角的矩形。
性能考虑
- 裁剪性能:使用 `ClipRRect` 时,`clipBehavior` 会影响性能,尤其是在需要抗锯齿或使用 `saveLayer` 时。在性能敏感的场景中,尽可能选择 `Clip.hardEdge`,因为它是最快的选项。
- 避免不必要的裁剪:如果可以通过布局或其他方式实现相同的效果,尽量避免使用 `ClipRRect`,因为裁剪操作会增加渲染开销。
总结
`ClipRRect` 是 Flutter 中用于实现圆角裁剪的强大工具。通过它,可以轻松地为任何组件添加圆角效果,使得应用的视觉效果更加美观和现代。在使用时,需要注意裁剪的性能影响,合理选择裁剪行为以达到最佳的性能和平滑度平衡。
AnimatedContainer
`AnimatedContainer` 是 Flutter 中一个非常有用的小部件,它在属性发生变化时可以自动动画化地过渡到新的属性。这使得创建动画效果和响应式界面变得非常简单,无需手动管理动画控制器或状态。
特性与属性
1.`duration`:
- 类型:`Duration`
- 指定动画过渡的持续时间。必须设置这个属性来定义动画的长短。
- 示例:`Duration(seconds: 1)` 表示动画持续一秒。
2.`curve`:
- 类型:`Curve`
- 定义动画的曲线,决定了动画的加速度和减速度。常用曲线有 `Curves.easeIn`、`Curves.easeOut`、`Curves.bounceIn` 等。
- 示例:`Curves.easeInOut` 表示动画以缓慢的速度开始和结束,但中间速度较快。
3.`alignment`:
- 控制子组件的对齐方式。
4.`padding`:
- 控制内部填充。
5.`color`:
- 背景颜色。
6.`decoration` 和 `foregroundDecoration`:
- `decoration` 用于背景装饰,例如边框、圆角、渐变等。
- `foregroundDecoration` 用于在子组件前的装饰。
7.`width` 和 `height`:
- 控制容器的宽度和高度。
8.`constraints`:
- 设置容器的大小限制,例如最小和最大宽高。
9.`margin`:
- 控制外部间距。
`10.transform`:
- 应用于子组件的变换,例如旋转、缩放、平移等。
11.`child`:
- 被包裹的子组件。
使用场景
- 动画化尺寸变化:在用户交互后,动态调整组件的大小。
- 背景颜色过渡:在状态改变时,平滑地过渡到新的背景颜色。
- 位置和边距动画:在布局中通过调整位置和边距来创建动画效果。
示例代码
import 'package:flutter/material.dart';class AnimatedContainerExample extends StatefulWidget {const AnimatedContainerExample({super.key});@override_AnimatedContainerExampleState createState() {return _AnimatedContainerExampleState();}
}class _AnimatedContainerExampleState extends State<AnimatedContainerExample> {double _width = 100.0;double _height = 100.0;Color _color = Colors.blue;@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('AnimatedContainer Example'),),body: Center(child: GestureDetector(onTap: () {setState(() {_width = _width == 100.0 ? 200.0 : 100.0;_height = _height == 100.0 ? 200.0 : 100.0;_color = _color == Colors.blue ? Colors.red : Colors.blue;});},child: AnimatedContainer(width: _width,height: _height,color: _color,alignment: Alignment.center,duration: const Duration(seconds: 1),curve: Curves.easeInOut,child: const Text('Tap me!',style: TextStyle(color: Colors.white, fontSize: 20.0),),),),),);}
}
BoxDecoration
`BoxDecoration` 是 Flutter 中用于装饰容器(如 `Container`)的一个类。它提供了一系列属性,允许你为容器添加背景颜色、渐变、图像、边框、阴影等装饰效果。`BoxDecoration` 结合 `Container` 使用,可以打造出丰富的视觉效果。
主要属性
1.`color`:
- 类型:`Color`
- 设置容器的背景颜色。
2.`image`:
- 类型:`DecorationImage`
- 用于在容器背景中绘制图像。
- 可以指定图像的对齐方式、填充方式等。
3.`border`:
- 类型:`Border`
- 为容器添加边框。可以指定每条边的宽度和颜色。
4.`borderRadius`:
- 类型:`BorderRadius`
- 设置容器的圆角半径。
5.`boxShadow`:
- 类型:`List`
- 为容器添加阴影效果。可以指定阴影的颜色、偏移、模糊半径等。
6.`gradient`:
- 类型:`Gradient`
- 为容器添加渐变背景。支持线性渐变、径向渐变等。
7.`backgroundBlendMode`:
- 类型:`BlendMode`
- 设置背景颜色和图像的混合模式。
8.`shape`:
- 类型:`BoxShape`
- 指定容器的形状。可以是矩形(默认)或圆形。
使用场景
- 背景颜色和图像:为容器添加背景颜色或图像。
- 边框和圆角:为容器添加边框和圆角效果。
- 阴影效果:为容器添加阴影,提升视觉层次感。
- 渐变背景:使用渐变色为背景,打造现代化的视觉效果。
示例代码
以下是一个使用 `BoxDecoration` 的示例,展示了如何为容器添加背景颜色、圆角、边框和阴影:
import 'package:flutter/material.dart';class BoxDecorationExample22 extends StatelessWidget {const BoxDecorationExample22({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('BoxDecoration Example'),),body: Container(width: 200.0,height: 200.0,decoration: BoxDecoration(color: Colors.blue[200],borderRadius: BorderRadius.circular(20.0),border: Border.all(color: Colors.blue,width: 3.0,),boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.5),spreadRadius: 5,blurRadius: 7,offset: const Offset(0, 3), // changes position of shadow),],),child: const Center(child: Text('Hello, Flutter!',style: TextStyle(color: Colors.white, fontSize: 20.0),),),),);}
}
TextInputFormatter
`TextInputFormatter` 是 Flutter 中用于在用户输入文本时进行格式化和验证的一个抽象类。它允许你在文本被输入到文本字段之前对其进行修改或限制,这对于实现自定义的输入行为(如限制输入类型或长度)非常有用。
主要属性和方法
- `formatEditUpdate`:
- 方法:`TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue)`
- 这是 `TextInputFormatter` 的核心方法,必须被重写。它接收旧的文本值和新的文本值,返回一个格式化后的文本值。
- `TextEditingValue` 包含文本字段的当前状态,包括文本内容、光标位置和选择范围。
常用子类
1.`LengthLimitingTextInputFormatter`:
- 用于限制输入文本的最大长度。
- 构造时传入一个整数表示最大长度。
- 示例:`LengthLimitingTextInputFormatter(10)` 限制输入长度为 10 个字符。
2.`FilteringTextInputFormatter`:
- 用于过滤输入的文本,只允许符合特定模式的输入。
- 提供了 `FilteringTextInputFormatter.digitsOnly` 来限制输入仅为数字。
- 可以通过自定义正则表达式来实现更复杂的过滤。
示例代码
以下是如何使用 `LengthLimitingTextInputFormatter` 和 `FilteringTextInputFormatter` 的示例:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';class TextInputFormatterExampleDemo extends StatelessWidget {const TextInputFormatterExampleDemo({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('TextInputFormatter Example'),),body: Padding(padding: const EdgeInsets.all(16.0),child: Column(children: [TextField(decoration: const InputDecoration(labelText: 'Limited Length (Max 10)',),inputFormatters: [LengthLimitingTextInputFormatter(10),],),const SizedBox(height: 20,),TextField(decoration: const InputDecoration(labelText: 'Digits Only',),keyboardType: TextInputType.number,inputFormatters: [FilteringTextInputFormatter.digitsOnly,],)],),),);}
}
代码解析
- 限制输入长度:第一个文本字段使用 `LengthLimitingTextInputFormatter(10)` 限制输入最大长度为 10 个字符。
- 限制输入内容:第二个文本字段使用 `FilteringTextInputFormatter.digitsOnly` 限制输入仅为数字。
自定义格式化器
你可以通过继承 `TextInputFormatter` 并重写 `formatEditUpdate` 方法来创建自定义的输入格式化器。例如,创建一个格式化器来限制输入只能是大写字母:
class UpperCaseTextInputFormatter extends TextInputFormatter {@overrideTextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {return TextEditingValue(text: newValue.text.toUpperCase(),selection: newValue.selection,);}
}
使用场景
- 限制输入的类型和格式(例如,只允许字母、数字或特定符号)。
- 验证用户输入的格式是否符合特定规则(如电子邮件、电话号码)。
- 动态调整用户输入,使其符合特定格式。
TextField
`TextField` 是 Flutter 中用于获取用户文本输入的一个重要组件。它提供了强大的功能和高度的可定制性,使开发者能够轻松地集成和管理用户输入。下面是对 `TextField` 的详细解析。
基本特性
1.文本输入:`TextField` 是用于用户输入文本的基本组件。
2.键盘类型:可以通过 `keyboardType` 属性设置输入时弹出的键盘类型,例如数字键盘、邮件键盘等。
3.样式和装饰:通过 `decoration` 属性可以自定义 `TextField` 的外观,包括提示文本、边框、标签等。
4.控制器:使用 `TextEditingController` 来管理和监听文本输入的变化。
5.输入格式化:使用 `inputFormatters` 来限制和格式化用户输入,例如限制输入长度或只允许数字输入。
6.焦点控制:通过 `FocusNode` 可以控制和监听 `TextField` 的焦点状态。
主要属性
- controller: `TextEditingController` 用于读取、设置和监听 `TextField` 的文本。
- focusNode: `FocusNode` 用于管理和监听焦点状态。
- decoration: `InputDecoration` 用于定义 `TextField` 的外观和样式。
- keyboardType: `TextInputType` 确定输入时使用的键盘类型。
- textInputAction: `TextInputAction` 确定操作按钮的类型,如“下一步”或“完成”。
- onChanged: 输入内容更改时的回调函数。
- onSubmitted: 用户提交(按下“完成”键)时的回调函数。
- inputFormatters: `TextInputFormatter` 用于格式化输入文本。
- obscureText: 用于密码输入,隐藏输入的字符。
- maxLength: 限制最大输入长度。
示例代码
以下是一个基本的 `TextField` 示例,展示了如何使用控制器、装饰器和输入格式化器:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';class TextFieldExample extends StatefulWidget {const TextFieldExample({super.key});@override_TextFieldExampleState createState() {return _TextFieldExampleState();}
}class _TextFieldExampleState extends State<TextFieldExample> {final TextEditingController _controller = TextEditingController();final FocusNode _focusNode = FocusNode();@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('TextField Example'),),body: Padding(padding: const EdgeInsets.all(16.0),child: Column(children: [TextField(controller: _controller,focusNode: _focusNode,decoration: const InputDecoration(labelText: 'Enter your text',border: OutlineInputBorder(),),keyboardType: TextInputType.text,textInputAction: TextInputAction.done,onChanged: (text) {print('Current text: $text');},onSubmitted: (text) {print('Submitted text: $text');},inputFormatters: [LengthLimitingTextInputFormatter(20),FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9]')),],),const SizedBox(height: 20),ElevatedButton(onPressed: () {// 打印当前文本框中的文本print('Final text: ${_controller.text}');// 移除焦点,使键盘消失_focusNode.unfocus();},child: const Text('Print Text and Unfocus'),),],)),);}
}
代码解析
- `TextEditingController`: 用于管理 `TextField` 的文本。可以通过 `_controller.text` 获取或设置输入文本。
- `FocusNode`: 管理 `TextField` 的焦点状态。使用 `_focusNode.unfocus()` 可以移除焦点,通常用于隐藏键盘。
- `InputDecoration`: 自定义 `TextField` 的外观,例如标签文本和边框。
- `inputFormatters`: 使用 `LengthLimitingTextInputFormatter` 限制输入长度,以及 `FilteringTextInputFormatter.allow` 限制输入内容为字母和数字。
- `keyboardType`: 设置为 `TextInputType.text`,用于一般文本输入。
- `textInputAction`: 设置为 `TextInputAction.done`,表示用户完成输入时的操作。
- 事件回调: `onChanged` 和 `onSubmitted` 允许在用户输入或提交时执行操作。
附加功能和用法
- 密码输入: 设置 `obscureText: true` 可以隐藏输入的字符,用于密码输入框。
- 多行输入: 通过设置 `maxLines` 属性,可以允许 `TextField` 输入多行文本。
- 文本样式: 使用 `style` 属性自定义文本的外观,例如字体大小和颜色。
- 错误信息: 使用 `errorText` 属性在 `InputDecoration` 中显示错误信息。
- 自动填充: 在 Android 和 iOS 上,`TextField` 支持自动填充功能,可以通过 `autofillHints` 配置。
Border
在 Flutter 中,`Border` 是一个非常重要的类,用于定义组件(如容器、按钮或输入框)周围的边框。它提供了多种方式来自定义边框的样式、颜色和宽度。理解 `Border` 的各种属性和用法有助于创建更具吸引力和功能性的 UI。
`Border` 类的基本概念
`Border` 类通常用于定义一个组件的四个边的样式。它通常与 `BoxDecoration` 一起使用,以应用于 `Container` 或其他需要边框的组件。
主要属性
- `top`、`bottom`、`left`、`right`: 每个边框的样式,通过 `BorderSide` 定义,可以设置颜色、宽度和样式。
- `all`: 使用同样的边框值应用到所有边。
- `symmetric`: 为水平和垂直方向的边设置对称的边框。
`BorderSide` 类
`BorderSide` 是用来描述边框的样式的类,包含以下属性:
- `color`: 边框的颜色。
- `width`: 边框的宽度,默认为 1.0。
- `style`: 边框的样式,`BorderStyle.solid`(实线)或 `BorderStyle.none`(无边框)。‘’
使用示例
以下是如何使用 `Border` 和 `BorderSide` 来自定义 `Container` 的边框:
import 'package:flutter/material.dart';class BorderExampleDemo extends StatelessWidget {const BorderExampleDemo({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Border Example'),),body: Center(child: Container(width: 200,height: 200,decoration: BoxDecoration(color: Colors.blue[50],border: const Border(top: BorderSide(color: Colors.blue,width: 3.0,style: BorderStyle.solid,),bottom: BorderSide(color: Colors.green,width: 5.0,style: BorderStyle.solid,),left: BorderSide(color: Colors.red,width: 2.0,style: BorderStyle.solid,),right: BorderSide(color: Colors.orange,width: 4.0,style: BorderStyle.solid,),)),),),);}
}
代码解析
- `BoxDecoration`: 用于定义 `Container` 的视觉外观,包括颜色和边框。
- `Border`: 使用 `Border` 类为 `Container` 的每一侧定义不同的 `BorderSide`。
- `BorderSide`: 描述了每个边的颜色、宽度和样式。
常用方法
- `Border.all()`: 创建一个统一的边框,所有边的样式相同。
decoration: BoxDecoration(border: Border.all(color: Colors.black,width: 2.0,),
),
- `Border.symmetric()`: 为水平(`horizontal`)和垂直(`vertical`)方向定义对称的边框。
decoration: BoxDecoration(color: Colors.yellow[50],border: Border.symmetric(vertical: BorderSide(color: Colors.red,width: 4.0,),horizontal: BorderSide(color: Colors.blue,width: 2.0,),),),
BorderRadius
`BorderRadius` 是 Flutter 中用于定义圆角矩形的类。它可以用于将边框、容器和其他矩形形状的角变圆。`BorderRadius` 提供了多种方法来定义角的圆度,允许你为每个角指定不同的半径,也可以为所有角指定相同的半径。
主要构造方法
1.`BorderRadius.circular(double radius)`: 为所有角设置相同的圆角半径。这个方法是最常用的,适合需要统一圆角的情况。
2.`BorderRadius.all(Radius radius)`: 使用 `Radius` 对象为所有角设置相同的半径。
3.`BorderRadius.only({Radius topLeft, Radius topRight, Radius bottomLeft, Radius bottomRight})`: 分别为每个角设置不同的半径,提供了最大的灵活性。
4.`BorderRadius.horizontal({Radius left, Radius right})`: 仅为水平的两个角设置半径。
5.`BorderRadius.vertical({Radius top, Radius bottom})`: 仅为垂直的两个角设置半径。
示例代码
以下是如何使用 `BorderRadius` 的一些示例:
1. 使用 `BorderRadius.circular`
import 'package:flutter/material.dart';class CircularBorderExample extends StatelessWidget {const CircularBorderExample({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Circular Border Example')),body: Center(child: Container(width: 200,height: 200,decoration: BoxDecoration(color: Colors.blue[100],borderRadius: BorderRadius.circular(20.0), // 所有角为圆角 20.0),),),);}
}
2. 使用 `BorderRadius.only`
import 'package:flutter/material.dart';
class OnlyBorderExample extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Only Border Example')),body: Center(child: Container(width: 200,height: 200,decoration: BoxDecoration(color: Colors.green[100],borderRadius: BorderRadius.only(topLeft: Radius.circular(30.0),bottomRight: Radius.circular(30.0),),),),),);}
}
3. 使用 `BorderRadius.horizontal`
import 'package:flutter/material.dart';
class HorizontalBorderExample extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Horizontal Border Example')),body: Center(child: Container(width: 200,height: 200,decoration: BoxDecoration(color: Colors.red[100],borderRadius: BorderRadius.horizontal(left: Radius.circular(20.0),right: Radius.circular(50.0),),),),),);}
}
EditableText
在 Flutter 中,`EditableText` 是文本输入框的核心控件,所有类似 `TextField` 和 `TextFormField` 的控件都是基于 `EditableText` 封装的。`EditableText` 提供了更底层的能力,允许开发者对文本输入框的行为进行高度自定义。
1. 什么是 `EditableText`?
`EditableText` 是一个可编辑的文本组件,用于实现完全可控的文本输入功能。它不像 `TextField` 那样提供一套高阶封装,而是提供了对文本输入的较底层控制,包括:
- 文本内容的管理
- 焦点的获取与丢失
- 自定义光标、样式、输入法行为
- 输入格式化器和验证规则
2. `EditableText` 的核心属性解析
以下是 `EditableText` 的关键属性及其作用:
必需的属性
属性 | 类型 | 描述 |
`controller` | `TextEditingController` | 管理输入框内容的核心控制器,可监听文本变化或更新文本。 |
`focusNode` | `FocusNode` | 管理输入框焦点状态的节点。可判断输入框是否聚焦并控制焦点行为。 |
`style` | `TextStyle` | 定义输入文本的样式(如字体大小、文本颜色等)。 |
`cursorColor` | `Color` | 设置光标的颜色。 |
`backgroundCursorColor` | `Color` | 光标的背景颜色,当光标不可见时使用该颜色。 |
常用的属性
属性 | 类型 | 描述 |
`obscureText` | `bool` | 是否隐藏输入的文本(常用于密码输入)。 |
`autofocus` | `bool` | 是否在构建时自动获取焦点。 |
`keyboardType` | `TextInputType` | 设置键盘类型(如文本、数字、email等)。 |
`textAlign` | `TextAlign` | 文本的对齐方式(如:左对齐、右对齐、居中)。 |
`maxLines` | `int` | 设置输入框的最大行数,默认为 1。 |
`minLines` | `int` | 设置输入框的最小行数。 |
`inputFormatters` | `List` | 输入格式化器,可用来限制或过滤非法输入(如限制字数、屏蔽特殊字符等)。 |
onChanged` | `ValueChanged` | 当文本内容发生变化时触发的回调函数。 |
`onEditingComplete` | `VoidCallback` | 当用户完成编辑时(如按下键盘的“完成”按钮)触发的回调。 |
`onSubmitted` | `ValueChanged` | 用户提交输入内容时触发的回调。 |
`readOnly` | `bool` | 是否设置为只读模式(用户无法编辑文本)。 |
光标和样式相关属性
属性 | 类型 | 描述 |
`cursorWidth` | `double`
| 光标的宽度。默认值通常为 2.0 像素。 |
`cursorHeight` | `double?` | 光标的高度。通常情况下,光标的高度与文本的高度一致,但你可以通过此属性自定义。 |
`cursorRadius` | `Radius?` | 光标的圆角半径。如果需要圆角光标,可以在这里设置。 |
`cursorOpacityAnimates` | `bool` | 如果为 true,光标的透明度会在显示和隐藏之间动画过渡。 |
`selectionHeightStyle` | `BoxHeightStyle` | 控制文本选择时的高度样式。影响文本选择的外观。 |
`selectionWidthStyle` | `BoxWidthStyle` | 控制文本选择时的宽度样式。通常与 `selectionHeightStyle` 一起使用。 |
其他重要属性
属性 | 类型 | 描述 |
`toolbarOptions` | `ToolbarOptions` | 定义当用户长按输入框时,弹出工具栏中可用的选项(如剪切、复制、粘贴等)。 |
`showCursor` | `bool?` | 控制光标是否显示。 |
`enableInteractiveSelection` | `bool` | 控制是否允许用户交互式选择文本(如长按选择文本)。 |
`textCapitalization` | `TextCapitalization` | 控制输入文本的自动大写行为(如每个单词首字母大写)。 |
使用 `EditableText` 的示例
以下是一个使用 `EditableText` 的完整示例,展示如何自定义一个简单的文本输入框:
import 'package:flutter/material.dart';class EditableTextWidgetDemo extends StatefulWidget {const EditableTextWidgetDemo({super.key});@override_EditableTextWidgetState createState() {return _EditableTextWidgetState();}
}class _EditableTextWidgetState extends State<EditableTextWidgetDemo> {final TextEditingController _controller = TextEditingController();final FocusNode _focusNode = FocusNode();@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('TextEditingController Example')),body: Center(child: Padding(padding: const EdgeInsets.all(16.0),child: EditableText(controller: _controller,focusNode: _focusNode,style: const TextStyle(color: Colors.black, fontSize: 18.0),cursorColor: Colors.blue,backgroundCursorColor: Colors.grey,keyboardType: TextInputType.text,autofocus: true,maxLines: null,// 允许多行输入onChanged: (text) {print("Text changed: $text");},),)));}@overridevoid dispose() {_controller.dispose();_focusNode.dispose();super.dispose();}
}
总结
- 灵活性: `EditableText` 提供了高度的灵活性和定制能力。虽然 `TextField` 和 `TextFormField` 已经满足了大多数日常需求,但 `EditableText` 允许开发者完全控制文本输入的细节。如果你需要实现一个非常定制化的文本输入体验,`EditableText` 是一个很好的起点。
- 自定义控制: 通过 `EditableText`,你可以完全自定义光标的外观、文本样式、输入格式化、焦点行为、输入法行为等等。这使得它适合于需要特定文本输入行为的应用场景。
- 底层实现: 作为 `TextField` 和 `TextFormField` 的底层实现,`EditableText` 需要开发者手动管理 `TextEditingController` 和 `FocusNode`,这意味着开发者必须更加关注资源的管理(例如确保在不需要时正确释放这些对象)。
- 应用场景: 使用 `EditableText` 适用于需要精细控制用户输入的场景,比如自定义的文本编辑器、需要特殊输入验证的表单等。
通过了解和善用 `EditableText`,开发者可以创建更具个性化的用户输入界面,满足特定的应用需求。希望这个解析能够帮助你更好地理解和使用 `EditableText`。
GestureDetector
`GestureDetector` 是 Flutter 中一个非常重要的组件,用于检测用户的手势操作(如点击、双击、拖动、滑动等)。通过使用 `GestureDetector`,你可以捕获用户在屏幕上的各种手势,并对这些手势做出响应。这使得 `GestureDetector` 成为构建交互式用户界面的关键工具之一。
主要功能
`GestureDetector` 提供了一种简单而强大的方式来监听和响应用户的手势。以下是一些常用的手势检测功能:
点击手势:
- `onTap`: 用户点击时触发。
- `onDoubleTap`: 用户双击时触发。
- `onLongPress`: 用户长按时触发。
拖动手势:
- `onPanStart`: 用户开始拖动时触发。
- `onPanUpdate`: 用户拖动过程中触发。
- `onPanEnd`: 用户拖动结束时触发。
滑动手势:
- `onHorizontalDragStart`, `onHorizontalDragUpdate`, `onHorizontalDragEnd`: 检测水平拖动。
- `onVerticalDragStart`, `onVerticalDragUpdate`, `onVerticalDragEnd`: 检测垂直拖动。
缩放手势:
- `onScaleStart`, `onScaleUpdate`, `onScaleEnd`: 用于检测缩放操作,通常用于实现捏合缩放功能。
基本用法
以下是一个简单的示例,展示如何使用 `GestureDetector` 来监听不同的手势:
import 'package:flutter/material.dart';class GestureDetectorExampleMyTestDemo extends StatelessWidget {const GestureDetectorExampleMyTestDemo({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('GestureDetector Example')),body: Center(child: GestureDetector(onTap: () {print('Tapped!');},onDoubleTap: () {print('Double Tapped!');},onLongPress: () {print('Long Pressed!');},onPanUpdate: (details) {print('Pan Updated: ${details.delta}');},child: Container(width: 200,height: 200,color: Colors.blue,alignment: Alignment.center,child: const Text('Tap Me',style: TextStyle(color: Colors.white, fontSize: 24),),),),),);}
}
详细属性解析
- `onTap`: 单次点击时的回调。
- `onDoubleTap`: 双击时的回调。
- `onLongPress`: 长按时的回调。
- `onPanStart`, `onPanUpdate`, `onPanEnd`: 分别用于开始、更新和结束拖动时的回调。
- `onHorizontalDragStart`, `onHorizontalDragUpdate`, `onHorizontalDragEnd`: 处理水平拖动。
- `onVerticalDragStart`, `onVerticalDragUpdate`, `onVerticalDragEnd`: 处理垂直拖动。
- `onScaleStart`, `onScaleUpdate`, `onScaleEnd`: 处理缩放手势。
注意事项
1. Hit Testing(命中测试)
- `GestureDetector` 需要一个非空的子组件才能检测手势。
- 如果 `GestureDetector` 的子组件是空的(比如没有子组件,或者子组件是 `Container` 且未设置 `color` 属性),手势检测将无法生效。这是因为 Flutter 默认不会为空组件进行命中测试。
- 解决方案:可以为 `GestureDetector` 的子组件设置一个明确的背景颜色(即使是透明的),例如 `color: Colors.transparent`。
GestureDetector(onTap: () {print('Tapped');},child: Container(width: 100,height: 100,color: Colors.transparent, // 必须设置颜色,否则点击事件可能无法检测),
)
2. 手势冲突
- 当多个手势识别器(如拖动和缩放)同时应用于同一个组件时,可能会发生手势冲突。
- Flutter 提供了 手势竞技场机制(Gesture Arena) 来解决冲突。在默认情况下,多个手势识别器会竞争事件的优先权,只有一个手势识别器会胜出。
- 如果你需要同时响应多个手势,可以使用 `RawGestureDetector` 或 `GestureRecognizer` 来自定义手势行为。
例如,通过 `onScaleUpdate` 实现拖动和缩放:
GestureDetector(onScaleUpdate: (details) {print('Scale: ${details.scale}, Translation: ${details.focalPointDelta}');},child: Container(width: 200,height: 200,color: Colors.blue,),
);
3. 嵌套手势
- 当 `GestureDetector` 嵌套时,内部的手势可能会覆盖外部的手势,或者导致手势冲突。
- Flutter 提供了 `Behavior` 属性来控制手势的传播方式:
- `HitTestBehavior.deferToChild`(默认值):只有子组件能够响应手势时,`GestureDetector` 才会检测手势。
- `HitTestBehavior.opaque`:即使子组件是透明的,父组件也会参与命中测试。
- `HitTestBehavior.translucent`:父组件会响应手势,但透明区域的子组件仍然可以响应手势。
GestureDetector(behavior: HitTestBehavior.translucent,onTap: () {print('Parent tapped!');},child: GestureDetector(onTap: () {print('Child tapped!');},child: Container(width: 100,height: 100,color: Colors.red,),),
);
Flutter实现输入验证码代码学习
import 'dart:async';import 'package:flutter/material.dart';
import 'package:flutter/services.dart';///验证码输入框
class VerificationCodeInputDemoPage extends StatelessWidget {const VerificationCodeInputDemoPage({super.key});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text("VerificationCodeInputDemoPage"),),body: GestureDetector(behavior: HitTestBehavior.translucent,onTap: () {FocusScope.of(context).requestFocus(FocusNode());},child: Center(child: VerCodeInput(ctx: context,length: 6,keyboardType: TextInputType.number,builder: staticRectangle(context),onChanged: (value) {},///输入完成时onFilled: (value) {//print('Your input is $value.');},),),),);}staticRectangle(BuildContext context) {var codeSize = 6;double padding = 16;double width = MediaQuery.sizeOf(context).width;double codeFullSize = ((width - 2 * padding) / codeSize);double codeNormalSize = codeFullSize - 20;return CodeInputBuilders.rectangle(totalSize: Size(codeFullSize, codeFullSize),emptySize: Size(codeNormalSize, codeNormalSize),filledSize: Size(codeNormalSize, codeNormalSize),borderRadius: BorderRadius.zero,border: Border.all(color: Theme.of(context).primaryColor, width: 1.0),color: Colors.transparent,textStyle: TextStyle(color: Theme.of(context).primaryColor,fontSize: 16.0,fontWeight: FontWeight.bold));}
}///from https://github.com/tiny-express/flutter_verification_code_input/blob/master/lib/src/verification_code_input.darttypedef CodeInputBuilder = Widget Function(bool hasFocus, String char);class VerCodeInput extends StatefulWidget {const VerCodeInput._({super.key,required this.length,required this.keyboardType,required this.inputFormatters,required this.builder,required this.ctx,this.onChanged,this.onFilled,});factory VerCodeInput({Key? key,required int length,TextInputType keyboardType = TextInputType.text,List<TextInputFormatter>? inputFormatters,BuildContext? ctx,required CodeInputBuilder builder,void Function(String value)? onChanged,void Function(String value)? onFilled,}) {assert(length > 0, 'The length needs to be larger than zero.');assert(length.isFinite, 'The length needs to be finite.');inputFormatters ??= _createInputFormatters(length, keyboardType);return VerCodeInput._(key: key,length: length,keyboardType: keyboardType,inputFormatters: inputFormatters,builder: builder,ctx: ctx,onChanged: onChanged,onFilled: onFilled,);}/// The length of character entities to always display.////// ## Sample code////// A code input with 4 characters:////// ```dart/// CodeInput(length: 4)/// ```final int length;/// The type of thconstard which shows up.////// ## Sample codeconst////// ```dart/// CodeInput(keyboardType: TextInputType.number)/// ```final TextInputType keyboardType;/// A list of input formatters which can validate the text as it is being/// typed.////// If you specify this parameter, the default input formatters aren't used,/// so make sure you really check for everything (like length of the input).////// ## Sample code////// An code input that displays a normal keyboard but only allows for/// hexadecimal input:////// ```dart/// CodeInput(/// inputFormatters: [/// WhitelistingTextInputFormatter(RegExp('^[0-9a-fA-F]*\$'))/// ]/// )/// ```final List<TextInputFormatter> inputFormatters;/// A builder for the character entities.////// See [CodeInputBuilders] for examples.final CodeInputBuilder builder;/// A callback for changes to the input.final void Function(String value)? onChanged;/// A callback for when the input is filled.final void Function(String value)? onFilled;/// context parent because of MediaQuery.of(widget.ctx)final BuildContext? ctx;/// A helping function that creates input formatters for a given length and/// keyboardType.static List<TextInputFormatter> _createInputFormatters(int length, TextInputType keyboardType) {final formatters = <TextInputFormatter>[LengthLimitingTextInputFormatter(length)];// Add keyboard specific formatters.// For example, a code input with a number keyboard type probably doesn't// want to allow decimal separators or signs.if (keyboardType == TextInputType.number) {formatters.add(FilteringTextInputFormatter.digitsOnly);}return formatters;}@override_VerCodeInputState createState() => _VerCodeInputState();
}class _VerCodeInputState extends State<VerCodeInput> {final node = FocusNode();final controller = TextEditingController();String get text => controller.text;@overrideWidget build(BuildContext context) {// We'll display the visual widget and a not shown EditableText for doing// the actual work on top of each other.return Stack(children: <Widget>[// This is the actual EditableText wrapped in a Container with zero// dimensions.SizedBox(width: 0.0,height: 0.0,child: EditableText(controller: controller,focusNode: node,inputFormatters: widget.inputFormatters,keyboardType: widget.keyboardType,backgroundCursorColor: Colors.black,style: const TextStyle(),// Doesn't really matter.cursorColor: Colors.black,// Doesn't really matter.onChanged: (value) => setState(() {widget.onChanged?.call(value);if (value.length == widget.length) {widget.onFilled?.call(value);}}),)),// These are the actual character widgets. A transparent container lies// right below the gesture detector, so all taps get collected, even// the ones between the character entities.GestureDetector(onTap: () {if (MediaQuery.viewInsetsOf(context).bottom == 0) {final focusScope = FocusScope.of(context);focusScope.requestFocus(FocusNode());Future.delayed(Duration.zero, () => focusScope.requestFocus(node));}},child: Container(color: Colors.transparent,child: Row(mainAxisSize: MainAxisSize.min,children: List.generate(widget.length, (i) {final hasFocus = controller.selection.start == i;final char = i < text.length ? text[i] : '';final characterEntity = widget.builder(hasFocus, char);return characterEntity;}),),)),]);}
}/// An abstract class that provides some commonly-used builders for the
/// character entities.
///
/// * [containerized]: A builder putting chars in an animated container.
/// * [circle]: A builder putting chars in circles.
/// * [rectangle]: A builder putting chars in rectangles.
/// * [lightCircle]: A builder putting chars in light circles.
/// * [darkCircle]: A builder putting chars in dark circles.
/// * [lightRectangle]: A builder putting chars in light rectangles.
/// * [darkRectangle]: A builder putting chars in dark rectangles.
abstract class CodeInputBuilders {/// Builds the input inside an animated container.static CodeInputBuilder containerized({Duration animationDuration = const Duration(milliseconds: 50),required Size totalSize,required Size emptySize,required Size filledSize,required BoxDecoration emptyDecoration,required BoxDecoration filledDecoration,required TextStyle emptyTextStyle,required TextStyle filledTextStyle,}) {return (bool hasFocus, String char) => Container(width: totalSize.width,height: totalSize.height,alignment: Alignment.center,child: AnimatedContainer(duration: const Duration(milliseconds: 100),decoration: char.isEmpty ? emptyDecoration : filledDecoration,width: char.isEmpty ? emptySize.width : filledSize.width,height: char.isEmpty ? emptySize.height : filledSize.height,alignment: Alignment.center,child: Text(char,style: char.isEmpty ? emptyTextStyle : filledTextStyle),));}/// Builds the input inside a circle.static CodeInputBuilder circle({double totalRadius = 30.0,double emptyRadius = 10.0,double filledRadius = 25.0,required Border border,required Color color,required TextStyle textStyle}) {final decoration = BoxDecoration(shape: BoxShape.circle,border: border,color: color,);return containerized(totalSize: Size.fromRadius(totalRadius),emptySize: Size.fromRadius(emptyRadius),filledSize: Size.fromRadius(filledRadius),emptyDecoration: decoration,filledDecoration: decoration,emptyTextStyle: textStyle.copyWith(fontSize: 0.0),filledTextStyle: textStyle);}/// Builds the input inside a rectangle.static CodeInputBuilder rectangle({Size totalSize = const Size(50.0, 60.0),Size emptySize = const Size(20.0, 20.0),Size filledSize = const Size(40.0, 60.0),BorderRadius borderRadius = BorderRadius.zero,required Border border,required Color color,required TextStyle textStyle,}) {final decoration = BoxDecoration(border: border,borderRadius: borderRadius,color: color,);return containerized(totalSize: totalSize,emptySize: emptySize,filledSize: filledSize,emptyDecoration: decoration,filledDecoration: decoration,emptyTextStyle: textStyle.copyWith(fontSize: 0.0),filledTextStyle: textStyle);}/// Builds the input inside a light circle.static CodeInputBuilder lightCircle({double totalRadius = 30.0,double emptyRadius = 10.0,double filledRadius = 25.0,}) {return circle(totalRadius: totalRadius,emptyRadius: emptyRadius,filledRadius: filledRadius,border: Border.all(color: Colors.white, width: 2.0),color: Colors.white10,textStyle: const TextStyle(color: Colors.white, fontSize: 20.0, fontWeight: FontWeight.bold));}/// Builds the input inside a light circle.static CodeInputBuilder darkCircle({double totalRadius = 30.0,double emptyRadius = 10.0,double filledRadius = 25.0,}) {return circle(totalRadius: totalRadius,emptyRadius: emptyRadius,filledRadius: filledRadius,border: Border.all(color: Colors.black, width: 2.0),color: Colors.black12,textStyle: const TextStyle(color: Colors.black, fontSize: 20.0, fontWeight: FontWeight.bold));}/// Builds the input inside a light rectangle.static CodeInputBuilder lightRectangle({Size totalSize = const Size(50.0, 60.0),Size emptySize = const Size(20.0, 20.0),Size filledSize = const Size(40.0, 60.0),BorderRadius borderRadius = BorderRadius.zero,}) {return rectangle(totalSize: totalSize,emptySize: emptySize,filledSize: filledSize,borderRadius: borderRadius,border: Border.all(color: Colors.white, width: 2.0),color: Colors.white10,textStyle: const TextStyle(color: Colors.white, fontSize: 20.0, fontWeight: FontWeight.bold));}static CodeInputBuilder staticRectangle({Size totalSize = const Size(60.0, 60.0),Size emptySize = const Size(40.0, 40.0),Size filledSize = const Size(40.0, 40.0),BorderRadius borderRadius = BorderRadius.zero,}) {return rectangle(totalSize: totalSize,emptySize: emptySize,filledSize: filledSize,borderRadius: borderRadius,border: Border.all(color: Colors.white, width: 1.0),color: Colors.transparent,textStyle: const TextStyle(color: Colors.white, fontSize: 20.0, fontWeight: FontWeight.bold));}/// Builds the input inside a dark rectangle.static CodeInputBuilder darkRectangle({Size totalSize = const Size(50.0, 60.0),Size emptySize = const Size(20.0, 20.0),Size filledSize = const Size(40.0, 60.0),BorderRadius borderRadius = BorderRadius.zero,}) {return rectangle(totalSize: totalSize,emptySize: emptySize,filledSize: filledSize,borderRadius: borderRadius,border: Border.all(color: Colors.black, width: 2.0),color: Colors.black12,textStyle: const TextStyle(color: Colors.black, fontSize: 20.0, fontWeight: FontWeight.bold));}
}
相关文章:
Flutter 实现验证码输入框学习
学习flutter代码 实现一个用于输入验证码的自定义组件,它允许用户输入固定长度的验证码,并在输入完成时触发回调。 前置知识点学习 TextStyle TextStyle 是 Flutter 中用于定义文本样式的类。它提供了一组属性来控制文本的外观,如字体大小、…...
hutool糊涂工具通过注解设置excel宽度
import java.lang.annotation.*;Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) public interface ExcelStyle {int width() default 0; }/*** 聊天记录*/ Data public class DialogContentInfo {/**…...
汽车基础软件AutoSAR自学攻略(四)-AutoSAR CP分层架构(3) (万字长文-配21张彩图)
汽车基础软件AutoSAR自学攻略(四)-AutoSAR CP分层架构(3) (万字长文-配21张彩图) 前面的两篇博文简述了AutoSAR CP分层架构的概念,下面我们来具体到每一层的具体内容进行讲解,每一层的每一个功能块力求用一个总览图,外加一个例子的图给大家进…...
有收到腾讯委托律师事务所向AppStore投诉带有【水印相机】主标题名称App的开发者吗
近期,有多名开发者反馈,收到来自腾讯科技 (深圳) 有限公司委托北京的一家**诚律师事务所卞,写给AppStore的投诉邮件。 邮件内容主要说的是,腾讯注册了【水印相机】这四个字的商标,所以你们这些在AppStore上的app&…...
SpringBoot操作spark处理hdfs文件
SpringBoot操作spark处理hdfs文件 1、导入依赖 <!-- spark依赖--><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>3.2.2</version></dependency><depend…...
Spring Boot中的依赖注入是如何工作
Spring Boot 中的依赖注入(Dependency Injection,简称 DI)是通过 Spring 框架的核心机制——控制反转(Inversion of Control,IOC)容器来实现的。Spring Boot 基于 Spring Framework,在应用中自动…...
算法面试1
简述yolov1的网络架构 YOLOv1网络结构包括24层卷积层用来提取图像的特征,2层全连接层回归得到7730(141420)的张量。 网络结构大概如下:输入的是4484483通道的图像,就是RGB图像,然后用64个卷积核大小是…...
Android车机DIY开发之软件篇(八)单独编译
Android车机DIY开发之软件篇(八)单独编译 1.CarLauncher单独编译 CarLauncher源码位于 packages/apps/Car/Launcher 用Eclipse ADT 谷歌定制版编译而成,.mk .bp编译 Android13目录如下: alientekalientek:~/packages/apps/Car$ ls Calendar …...
保证Mysql数据库到ES的数据一致性的解决方案
文章目录 1.业务场景介绍1.1 需求分析1.2 技术实现方案 2.业界常用数据一致性方案分析2.1 同步双写方案2.2 MQ异步双写方案2.3 扫表定期同步方案2.4 监听binlog同步方案 1.业务场景介绍 1.1 需求分析 某知名的在线旅游平台,在即将到来的春季促销活动之前ÿ…...
Cursor实现go项目配置并实现仓库Gin项目运行
✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏:知识备份 ✨特色专栏:知识分享 &#x…...
【网络云SRE运维开发】2025第2周-每日【2025/01/11】小测-【第11章NAT理论和实操考试】解析
文章目录 一、选择题二、理论题三、实操题 【网络云SRE运维开发】2025第2周-每日【2025/01/11】小测-【第11章NAT理论和实操考试】解析 一、选择题 在H3C设备上,NAT技术主要用于( ) A. 提高网络安全性 B. 实现不同网段的通信 C. 将内部私有IP…...
drawDB docker部属
docker pull xinsodev/drawdb docker run --name some-drawdb -p 3000:80 -d xinsodev/drawdb浏览器访问:http://192.168.31.135:3000/...
页面顶部导航栏(Navbar)的功能(Navbar/index.vue)
这段代码是一个 Vue.js 组件,实现了页面顶部导航栏(Navbar)的功能。我将分块分析它的各个部分: 模板 (Template): <!-- spid-admin/src/layout/components/Navbar/index.vue --> <template><div class"navb…...
【人工智能】用Python进行对象检测:从OpenCV到YOLO的全面指南
对象检测是计算机视觉领域的核心任务之一,广泛应用于视频监控、自动驾驶、智能安防等多个场景。随着深度学习技术的发展,基于传统方法的对象检测逐渐被基于神经网络的先进模型所取代。本文将系统地介绍如何使用Python进行对象检测,重点探讨了…...
深度学习从入门到实战——卷积神经网络原理解析及其应用
卷积神经网络CNN 卷积神经网络前言卷积神经网络卷积的填充方式卷积原理展示卷积计算量公式卷积核输出的大小计算感受野池化自适应均值化空洞卷积经典卷积神经网络参考 卷积神经网络 前言 为什么要使用卷积神经网络呢? 首先传统的MLP的有什么问题呢? - …...
Flink概念知识讲解之:Restart重启策略配置
Flink概念知识讲解之:Restart重启策略配置 当 Task 发生故障时,Flink 需要重启出错的 Task 以及其他受到影响的 Task ,以使得作业恢复到正常执行状态。 Flink 通过重启策略和故障恢复策略来控制 Task 重启:重启策略决定是否可以…...
Golang中使用 Mqtt
MQTT 是一种基于发布/订阅模式的 轻量级物联网消息传输协议 ,可以用极少的代码和带宽为联网设备提供实时可靠的消息服务,它广泛应用于物联网、移动互联网、智能硬件、车联网、电力能源等行业。 本文主要介绍如何在 Golang 项目中使用 github.com/eclips…...
腾讯云下架印度云服务器节点,印度云服务器租用何去何从
近日,腾讯云下架印度云服务器节点的消息引起了业界的广泛关注。这一变动让许多依赖印度云服务器的用户开始担忧,印度云服务器租用的未来究竟在何方? 从印度市场本身来看,其云服务市场的潜力不容小觑。据 IDC 报告,到 2…...
STM32内置Flash
一、原理 利用flash存储用户数据需要注意查看,用户数据是否会覆盖芯片运行程序。 IAP(在程序中编程)利用程序修改程序本身,和OTA是一个原理。IAP在程序中编程支持任意一种通信下载。 ICP(在电路中编程,通…...
面试:C++类成员初始化顺序
1、非静态数据成员:按它们在类定义的声明顺序初始化,不会按它们在初始化列表的顺序。 2、静态数据成员:在main函数启动之前,并且只初始化一次 3、基类构造函数:如果类从一个或多个基类继承而来,基类的构造…...
约束的笔记
约束的分类 为什么需要约束 为了保证数据的完整性 ①实体完整性(Entity Integrity)(同一个表中,不能存在两条完全相同无法区分的记录) ②域完整性(Domain Integrity) ③引用完整性(Referential Integ…...
【Docker】安装registry本地镜像库,开启Https功能
下载镜像 docker pull registry:2 需要启动https功能,就要生成服务端的自签名的证书和私钥,以及在docker客户端安装这个经过签名的证书。 第一步:生成公私钥信息,第二步,制作证书签名申请文件, 第三步&…...
el-tree拖拽光标错位问题
背景:el-tree实现的分类树增加拖拽功能后,当分类树由于数量较多产生滚动条,如果分类树已滚动,进行拖拽时会造成光标错位的问题: 原因:el-tree拖拽光标定位的高度并未加上滚动的高度解决:将滚动的样式属性放…...
Linux权限
目录 一.Linux权限的概念 二.Linux权限管理 1.文件访问者的分类 2.文件类型和访问权限 1.文件类型 2.基本权限 3.文件权限的表示方法 1.字符表示法 2.八进制表示法 4.文件权限的相关访问方法 1.chmod 2.chown 3.chgrp 4.粘滞位 三.权限总结 一.Linux权限的概念 …...
mysql binlog 日志分析查找
文章目录 前言一、分析 binlog 内容二、编写脚本结果总结 前言 高效快捷分析 mysql binlog 日志文件。 mysql binlog 文件很大 怎么快速通过关键字查找内容 一、分析 binlog 内容 通过 mysqlbinlog 命令可以看到 binlog 解析之后的大概样子 二、编写脚本 编写脚本 search_…...
win32汇编环境,窗口程序中对按钮控件常用操作的示例
;运行效果 ;win32汇编环境,窗口程序中对按钮控件常用操作的示例 ;常用的操作,例如创建按钮控件,使其无效,改变文本,得到文本等。 ;将代码复制进radasm软件里,直接就可以编译运行。重点部分加备注。 ;>&g…...
风水算命系统架构与功能分析
系统架构 服务端:Java(最低JDK1.8,支持JDK11以及JDK17)数据库:MySQL数据库(标配5.7版本,支持MySQL8)ORM框架:Mybatis(集成通用tk-mapper,支持myb…...
如何在 Ubuntu 22.04 上安装和配置邮件服务器教程
简介: 在本指南中,我们将演示如何在 Ubuntu 22.04 上安装和配置邮件服务器,因为大中型公司可以从拥有私人邮件服务器中获益匪浅。通过使用邮件服务器,可以密切监视所有电子邮件流量。此外,自定义设置的灵活性使得建立…...
后门原理与实践
实验目录 windows主机与kali虚拟机实现互联互通使用netcat获取主机操作Shell,cron启动使用socat获取主机操作Shell, 任务计划启动使用MSF meterpreter生成可执行文件,利用ncat或socat传送到主机并运行获取主机Shell使用MSF meterpreter生成获取目标主机…...
代理模式详解与应用
代理模式(Proxy Pattern),也称为委托模式或 surrogate 模式,是一种结构型设计模式。它为其他对象提供一个代理以控制对这个对象的访问。通过引入代理对象,可以在不改变原始对象接口的前提下,添加额外的功能…...
C#,动态规划问题中基于单词搜索树(Trie Tree)的单词断句分词( Word Breaker)算法与源代码
1 分词 分词是自然语言处理的基础,分词准确度直接决定了后面的词性标注、句法分析、词向量以及文本分析的质量。英文语句使用空格将单词进行分隔,除了某些特定词,如how many,New York等外,大部分情况下不需要考虑分词…...
基于单片机的智能家居排气扇系统设计
1系统方案设计 本设计基于单片机的智能家居排气扇系统采用STM32单片机作为主控制器,通过DHT11温湿传感器和MQ-2烟雾传感器实现温度、湿度、烟雾检测,在自动模式下,可以根据烟雾浓度通过PWM调速的方式自动调节排气扇的速度,而在手…...
基于JAVA+SpringBoot+Vue的二手车交易系统
基于JAVASpringBootVue的二手车交易系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末附源码下载链接🍅 哈喽…...
【JVM-2.2】使用JConsole监控和管理Java应用程序:从入门到精通
在Java应用程序的开发和运维过程中,监控和管理应用程序的性能和资源使用情况是非常重要的。JConsole是Java Development Kit(JDK)自带的一款图形化监控工具,它可以帮助开发者实时监控Java应用程序的内存、线程、类加载以及垃圾回收…...
windows及linux 安装 Yarn 4.x 版本
1. 确保系统环境准备 a. 安装 Node.js Yarn 依赖于 Node.js,所以需要先安装 Node.js。前往 Node.js 官网 下载并安装适合你的 Windows 版本的 Node.js(推荐 LTS 版本)。安装完成后,打开命令提示符(CMD)或 PowerShell,验证安装:node -v npm -v如果显示版本号,则表示安…...
VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署
近期有个工作需求是进行 YOLOv8 模型的 C 部署,部署环境如下 系统:WindowsIDE:VS2015语言:COpenCV 4.5.0OnnxRuntime 1.15.1 0. 预训练模型保存为 .onnx 格式 假设已经有使用 ultralytics 库训练并保存为 .pt 格式的 YOLOv8 模型…...
1.两数之和--力扣
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 示例 1…...
MySQL库表的操作
目录 一、库的操作 1.1库的创建 1.2字符集和校验规则 1.2.1 查看系统默认字符集以及校验规则 1.2.2 查看数据库支持的字符集 1.2.3 查看数据库支持的字符集校验规则 1.2.4 校验规则对数据库的影响 1.3操纵数据库 1.3.1显示库 1.3.2显示创建语句 1.3.3修改数据库 1.3…...
【强化学习】深度确定性策略梯度算法(DDPG)详解(附代码)
📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅…...
单片机实物成品-011 火灾监测
火灾监测(20个版本) 版本20: oled显示温湿度烟雾浓度火焰传感器天然气浓度窗户风扇水泵排气系统声光报警语音播报按键WIFI模块 ----------------------------------------------------------------------------- https://www.bilibili.com…...
牛客网刷题 ——C语言初阶(6指针)——BC106 上三角矩阵判定
1. 题目描述——BC106 上三角矩阵判定 牛客网OJ题链接 描述 KiKi想知道一个n阶方矩是否为上三角矩阵,请帮他编程判定。上三角矩阵即主对角线以下的元素都为0的矩阵,主对角线为从矩阵的左上角至右下角的连线。 示例 输入: 3 1 2 3 0 4 5 0 0…...
Mysql--重点篇--索引(索引分类,Hash和B-tree索引,聚簇和非聚簇索引,回表查询,覆盖索引,索引工作原理,索引失效,索引创建原则等)
索引是数据库中用于加速查询操作的重要机制。通过索引,MySQL可以快速定位到满足查询条件的数据行,而不需要扫描整个表。合理的索引设计可以显著提高查询性能,但不合理的索引可能会导致性能下降和磁盘空间浪费。因此,理解索引的工作…...
Vue3框架核心功能点响应式数据reactive、组合式API setup、computed、组件通信、路由导航,状态管理vuex、pinia等的实战示例代码
记录几个Vue3框架核心功能点,例如响应式数据reactive、组合式API setup、computed、组件通信、路由导航,状态管理vuex、pinia……等实战示例代码: 一、响应式数据(Reactive Data) 创建响应式对象 使用reactive函数创建…...
Gitlab-Runner配置
原理 Gitlab-Runner是一个非常强大的CI/CD工具。它可以帮助我们自动化执行各种任务,如构建、测试和部署等。Gitlab-Runner和Gitlab通过API通信,接收作业并提交到执行队列,Gitlab-Runner从队列中获取作业,并允许在不同环境下进行作…...
多台PC共用同一套鼠标键盘
当环境中有多个桌面 pc 需要操作的时候,在 多台 pc 之间切换会造成很多的不方便 可以通过远程进行连接,但是有一个更好的方案是让多台机器之间共用同一套键盘鼠标 常用的解决方案 synergy 和 sharemouse,通过移动光标在不同的 pc 间切换 s…...
学会使用computed计算属性与watch监听(小白学习笔记)
1. 使用不同方法实现 姓名案例 需求: 根据data中 firstName 和 lastName 的值 来动态地展示全名 1.1. 插值语法 如果只使用学过的插值语法 那可以在模板中直接使用两个变量 . 但是如果需要对数据进行计算等处理 就需要在插值语法里写复杂的js表达式. 这样就违背了vue风格指…...
atoi函数的概念和使用案例
atoi 函数是 C 语言标准库中的一个函数,它用于将字符串转换为整数。atoi 的名称是 “ASCII to integer” 的缩写。该函数定义在 <stdlib.h> 头文件中。 概念 atoi 函数会从字符串的开始位置开始转换,直到遇到第一个非数字字符或遇到字符串结束符…...
unittest VS pytest
以下是 unittest 和 pytest 框架的对比表格: 特性unittestpytest设计理念基于类的设计,类似于 Java 的 JUnit更简洁,基于函数式编程设计,支持类和函数两种方式测试编写需要继承 unittest.TestCase 类,方法以 test_ 开…...
B2C API安全警示:爬虫之外,潜藏更大风险挑战
在数字化时代,B2C(Business-to-Consumer)电子商务模式已成为企业连接消费者、推动业务增长的重要桥梁。而B2C API(应用程序编程接口)作为企业与消费者之间数据交互的桥梁,其安全性更是至关重要。然而&#…...
大型语言模型(LLM)中的tokens是什么
大型语言模型(LLM)中的tokens是什么 在大型语言模型(LLM)中,tokens是文本处理的基本单位,它可以是一个单词、一个字符、一个标点符号,或者是一个特殊的标记。以下是关于tokens的详细介绍及举例: 一、tokens的定义和作用 定义:tokens是将文本分割成的一个个有意义的…...