Compare commits
No commits in common. 'master' and 'null_safety' have entirely different histories.
master
...
null_safet
@ -1,4 +1,3 @@
|
||||
{
|
||||
"flutterSdkVersion": "2.8.1",
|
||||
"flavors": {}
|
||||
"flutterSdkVersion": "stable"
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"dart.flutterSdkPath": "/Users/zhangmeng/fvm/versions/2.0.2"
|
||||
"dart.flutterSdkPath": "/Users/akufe/fvm/versions/stable"
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
"flutterSdkVersion": "2.2.0",
|
||||
"flavors": {}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import 'package:ansu_ui/extension/list_extension.dart';
|
||||
import 'package:example/codeviewer/code_segments.dart';
|
||||
import 'package:example/component/example_scaffold.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
|
||||
class ExampleListExt extends StatefulWidget {
|
||||
const ExampleListExt({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ExampleListExtState createState() => _ExampleListExtState();
|
||||
}
|
||||
|
||||
class _ExampleListExtState extends State<ExampleListExt> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ExampleScaffold(
|
||||
title: 'String Ext',
|
||||
text: (context) => CodeSegments.stringExt(context),
|
||||
children: [
|
||||
Container(
|
||||
color: Colors.blue,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
child: Text('1'),
|
||||
),
|
||||
Visibility(
|
||||
visible: true,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
child: Text('2'),
|
||||
),
|
||||
),
|
||||
Offstage(
|
||||
offstage: true,
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
child: Text('2'),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
child: Text('3'),
|
||||
),
|
||||
].sepWidget(separate: 10.w.heightBox),
|
||||
),
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import 'package:ansu_ui/ansu_ui.dart';
|
||||
import 'package:ansu_ui/chart/circle_chart_widget.dart';
|
||||
import 'package:example/codeviewer/code_segments.dart';
|
||||
import 'package:example/common/code_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class ExampleChart extends StatefulWidget {
|
||||
const ExampleChart({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ExampleChartState createState() => _ExampleChartState();
|
||||
}
|
||||
|
||||
class _ExampleChartState extends State<ExampleChart> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ASScaffold(
|
||||
title: 'chart',
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.code, color: Colors.black54),
|
||||
onPressed: () => Get.to(CodeView(
|
||||
text: (context) => CodeSegments.button(context),
|
||||
)),
|
||||
),
|
||||
],
|
||||
body: ListView(
|
||||
children: [
|
||||
20.hb,
|
||||
ListTile(
|
||||
title: Text('circle chart'),
|
||||
trailing: Container(
|
||||
width: 50.w,
|
||||
height: 50.w,
|
||||
child: CircleChart(
|
||||
size: 40.w,
|
||||
color: Colors.red,
|
||||
aboveStrokeWidth: 10.w,
|
||||
core: '65%'.text.size(20.sp).color(kTextColor).make(),
|
||||
aspectRato: 0.65,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
import 'package:ansu_ui/ansu_ui.dart';
|
||||
import 'package:ansu_ui/divider/as_dotted_divider.dart';
|
||||
import 'package:example/codeviewer/code_segments.dart';
|
||||
import 'package:example/common/code_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class ExampleDivider extends StatefulWidget {
|
||||
ExampleDivider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ExampleDividerState createState() => _ExampleDividerState();
|
||||
}
|
||||
|
||||
class _ExampleDividerState extends State<ExampleDivider> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ASScaffold(
|
||||
title: '分割线',
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.code, color: Colors.black54),
|
||||
onPressed: () => Get.to(CodeView(
|
||||
text: (context) => CodeSegments.button(context),
|
||||
)),
|
||||
),
|
||||
],
|
||||
body: Center(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
child: 'ASDivider'.text.make(),
|
||||
),
|
||||
ASDivider(
|
||||
color: Colors.black,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
).expand(),
|
||||
ASVDivider(),
|
||||
Container(
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
).expand(),
|
||||
],
|
||||
),
|
||||
ASDivider(),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 50.w,
|
||||
color: Colors.red,
|
||||
child: 'ASDottedDivider'.text.make(),
|
||||
),
|
||||
ASDottedDivider.horizontal(
|
||||
color: Colors.black,
|
||||
),
|
||||
Container(
|
||||
height: 100.w,
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
color: Colors.red,
|
||||
).expand(),
|
||||
ASDottedDivider.vertical(
|
||||
color: Colors.black,
|
||||
),
|
||||
Container(
|
||||
color: Colors.red,
|
||||
).expand(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,63 +1,77 @@
|
||||
library ansu_ui;
|
||||
|
||||
export 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
//third party
|
||||
export 'package:velocity_x/velocity_x.dart';
|
||||
|
||||
export 'badge/as_badge.dart';
|
||||
export 'bar/as_navigation_bar.dart';
|
||||
export 'bar/as_navigation_item.dart';
|
||||
export 'bar/as_tabbar.dart';
|
||||
export 'bar/as_tabbar_item.dart';
|
||||
export 'box/as_check_box.dart';
|
||||
export 'buttons/as_back_button.dart';
|
||||
export 'buttons/as_bottom_button.dart';
|
||||
//buttons
|
||||
export 'buttons/as_button.dart';
|
||||
export 'buttons/as_check_button.dart';
|
||||
export 'buttons/as_gradient_button.dart';
|
||||
export 'buttons/as_long_button.dart';
|
||||
export 'buttons/as_material_button.dart';
|
||||
export 'buttons/as_back_button.dart';
|
||||
export 'buttons/as_numeric_button.dart';
|
||||
export 'buttons/as_bottom_button.dart';
|
||||
export 'buttons/as_gradient_button.dart';
|
||||
export 'buttons/as_radio_button.dart';
|
||||
export 'dialog/as_bottom_dialog.dart';
|
||||
export 'dialog/as_bottom_dialog_item.dart';
|
||||
export 'dialog/as_delete_dialog.dart';
|
||||
export 'buttons/as_material_button.dart';
|
||||
export 'buttons/as_check_button.dart';
|
||||
|
||||
//scaffold
|
||||
export 'scaffold/as_scaffold.dart';
|
||||
|
||||
export 'styles/as_colors.dart';
|
||||
|
||||
export 'bar/as_tabbar.dart';
|
||||
export 'bar/as_tabbar_item.dart';
|
||||
export 'bar/as_navigation_bar.dart';
|
||||
export 'bar/as_navigation_item.dart';
|
||||
|
||||
export 'drawer/as_drawer.dart';
|
||||
|
||||
export 'toast/as_toast.dart';
|
||||
|
||||
export 'pickers/as_date_picker.dart';
|
||||
export 'pickers/as_picker_box.dart';
|
||||
export 'pickers/as_two_date_picker.dart';
|
||||
export 'pickers/as_date_range_picker_part.dart';
|
||||
|
||||
export 'dialog/as_dialog.dart';
|
||||
export 'dialog/as_dialog_button.dart';
|
||||
export 'dialog/as_delete_dialog.dart';
|
||||
export 'dialog/as_bottom_dialog.dart';
|
||||
export 'dialog/as_bottom_dialog_item.dart';
|
||||
export 'dialog/as_show_bottom_dialog.dart';
|
||||
export 'divider/as_divider.dart';
|
||||
export 'drawer/as_drawer.dart';
|
||||
export 'extension/Text_extension.dart';
|
||||
export 'extension/image_extension.dart';
|
||||
export 'extension/list_extension.dart';
|
||||
export 'extension/num_extension.dart';
|
||||
export 'extension/string_extension.dart';
|
||||
export 'extension/text_style_extension.dart';
|
||||
export 'extension/widget_extension.dart';
|
||||
export 'list_tile/as_card_expandable.dart';
|
||||
export 'list_tile/as_edit_tile.dart';
|
||||
|
||||
export 'list_tile/as_list_tile.dart';
|
||||
export 'list_tile/as_list_tile_x.dart';
|
||||
export 'list_tile/as_option_tile.dart';
|
||||
export 'list_tile/as_edit_tile.dart';
|
||||
export 'list_tile/as_option_tile_item.dart';
|
||||
export 'list_tile/as_vertical_tile_item.dart';
|
||||
export 'pickers/as_date_picker.dart';
|
||||
export 'pickers/as_date_range_picker_part.dart';
|
||||
export 'pickers/as_picker_box.dart';
|
||||
export 'pickers/as_two_date_picker.dart';
|
||||
export 'pop_up_menu/pop_up_menu.dart';
|
||||
export 'list_tile/as_list_tile_x.dart';
|
||||
export 'list_tile/as_card_expandable.dart';
|
||||
|
||||
export 'refresh/as_refresh.dart';
|
||||
//scaffold
|
||||
export 'scaffold/as_scaffold.dart';
|
||||
export 'styles/as_colors.dart';
|
||||
export 'tag/as_check_tag.dart';
|
||||
|
||||
export 'box/as_check_box.dart';
|
||||
|
||||
export 'pop_up_menu/pop_up_menu.dart';
|
||||
|
||||
export 'tag/as_tag.dart';
|
||||
export 'tag/as_check_tag.dart';
|
||||
|
||||
export 'divider/as_divider.dart';
|
||||
export 'text_field/as_search_text_field.dart';
|
||||
export 'theme/as_theme.dart';
|
||||
export 'toast/as_toast.dart';
|
||||
export 'utils/as_grid_image_view.dart';
|
||||
export 'badge/as_badge.dart';
|
||||
|
||||
export 'utils/screen_adapter.dart';
|
||||
export 'utils/camera_util.dart';
|
||||
export 'utils/camera_view.dart';
|
||||
export 'utils/photo_viewer.dart';
|
||||
export 'utils/screen_adapter.dart';
|
||||
|
||||
export 'extension/num_extension.dart';
|
||||
export 'extension/list_extension.dart';
|
||||
export 'extension/widget_extension.dart';
|
||||
export 'extension/string_extension.dart';
|
||||
export 'extension/text_style_extension.dart';
|
||||
export 'extension/image_extension.dart';
|
||||
|
||||
export 'theme/as_theme.dart';
|
||||
|
||||
//third party
|
||||
export 'package:velocity_x/velocity_x.dart';
|
||||
export 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
@ -1,56 +0,0 @@
|
||||
import 'package:ansu_ui/painters/circle_chart_painter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class CircleChart extends StatelessWidget {
|
||||
final double? size;
|
||||
|
||||
///角度
|
||||
final double aspectRato;
|
||||
|
||||
///底部圆圈的宽度
|
||||
final double? underStrokeWidth;
|
||||
|
||||
///弧的宽度
|
||||
final double? aboveStrokeWidth;
|
||||
|
||||
///弧的颜色
|
||||
final Color color;
|
||||
|
||||
///圆圈中间显示的组件
|
||||
final Widget core;
|
||||
|
||||
const CircleChart(
|
||||
{Key? key,
|
||||
this.size,
|
||||
required this.aspectRato,
|
||||
this.underStrokeWidth,
|
||||
this.aboveStrokeWidth,
|
||||
required this.color,
|
||||
required this.core})
|
||||
: super(key: key);
|
||||
|
||||
double get customSize => size ?? 100.w;
|
||||
|
||||
double get customUnderWidth => underStrokeWidth ?? 5.w;
|
||||
|
||||
double get customAboveWidth => aboveStrokeWidth ?? 15.w;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: customSize,
|
||||
height: customSize,
|
||||
child: CustomPaint(
|
||||
painter: CircleChartPainter(
|
||||
underStrokeWidth: customUnderWidth,
|
||||
aboveStrokeWidth: customAboveWidth,
|
||||
radius: aspectRato,
|
||||
aboveColor: color),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: core,
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class ASDottedDivider extends StatelessWidget {
|
||||
final Axis axis;
|
||||
final List<int>? dash;
|
||||
final Color? color;
|
||||
final double? dashWidth;
|
||||
final double? strokeWidth;
|
||||
const ASDottedDivider({
|
||||
required this.axis,
|
||||
this.dash = const <int>[2, 1],
|
||||
this.color = const Color(0xFFD8D8D8),
|
||||
this.dashWidth,
|
||||
this.strokeWidth,
|
||||
});
|
||||
|
||||
ASDottedDivider.horizontal({
|
||||
this.dashWidth,
|
||||
this.strokeWidth,
|
||||
this.color = const Color(0xFFD8D8D8),
|
||||
}) : this.axis = Axis.horizontal,
|
||||
this.dash = const <int>[2, 1];
|
||||
|
||||
ASDottedDivider.vertical({
|
||||
this.dashWidth,
|
||||
this.strokeWidth,
|
||||
this.color = const Color(0xFFD8D8D8),
|
||||
}) : this.axis = Axis.vertical,
|
||||
this.dash = const <int>[2, 1];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LayoutBuilder(builder: (context, boxConstraints) {
|
||||
final boxWidth = this.axis == Axis.horizontal
|
||||
? boxConstraints.constrainWidth()
|
||||
: boxConstraints.constrainHeight();
|
||||
final _dashWidth = dashWidth ?? 10.w;
|
||||
final _dashPattern = (1 + dash![1] / dash![0]);
|
||||
final int count =
|
||||
(( boxWidth) / (_dashWidth * _dashPattern)).floor();
|
||||
return Flex(
|
||||
direction: axis,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: List.generate(
|
||||
count,
|
||||
(_) => SizedBox(
|
||||
width: this.axis == Axis.horizontal
|
||||
? _dashWidth
|
||||
: strokeWidth ?? 1.w,
|
||||
height: this.axis == Axis.horizontal
|
||||
? strokeWidth ?? 1.w
|
||||
: _dashWidth,
|
||||
child:
|
||||
DecoratedBox(decoration: BoxDecoration(color: color)),
|
||||
)));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
import 'package:ansu_ui/utils/match_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension TextSpanExt on TextSpan {
|
||||
TextSpan match(String match) {
|
||||
return MatchText(matchText: match, text: this.text ?? '', style: this.style)
|
||||
.matchSpan();
|
||||
}
|
||||
}
|
@ -1,45 +1,11 @@
|
||||
import 'package:ansu_ui/utils/match_text.dart';
|
||||
import 'package:auto_size_text_pk/auto_size_text_pk.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'Text_extension.dart';
|
||||
|
||||
extension WidgetExt on Widget {
|
||||
Widget paddingExt(double horizontal, [double vertical = 0]) =>
|
||||
Padding(
|
||||
Widget paddingExt(double horizontal, [double vertical = 0]) => Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: horizontal,
|
||||
vertical: vertical,
|
||||
),
|
||||
child: this,
|
||||
);
|
||||
|
||||
Widget match(String match) {
|
||||
if (this.runtimeType == Text) {
|
||||
// var spans = (this as Text).textSpan;
|
||||
// if (spans != null) {
|
||||
// spans = spans.match(match);
|
||||
// return Text.rich(spans);
|
||||
// }
|
||||
return MatchText(
|
||||
matchText: match,
|
||||
text: (this as Text).data ?? '',
|
||||
style: (this as Text).style,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.runtimeType == AutoSizeText) {
|
||||
var spans = (this as AutoSizeText).textSpan;
|
||||
if (spans != null) {
|
||||
spans = spans.match(match);
|
||||
return AutoSizeText.rich(spans);
|
||||
}
|
||||
return MatchText(
|
||||
matchText: match,
|
||||
text: (this as AutoSizeText).data ?? '',
|
||||
style: (this as AutoSizeText).style,
|
||||
);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CircleChartPainter extends CustomPainter {
|
||||
final double underStrokeWidth;
|
||||
final double aboveStrokeWidth;
|
||||
final double radius;
|
||||
final Color aboveColor;
|
||||
|
||||
CircleChartPainter(
|
||||
{required this.underStrokeWidth,
|
||||
required this.aboveStrokeWidth,
|
||||
required this.radius,
|
||||
required this.aboveColor});
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
var offset = Offset(size.width / 2, size.height / 2);
|
||||
var paint = Paint()
|
||||
..strokeWidth = underStrokeWidth
|
||||
..style = PaintingStyle.stroke
|
||||
..color = Color(0xFFCECECE);
|
||||
canvas.drawCircle(offset, size.width / 2, paint);
|
||||
paint
|
||||
..strokeWidth = aboveStrokeWidth
|
||||
..strokeCap = StrokeCap.round
|
||||
..color = aboveColor;
|
||||
var rect = Rect.fromCircle(center: offset, radius: size.width / 2);
|
||||
canvas.drawArc(rect, -pi / 2, 2 * pi * radius, false, paint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:ansu_ui/ansu_ui.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class AsGridImageView extends StatelessWidget {
|
||||
final List<File>? files;
|
||||
final List<String>? nets;
|
||||
final String? placeholder;
|
||||
final void Function(dynamic value)? onDelete;
|
||||
final double? iconSize;
|
||||
|
||||
const AsGridImageView.fromFile({Key? key,
|
||||
required this.files,
|
||||
this.placeholder,
|
||||
this.onDelete,
|
||||
this.iconSize})
|
||||
: nets = null,
|
||||
super(key: key);
|
||||
|
||||
const AsGridImageView.fromNets({Key? key,
|
||||
required this.nets,
|
||||
this.placeholder,
|
||||
this.onDelete,
|
||||
this.iconSize})
|
||||
: files = null,
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var size = iconSize ?? 16.w;
|
||||
return GridView(
|
||||
padding: EdgeInsets.all(10.w),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 10.w,
|
||||
crossAxisSpacing: 10.w,
|
||||
),
|
||||
shrinkWrap: true,
|
||||
children: files == null
|
||||
? nets!
|
||||
.map((e) =>
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
PhotoViewer.fromNet(
|
||||
context,
|
||||
tag: e,
|
||||
net: e,
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
Hero(
|
||||
tag: e,
|
||||
child: FadeInImage.assetNetwork(
|
||||
placeholder: placeholder ?? '', image: e),
|
||||
),
|
||||
if(onDelete != null) Positioned(
|
||||
top: size / 2,
|
||||
right: size / 2,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
onDelete!(e);
|
||||
},
|
||||
child: Icon(
|
||||
CupertinoIcons.xmark_circle_fill,
|
||||
color: Colors.black45,
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
))
|
||||
.toList()
|
||||
: files!
|
||||
.map((e) =>
|
||||
Stack(children: [
|
||||
if(onDelete != null) Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
onDelete!(e);
|
||||
},
|
||||
child: Icon(
|
||||
CupertinoIcons.xmark_circle_fill,
|
||||
color: Colors.black45,
|
||||
),
|
||||
)),
|
||||
GestureDetector(
|
||||
onTap: () =>
|
||||
PhotoViewer.fromFile(context,
|
||||
tag: e.path, file: e),
|
||||
child: Hero(tag: e.path, child: Image.file(e)))
|
||||
]))
|
||||
.toList());
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import 'package:ansu_ui/ansu_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MatchText extends StatelessWidget {
|
||||
final String matchText;
|
||||
final String text;
|
||||
final TextStyle? style;
|
||||
|
||||
const MatchText({
|
||||
Key? key,
|
||||
required this.matchText,
|
||||
required this.text,
|
||||
this.style,
|
||||
}) : super(key: key);
|
||||
|
||||
TextSpan matchSpan() {
|
||||
return TextSpan(children: getSpans());
|
||||
}
|
||||
|
||||
List<TextSpan> getSpans() {
|
||||
var textStyle = style ?? TextStyle(color: kTextColor, fontSize: 14.sp);
|
||||
if (matchText.isEmpty) {
|
||||
return [TextSpan(text: text, style: textStyle)];
|
||||
}
|
||||
List<TextSpan> allSpan = text
|
||||
.replaceAllMapped(matchText, (Match mt) => '\r${mt[0]}\r')
|
||||
.split('\r')
|
||||
.map<TextSpan>(
|
||||
(e) => (matchText.matchAsPrefix(e) == null || e.length == text.length)
|
||||
? TextSpan(text: e, style: textStyle)
|
||||
: TextSpan(text: e, style: textStyle.copyWith(color: Colors.red)),
|
||||
)
|
||||
.toList();
|
||||
return allSpan;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RichText(text: TextSpan(children: getSpans()));
|
||||
}
|
||||
}
|
Loading…
Reference in new issue