我创建了一个可重用的多行文本组件。我正在使用TextSpan小部件。
代码:
/// Creates multi line styled widget which displays list of items with bullet
class AppMultiLineText extends StatelessWidget {
final List<CustomStyledText> items;
final String semanticsText;
const AppMultiLineText({@required this.items, this.semanticsText}) : assert(items != null);
@override
Widget build(BuildContext context) {
final style = context.appThemeData.bodyCopyDefault.appTextStyle;
final styleBold = context.appThemeData.bodyCopyBold.appTextStyle;
return MergeSemantics(
child: Padding(
padding: context.appThemeData.multilineDisplay.padding,
child: Column(
children: [
_buildRow(context, items, style, styleBold, semanticsText),
],
),
),
);
}
}
Widget _buildRow(BuildContext context, List<CustomStyledText> styledText, AppTextStyle style, AppTextStyle styleBold,
String semanticsText) {
final _padding = EdgeInsets.symmetric(vertical: context.appThemeData.bulletStyle.spaceBetweenLines);
return Semantics(
child: Padding(
padding: _padding,
child: Row(
children: [
_buildBulletSection(context),
_styledWidget(context, styledText, style, styleBold, semanticsText),
],
),
),
);
}
Widget _buildBulletSection(BuildContext context) {
// final textScaleFactor = _textScaleFactor(context);
final _bulletPadding = EdgeInsets.only(
top: context.appThemeData.bulletStyle.bulletOffset, right: context.appThemeData.bulletStyle.spaceAfterBullet);
return Text.rich(
TextSpan(
children: [
WidgetSpan(
child: Padding(
padding: _bulletPadding,
child: _drawBullet(context),
),
),
],
),
//textScaleFactor: textScaleFactor,
);
}
Widget _drawBullet(BuildContext context) {
final _bulletDiameter = context.appThemeData.bulletStyle.bulletDiameter;
return Container(
width: _bulletDiameter,
height: _bulletDiameter,
decoration: BoxDecoration(
color: context.appThemeData.bodyCopyDefault.appTextStyle.textStyle.color,
shape: BoxShape.circle,
),
);
}
Widget _styledWidget(BuildContext context, List<CustomStyledText> styledText, AppTextStyle style,
AppTextStyle styleBold, String semanticsText) {
final scaleFactor = context.calculateScaleFactor(
style.textStyle.fontSize,
style.maximumFontSize,
style.minimumScalingFactor,
);
return Expanded(
child: Text.rich(
TextSpan(
style: style.textStyle,
children: styledText.map((e) {
return TextSpan(
text: e.text,
style: e.isBold
? styleBold.textStyle.copyWith(
letterSpacing: e.isNumeric ? PresentationConstants.numericLetterSpacing : null,
)
: style.textStyle.copyWith(
letterSpacing: e.isNumeric ? PresentationConstants.numericLetterSpacing : null,
),
);
}).toList(),
),
style: style.textStyle,
textScaleFactor: scaleFactor,
textAlign: style.textAlign,
semanticsLabel: semanticsText,
),
);
}
class CustomStyledText {
final String text;
final String styleText;
final bool isBold;
final bool isNumeric;
CustomStyledText(
this.text, {
this.styleText,
this.isBold = false,
this.isNumeric = false,
});
}
class:
AppMultiLineText(
items: [
CustomStyledText(context.appLocalization.listOfRequirementsBodyCopy1),
CustomStyledText(context.appLocalization.listOfRequirementsBodyCopy2),
],
),
],
),
[![在此输入图像描述][1]][1]
这是预期的设计[1] :https://i.stack.imgur.com/AZF3w.png
但我把所有项目都作为段落。
最好使用RichText小部件。提供详细信息
我可以提出另一个解决方案吗?
import 'package:flutter/material.dart';
class CustomList extends StatelessWidget {
final List<Widget> children;
const CustomList({
Key key,
this.children = const [],
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
for (final child in children)
Container(
padding: EdgeInsets.all(10.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(
Icons.circle,
size: 4.0,
),
),
SizedBox(width: 10.0),
Expanded(child: child),
],
),
),
],
);
}
}
把你喜欢的任何小部件传给它的孩子,它会自动附加点:
CustomList(
children: [
Text('My first line of text'),
Text(
'My second line of text which is long enough, long enough, long enough, long enough, long enough, long enough',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.orange,
fontSize: 20.0,
),
),
],
),
-----------Addon----------------
你可以更进一步,添加一个";类型";从无序风格切换到有序风格。
import 'package:flutter/material.dart';
enum CustomListType { Unordered, Ordered }
class CustomList extends StatelessWidget {
final List<Widget> children;
final CustomListType type;
const CustomList({
Key key,
this.children = const [],
this.type = CustomListType.Unordered,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final _children = <Widget>[];
for (var i = 0; i < children.length; i++) {
_children.add(Container(
padding: EdgeInsets.all(10.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
type == CustomListType.Ordered
? Text('${i + 1}.')
: Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(
Icons.circle,
size: 4.0,
),
),
SizedBox(width: 10.0),
Expanded(child: children.elementAt(i)),
],
),
));
}
return Column(
children: _children,
);
}
}
CustomList(
type: CustomListType.Ordered,
children: [
Text('My first line of text'),
Text(
'My second line of text which is long enough, long enough, long enough, long enough, long enough, long enough',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.orange,
fontSize: 20.0,
),
),
],
),