如何为 flutter 包创建新的文本小部件?
how to create new text widget for flutter package?
我需要在 Flutter 中创建自定义文本小部件。我必须更改它在不透明度为 0.7 的样式中接受的任何颜色。如果它没有样式,我必须显示默认样式的颜色,不透明度为 0.7。
最后想打包发布(独立于平台文)可以使用
我的问题是使用我描述的功能创建一个新的文本小部件。
有多种方法可以解决这个问题:
您可以制作基于函数的 Widget 或基于 class 的 Widget:
基于功能的小部件:
Widget myCustomText({required String data, Color? customColor}) {
return Opacity(
opacity: 0.7,
child: Text(
data,
style: TextStyle(
color: customColor ?? Colors.black,
),
),
);
}
另一种方法是制作一个基于 class 的小部件:
class MyCustomText extends StatelessWidget {
final String data;
final Color? customColor;
const MyCustomText({Key? key, required this.data, this.customColor})
: super(key: key);
@override
Widget build(BuildContext context) {
return Opacity(
opacity: 0.7,
child: Text(
data,
style: TextStyle(color: customColor ?? Colors.black),
),
);
}
}
以下是您可以根据需要实施自定义文本的方法:
// 代码 M:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//Widget based Implementation
myCustomTextWidget(data: "Hello world"),
myCustomTextWidget(data: "Hello Peter", customColor: Colors.amber),
//Class based implementation
MyCustomTextClassWidget(data: "Hello Spidey"),
MyCustomTextClassWidget(data: "Hello 007", customColor: Colors.orange,)
],
),
);
}
}
解释:Null(??) 运算符检查是否给定值,如果没有给定,则在它之后使用默认值。
结论:使用基于 Class 的 Widget,即方法 2 更健壮,Flutter 官方团队推荐使用基于 class 的 widget。它也是友好和高性能的重建。
以上代码的输出(M):
工作解决方案只需使用
ThemeData.primaryColor
为默认文字颜色的配置;
- 如果它没有
TextStyle
传递给 CustomTextWidget
,则使用默认文本颜色,不透明度为 0.7;
- 如果它确实有
TextStyle
传递给 CustomTextWidget
,则使用不透明度为 0.7 的 textStyle。
代码在这里:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: const HomeWidget(title: _title),
theme: ThemeData.light().copyWith(
// default text color
primaryColor: Colors.pink,
colorScheme: ColorScheme.fromSwatch().copyWith(
// change the appbar color
primary: Colors.green[800],
),
),
);
}
}
class HomeWidget extends StatelessWidget {
const HomeWidget({
Key? key,
required String title,
}) : _title = title,
super(key: key);
final String _title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_title),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
CustomTextWidget(text: 'text does not have a style'),
CustomTextWidget(
text: 'text with passed black color style and fontSize 24',
textStyle: TextStyle(
fontSize: 24,
color: Colors.black
),
),
CustomTextWidget(
text: 'text with passed blue color style',
textStyle: TextStyle(
color: Colors.blue
),
),
],
),
);
}
}
class CustomTextWidget extends StatelessWidget {
final String text;
final TextStyle? textStyle;
const CustomTextWidget({Key? key, required this.text, this.textStyle}) : super(key: key);
@override
Widget build(BuildContext context) {
final TextStyle finalTextStyle = textStyle ?? const TextStyle();
final Color? finalColor = textStyle != null && textStyle!.color != null
? textStyle!.color
: Theme.of(context).primaryColor;
return Text(
text,
// it accepts in the style with an opacity of 0.7.
style: finalTextStyle.copyWith(color: finalColor!.withOpacity(0.7)),
);
}
}
预期结果:
当没有将 TextStyle 设置为 Text Widget 时,Flutter 使用 DefaultTextStyle class。
我通过这个 class 和扩展解决了问题。
class NewTextWidget extends StatelessWidget {
const NewTextWidget({
Key? key,
required this.textWidget,
}): super(key: key);
final Text textWidget;
@override
Widget build(BuildContext context) {
return Text(textWidget.data! ,style:textWidget.style.colorOpacity(context: context),);
}
}
extension TextStyleOpacity on TextStyle?{
TextStyle colorOpacity ({required BuildContext context}){
Color? color =this==null?DefaultTextStyle.of(context).style.color: this?.color;
if(this==null){
return DefaultTextStyle.of(context).style.copyWith(color: color!.withOpacity(0.7));
}else{
return this!.copyWith(color: color!.withOpacity(0.7));
}
}
}
感谢大家。
我需要在 Flutter 中创建自定义文本小部件。我必须更改它在不透明度为 0.7 的样式中接受的任何颜色。如果它没有样式,我必须显示默认样式的颜色,不透明度为 0.7。 最后想打包发布(独立于平台文)可以使用
我的问题是使用我描述的功能创建一个新的文本小部件。
有多种方法可以解决这个问题:
您可以制作基于函数的 Widget 或基于 class 的 Widget:
基于功能的小部件:
Widget myCustomText({required String data, Color? customColor}) {
return Opacity(
opacity: 0.7,
child: Text(
data,
style: TextStyle(
color: customColor ?? Colors.black,
),
),
);
}
另一种方法是制作一个基于 class 的小部件:
class MyCustomText extends StatelessWidget {
final String data;
final Color? customColor;
const MyCustomText({Key? key, required this.data, this.customColor})
: super(key: key);
@override
Widget build(BuildContext context) {
return Opacity(
opacity: 0.7,
child: Text(
data,
style: TextStyle(color: customColor ?? Colors.black),
),
);
}
}
以下是您可以根据需要实施自定义文本的方法: // 代码 M:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//Widget based Implementation
myCustomTextWidget(data: "Hello world"),
myCustomTextWidget(data: "Hello Peter", customColor: Colors.amber),
//Class based implementation
MyCustomTextClassWidget(data: "Hello Spidey"),
MyCustomTextClassWidget(data: "Hello 007", customColor: Colors.orange,)
],
),
);
}
}
解释:Null(??) 运算符检查是否给定值,如果没有给定,则在它之后使用默认值。
结论:使用基于 Class 的 Widget,即方法 2 更健壮,Flutter 官方团队推荐使用基于 class 的 widget。它也是友好和高性能的重建。
以上代码的输出(M):
工作解决方案只需使用
ThemeData.primaryColor
为默认文字颜色的配置;- 如果它没有
TextStyle
传递给CustomTextWidget
,则使用默认文本颜色,不透明度为 0.7; - 如果它确实有
TextStyle
传递给CustomTextWidget
,则使用不透明度为 0.7 的 textStyle。
代码在这里:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: const HomeWidget(title: _title),
theme: ThemeData.light().copyWith(
// default text color
primaryColor: Colors.pink,
colorScheme: ColorScheme.fromSwatch().copyWith(
// change the appbar color
primary: Colors.green[800],
),
),
);
}
}
class HomeWidget extends StatelessWidget {
const HomeWidget({
Key? key,
required String title,
}) : _title = title,
super(key: key);
final String _title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_title),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
CustomTextWidget(text: 'text does not have a style'),
CustomTextWidget(
text: 'text with passed black color style and fontSize 24',
textStyle: TextStyle(
fontSize: 24,
color: Colors.black
),
),
CustomTextWidget(
text: 'text with passed blue color style',
textStyle: TextStyle(
color: Colors.blue
),
),
],
),
);
}
}
class CustomTextWidget extends StatelessWidget {
final String text;
final TextStyle? textStyle;
const CustomTextWidget({Key? key, required this.text, this.textStyle}) : super(key: key);
@override
Widget build(BuildContext context) {
final TextStyle finalTextStyle = textStyle ?? const TextStyle();
final Color? finalColor = textStyle != null && textStyle!.color != null
? textStyle!.color
: Theme.of(context).primaryColor;
return Text(
text,
// it accepts in the style with an opacity of 0.7.
style: finalTextStyle.copyWith(color: finalColor!.withOpacity(0.7)),
);
}
}
预期结果:
当没有将 TextStyle 设置为 Text Widget 时,Flutter 使用 DefaultTextStyle class。
我通过这个 class 和扩展解决了问题。
class NewTextWidget extends StatelessWidget {
const NewTextWidget({
Key? key,
required this.textWidget,
}): super(key: key);
final Text textWidget;
@override
Widget build(BuildContext context) {
return Text(textWidget.data! ,style:textWidget.style.colorOpacity(context: context),);
}
}
extension TextStyleOpacity on TextStyle?{
TextStyle colorOpacity ({required BuildContext context}){
Color? color =this==null?DefaultTextStyle.of(context).style.color: this?.color;
if(this==null){
return DefaultTextStyle.of(context).style.copyWith(color: color!.withOpacity(0.7));
}else{
return this!.copyWith(color: color!.withOpacity(0.7));
}
}
}
感谢大家。