blockBuilder method
Implementation
Widget blockBuilder(BuildContext context, Block block) {
Text textView;
var textTheme = Theme.of(context).textTheme;
TextStyle textStyle;
switch (block.type) {
case BlockType.h1:
textStyle = textTheme.displayLarge ?? defaultStyle;
break;
case BlockType.h2:
textStyle = textTheme.displayMedium ?? defaultStyle;
break;
case BlockType.h3:
textStyle = textTheme.displaySmall ?? defaultStyle;
break;
case BlockType.h4:
textStyle = textTheme.headlineMedium ?? defaultStyle;
break;
case BlockType.h5:
textStyle = textTheme.headlineSmall ?? defaultStyle;
break;
case BlockType.h6:
textStyle = textTheme.titleLarge ?? defaultStyle;
break;
case BlockType.code:
textStyle = defaultStyle.copyWith(fontWeight: FontWeight.w500, color: Colors.grey.shade700);
break;
case BlockType.quote:
textStyle = TextStyle(
fontSize: 14,
color: Colors.grey.shade600,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w500,
);
break;
default:
textStyle = textTheme.bodyMedium ?? defaultStyle;
break;
}
if (block.inlineStyle.isNotEmpty) {
var styleMap = block.textStyleMap(textStyle);
textView = Text.rich(
TextSpan(children: styleMap.map((entry) => TextSpan(text: entry.key, style: entry.value)).toList()),
textAlign: block.data.textAlign);
} else {
textView = Text(block.text, style: textStyle, textAlign: block.data.textAlign);
}
if (!block.data.isEmpty && block.data.textIndent != 0) {
return Padding(
padding: EdgeInsets.only(left: TextUtil.measureText('缩进', textStyle).width * block.data.textIndent),
child: textView,
);
}
// 引用块
if (block.type == BlockType.quote) {
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey.shade100, border: Border(left: BorderSide(color: Colors.grey.shade300, width: 5))),
child: textView,
);
}
if (block.type == BlockType.code) {
return Container(
padding: const EdgeInsets.all(12),
color: Colors.grey.shade100,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: textView,
),
);
}
// 无序列表
if (block.type == BlockType.bulletList) {
var size = TextUtil.measureText('缩进', textStyle);
double dotSize = 5;
const solid = BoxDecoration(color: Colors.black, shape: BoxShape.circle);
var hollow = BoxDecoration(shape: BoxShape.circle, border: Border.all(color: Colors.black));
Widget dot = Container(
width: dotSize,
height: dotSize,
margin: EdgeInsets.only(right: dotSize),
decoration: block.depth > 0 ? hollow : solid,
);
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox.fromSize(
size: Size(size.width * block.depth + dotSize * 2, size.height),
child: Align(alignment: Alignment.centerRight, child: dot),
),
textView,
],
);
}
if (block.type == BlockType.numberList) {
var size = TextUtil.measureText('缩进', textStyle);
Text numberView = Text('${block.data.number}.', style: textStyle);
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox.fromSize(
size: Size(size.width * block.depth + size.width / 2, size.height),
child: Align(alignment: Alignment.centerRight, child: numberView),
),
Expanded(child: textView),
],
);
}
if (block.entityRanges.isNotEmpty) {
List<Widget> children = [];
String text = block.text;
var entityMap = data.entityMap;
for (var range in block.entityRanges) {
var entity = entityMap["${range.key}"];
if (entity == null) continue;
switch (entity.type) {
case EntityType.image:
Image image = Image.network(
entity.data.url!,
width: MediaQuery.of(context).size.width,
fit: BoxFit.scaleDown,
);
children.add(image);
if (entity.data.name?.isNotEmpty ?? false) {
children.add(Text(entity.data.name!, style: textStyle, textAlign: TextAlign.center));
}
break;
case EntityType.divider:
Divider divider = const Divider();
children.add(divider);
break;
case EntityType.link:
textView = Text.rich(
TextSpan(
children: [
TextSpan(text: text.substring(0, range.offset)),
TextSpan(
text: text.substring(range.offset, range.offset + range.length),
style: textStyle.copyWith(color: Colors.blue, decoration: TextDecoration.underline),
recognizer: TapGestureRecognizer()..onTap = () => onLinkTab?.call(entity.data.url ?? ""),
),
TextSpan(text: text.substring(range.offset + range.length)),
],
),
textAlign: block.data.textAlign,
);
children.add(textView);
break;
}
}
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
);
}
return textView;
}