Flutter圆角文本框插件rounded_text_field的使用
Flutter圆角文本框插件rounded_text_field的使用
目录
内容
功能
- ✅ 高亮文本
- ✅ 高亮文本框
- ✅ 高亮文本片段
开始使用
导入包:
import 'package:rounded_text_field/rounded_text_field.dart';
用法
高亮简单文本
RoundedBackgroundText(
'A cool text to be highlighted',
style: const TextStyle(fontWeight: FontWeight.bold),
backgroundColor: Colors.white,
),
多行文本也支持:
RoundedBackgroundText(
'A cool text to be highlighted\nWith two lines or more',
style: const TextStyle(fontWeight: FontWeight.bold),
backgroundColor: Colors.amber,
),
高亮文本框
必须使用TextEditingController
:
RoundedBackgroundTextField(
backgroundColor: Colors.blue,
style: const TextStyle(fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
文本会随着用户输入而高亮。
文本高亮会跟随文本框滚动位置。
高亮文本片段
高亮文本的一部分:
RichText(
text: TextSpan(
text: 'Start your text and ',
children: [
RoundedBackgroundTextSpan(
text: 'highlight something',
backgroundColor: Colors.blue,
),
const TextSpan(text: ' when necessary'),
],
),
),
你可能想知道的
改变圆角半径
可以通过设置innerRadius
和outerRadius
来改变圆角半径:
RoundedBackgroundText(
'A cool text to be highlighted',
style: const TextStyle(fontWeight: FontWeight.bold),
backgroundColor: Colors.white,
innerRadius: 15.0,
outerRadius: 10.0,
),
最大允许值为20.0
。最小值为0.0
。
深入解析
这一部分详细解释了背景绘制的工作原理。
RoundedBackgroundText
并没有在底层使用Text
小部件。相反,它使用了一个自定义文本绘制器来在背景上绘制文本。一旦RoundedBackgroundText
小部件被初始化,文本的行度量就会被计算(参见computeLineMetrics
),并且当文本更改或父容器宽度变化时会重新计算。这在构建时完成,从而为用户提供流畅的体验。
为了绘制背景,会使用之前生成的行度量。每行有四个属性:
x
- 行在大小内的水平起始位置y
- 行在大小内的垂直起始位置width
- 行的水平尺寸height
- 行的垂直尺寸
使用这些值,我们可以为每一行生成背景。背景从左上角到左下角再到右下角再到右上角再到左上角生成。这使得计算角落(内角或外角)变得容易。
内角和外角的半径是根据行高度(由行度量提供)和给定的innerRadius
和outerRadius
动态计算的。默认情况下,innerRadius
为10.0
,outerRadius
为10.0
。为了保持正确的圆润度,这些值必须在0.0
(最小值)和20.0
(最大值)之间,否则绘制将超出范围。
贡献
所有贡献都欢迎!
完整示例代码
以下是一个完整的示例代码,展示了如何使用rounded_text_field
插件:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:rounded_text_field/rounded_background_text.dart';
final _primaryAndAccentColors = [...Colors.primaries, ...Colors.accents];
enum _HighlightTextType { field, text, span, selectableText }
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final ScrollController colorsController;
final controller = TextEditingController();
double fontSize = 20.0;
double innerRadius = kDefaultInnerRadius;
double outerRadius = kDefaultOuterRadius;
TextAlign textAlign = TextAlign.center;
FontWeight fontWeight = FontWeight.bold;
_HighlightTextType type = _HighlightTextType.text;
late Color selectedColor;
[@override](/user/override)
void initState() {
super.initState();
final initialIndex = Random().nextInt(_primaryAndAccentColors.length);
selectedColor = _primaryAndAccentColors[initialIndex];
colorsController = ScrollController(
initialScrollOffset: 40.0 * initialIndex,
);
}
[@override](/user/override)
void dispose() {
controller.dispose();
colorsController.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Rounded Background Showcase',
theme: ThemeData(primarySwatch: Colors.blue, brightness: Brightness.dark),
home: Scaffold(
body: SafeArea(
child: Column(children: [
Material(
child: Row(children: [
const VerticalDivider(),
Expanded(
child: DropdownButton<FontWeight>(
isExpanded: true,
value: fontWeight,
onChanged: (w) => setState(
() => fontWeight = w ?? FontWeight.normal,
),
icon: const Icon(Icons.format_bold),
items: FontWeight.values.map((e) {
return DropdownMenuItem(
value: e,
child: Text('$e'.replaceAll('FontWeight.', '')),
);
}).toList(),
),
),
const VerticalDivider(),
Expanded(
child: DropdownButton<TextAlign>(
value: textAlign,
onChanged: (align) => setState(
() => textAlign = align ?? TextAlign.center,
),
icon: Icon(() {
switch (textAlign) {
case TextAlign.center:
return Icons.format_align_center;
case TextAlign.end:
case TextAlign.right:
return Icons.format_align_right;
case TextAlign.start:
case TextAlign.left:
return Icons.format_align_left;
default:
return null;
}
}()),
isExpanded: true,
items: const [
DropdownMenuItem(
value: TextAlign.start,
child: Text('Start'),
),
DropdownMenuItem(
value: TextAlign.center,
child: Text('Center'),
),
DropdownMenuItem(
value: TextAlign.end,
child: Text('End'),
),
],
),
),
const VerticalDivider(),
Expanded(
child: DropdownButton<_HighlightTextType>(
value: type,
onChanged: (t) => setState(
() => type = t ?? _HighlightTextType.field,
),
icon: const Icon(Icons.text_fields),
isExpanded: true,
items: const [
DropdownMenuItem(
value: _HighlightTextType.field,
child: Text('Field'),
),
DropdownMenuItem(
value: _HighlightTextType.text,
child: Text('Text'),
),
DropdownMenuItem(
value: _HighlightTextType.selectableText,
child: Text('Selectable Text'),
),
DropdownMenuItem(
value: _HighlightTextType.span,
child: Text('Span'),
),
],
),
),
const VerticalDivider(),
]),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
child: () {
final textColor = selectedColor.computeLuminance() > 0.5
? Colors.black
: Colors.white;
switch (type) {
case _HighlightTextType.field:
return RoundedBackgroundTextField(
controller: controller,
backgroundColor: selectedColor,
textAlign: textAlign,
hint: 'Type your text here',
style: TextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: textColor,
),
innerRadius: innerRadius,
outerRadius: outerRadius,
);
case _HighlightTextType.text:
return RoundedBackgroundText(
'''Rounded Background Text Showcase
It handles well all font sizes and weights, as well as text alignments
Contributions are welcome!
Done with so much <3 by [@bdlukaa](/user/bdlukaa)''',
backgroundColor: selectedColor,
textAlign: textAlign,
style: TextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: textColor,
),
innerRadius: innerRadius,
outerRadius: outerRadius,
);
case _HighlightTextType.selectableText:
return RoundedBackgroundText.selectable(
'''Rounded Background Text Showcase
It handles well all font sizes and weights, as well as text alignments
Contributions are welcome!
Done with so much <3 by [@bdlukaa](/user/bdlukaa)''',
backgroundColor: selectedColor,
textAlign: textAlign,
style: TextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: textColor,
),
innerRadius: innerRadius,
outerRadius: outerRadius,
);
case _HighlightTextType.span:
return RichText(
textAlign: textAlign,
text: TextSpan(
text: 'You can use this to ',
style: TextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: Colors.white,
),
children: [
RoundedBackgroundTextSpan(
text: 'highlight important stuff inside a text',
backgroundColor: selectedColor,
innerRadius: innerRadius,
outerRadius: outerRadius,
textAlign: textAlign,
style: TextStyle(
fontSize: fontSize,
fontWeight: fontWeight,
color: textColor,
),
),
const TextSpan(text: ' and stuff like that'),
],
),
);
}
}(),
),
),
),
Row(children: [
GestureDetector(
onTap: () {
colorsController.animateTo(
(colorsController.position.pixels - 40),
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
);
},
child: const Icon(Icons.chevron_left),
),
const Spacer(),
GestureDetector(
onTap: () {
colorsController.animateTo(
(colorsController.position.pixels + 40),
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
);
},
child: const Icon(Icons.chevron_right),
),
]),
Material(
child: SingleChildScrollView(
controller: colorsController,
padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: 8.0),
scrollDirection: Axis.horizontal,
child: Wrap(
runSpacing: 10.0,
spacing: 10.0,
alignment: WrapAlignment.center,
children: _primaryAndAccentColors.map((color) {
return MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: () => setState(() => selectedColor = color),
child: AnimatedContainer(
duration: kThemeChangeDuration,
curve: Curves.bounceInOut,
height: 30.0,
width: 30.0,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(2.0),
border: Border.all(
color: color.computeLuminance() > 0.5
? Colors.black
: Colors.white,
width: 2.5,
style: selectedColor == color
? BorderStyle.solid
: BorderStyle.none,
),
),
),
),
);
}).toList(),
),
),
),
Material(
child: Row(children: [
Expanded(
child: Slider(
onChanged: (v) => setState(() => fontSize = v),
value: fontSize,
min: 8,
max: 30,
divisions: 30 - 8,
label: '${fontSize.toInt()}',
),
),
Expanded(
child: Slider(
onChanged: (v) => setState(() => innerRadius = v),
value: innerRadius,
min: 0,
max: 20,
label: '${innerRadius.toInt()}',
divisions: 20,
),
),
Expanded(
child: Slider(
onChanged: (v) => setState(() => outerRadius = v),
value: outerRadius,
min: 0,
max: 20,
label: '${outerRadius.toInt()}',
divisions: 20,
),
),
]),
),
]),
),
),
);
}
}
更多关于Flutter圆角文本框插件rounded_text_field的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter圆角文本框插件rounded_text_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
rounded_text_field
是一个用于 Flutter 的插件,可以帮助你轻松地创建带有圆角的文本框。它提供了一种简单的方式来定制文本框的外观,包括圆角半径、边框颜色、背景颜色等。
以下是使用 rounded_text_field
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 rounded_text_field
插件的依赖:
dependencies:
flutter:
sdk: flutter
rounded_text_field: ^1.0.0 # 请根据实际情况使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在需要使用 rounded_text_field
的 Dart 文件中导入插件:
import 'package:rounded_text_field/rounded_text_field.dart';
3. 使用 RoundedTextField
你可以在 UI 中使用 RoundedTextField
来创建一个带有圆角的文本框。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:rounded_text_field/rounded_text_field.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Rounded TextField Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: RoundedTextField(
borderRadius: 20.0, // 设置圆角半径
borderColor: Colors.blue, // 设置边框颜色
backgroundColor: Colors.grey[200], // 设置背景颜色
hintText: 'Enter your text here', // 设置提示文本
onChanged: (value) {
// 处理文本变化
print('Text changed: $value');
},
),
),
),
);
}
}