import 'dart:convert'; import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:liftmanager/internal/bbs/bbs_router.dart'; import 'package:liftmanager/internal/bbs/model/expert_comment_model.dart' as comment; import 'package:liftmanager/internal/bbs/model/expert_model.dart'; import 'package:liftmanager/internal/bbs/presenter/expert_comment_list_presenter.dart'; import 'package:liftmanager/internal/search/presenter/base_list_provider.dart'; import 'package:liftmanager/mvp/base_page_state.dart'; import 'package:liftmanager/net/api_service.dart'; import 'package:liftmanager/res/resources.dart'; import 'package:liftmanager/routers/fluro_navigator.dart'; import 'package:liftmanager/utils/theme_utils.dart'; import 'package:liftmanager/utils/time_format.dart'; import 'package:liftmanager/utils/toast.dart'; import 'package:liftmanager/widgets/app_bar.dart'; import 'package:liftmanager/widgets/clip_widgets.dart'; import 'package:liftmanager/widgets/load_image.dart'; import 'package:liftmanager/widgets/my_refresh_list.dart'; import 'package:liftmanager/widgets/star_item.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; class ExpertDetail extends StatefulWidget { ExpertDetail(this.id); final String id; @override ExpertDetailState createState() => ExpertDetailState(); } class ExpertDetailState extends BasePageState { BaseListProvider provider = BaseListProvider(); // ExpertListState({Key key}) : super(key: key); ScrollController _scrollController; int listLength = 0; List labelList = ["特邀专家", "回复及时"]; @override void initState() { super.initState(); getExpertDetail(); _onRefresh(); } bool _hasData = false; bool kaiType = false; int _page = 1; Records detailObj; Future getExpertDetail() async { await NewApiService().getExpertDetail(widget.id, onSuccess: (res) { if (res != null) { _hasData = true; detailObj = res; print(123456); print(jsonEncode(res)); setState(() {}); } }, onError: (code, msg) { toasts(msg); }); } @override Widget build(BuildContext context) { double width = MediaQuery.of(context).size.width; double height = MediaQuery.of(context).size.height; return ChangeNotifierProvider>( create: (_) => provider, child: Scaffold( appBar: MyAppBar( centerTitle: '专家详情', // title: '专家详情', actions: [ // FlatButton( // child: Icon( // IconData( // 0xe6f4, // fontFamily:"Iconfont" // ), // size: 26.0, // color:Color.fromRGBO(255, 255, 255, 1), // ), // textColor: Colours.dark_text, // highlightColor: Colors.transparent, // onPressed: () { // }, // ) ], ), body: Container( child: _hasData ? Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // provider.list.length<1?expertDetailWisget():Container(child: null,), expertDetailWisget(), listLength == 0 ? Expanded( child: ListView( children: [ Column(children: [ Container( padding: EdgeInsets.only( left: ScreenUtil().setWidth(20), right: ScreenUtil().setWidth(15), top: ScreenUtil().setWidth(10), bottom: ScreenUtil().setWidth(10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours.line), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( padding: EdgeInsets.only( right: 5), child: LoadAssetImage( // image: AssetImage(i['img']), "expert_three", width: ScreenUtil() .setWidth(32), height: ScreenUtil() .setWidth(32), // alignment: Alignment.centerLeft, ), ), Text( "专家简介", style: TextStyle( fontSize: ScreenUtil() .setSp(17)), textAlign: TextAlign.start, ), // Text( // "奥的斯", // style: TextStyle( // color:Color(0xff999999), // fontSize:18 // ), // textAlign:TextAlign.start, // ), ]), ), !kaiType ? Container( width: width, padding: EdgeInsets.only( left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth(15), top: ScreenUtil() .setWidth(10)), child: Text( detailObj.introduction ?? '暂无', style: TextStyle( color: Color(0xff999999), fontSize: ScreenUtil() .setSp(14)), textAlign: TextAlign.start, maxLines: 2, overflow: TextOverflow.ellipsis, ), ) : Container( width: width, padding: EdgeInsets.only( left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth(15), top: ScreenUtil() .setWidth(10)), child: Text( detailObj.introduction ?? '暂无', style: TextStyle( color: Color(0xff999999), fontSize: ScreenUtil() .setSp(14)), textAlign: TextAlign.start, ), ), // !kaiType? InkWell( onTap: () { setState(() { kaiType = !kaiType; }); }, child: Container( color: Color(0x195887FF), // this.bgcolor =const Color(0x195887FF), // this.textcolor= const Color(0xff5887FF), padding: EdgeInsets.only( right: 20, bottom: 10), width: width, child: Text( !kaiType ? "展开" : "收起", style: TextStyle( color: Color(0xff5887FF), fontSize: ScreenUtil().setSp(14)), textAlign: TextAlign.end, ), ), ) // :Container(child: null,) , Container( height: 5, color: ThemeUtils .getDialogTextFieldColor( context), child: null, ), Container( padding: EdgeInsets.only( left: ScreenUtil().setWidth(20), right: ScreenUtil().setWidth(15), top: ScreenUtil().setWidth(10), bottom: ScreenUtil().setWidth(10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours.line), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( padding: EdgeInsets.only( right: 5), child: LoadAssetImage( // image: AssetImage(i['img']), "expert_two", width: ScreenUtil() .setWidth(32), height: ScreenUtil() .setWidth(32), // alignment: Alignment.centerLeft, ), ), Text( "执业经历", style: TextStyle( fontSize: ScreenUtil() .setSp(17)), textAlign: TextAlign.start, ), // Text( // "奥的斯", // style: TextStyle( // color:Color(0xff999999), // fontSize:18 // ), // textAlign:TextAlign.start, // ), ]), ), Container( width: width, padding: EdgeInsets.only( left: ScreenUtil().setWidth(20), right: ScreenUtil().setWidth(15), top: ScreenUtil().setWidth(10), bottom: ScreenUtil().setWidth(10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 5, color: ThemeUtils .getDialogTextFieldColor( context)), ), ), child: Text( detailObj.experience ?? '暂无', style: TextStyle( color: Color(0xff999999), fontSize: ScreenUtil().setSp(14)), textAlign: TextAlign.start, ), ), Container( padding: EdgeInsets.only( left: ScreenUtil().setWidth(20), right: ScreenUtil().setWidth(15), top: ScreenUtil().setWidth(10), bottom: ScreenUtil().setWidth(10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours.line), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( padding: EdgeInsets.only( right: 5), child: LoadAssetImage( // image: AssetImage(i['img']), "expert_one", width: ScreenUtil() .setWidth(32), height: ScreenUtil() .setWidth(32), // alignment: Alignment.centerLeft, ), ), Text( "用户评价", style: TextStyle( fontSize: ScreenUtil() .setSp(17)), textAlign: TextAlign.start, ), ]), ), Center( child: Container( padding: EdgeInsets.only(top: 10), child: Text( '无数据', style: TextStyle( color: Color(0xff999999), fontSize: ScreenUtil().setSp(14)), textAlign: TextAlign.start, ), )), ]) ], ), ) : Container( child: null, ), listLength != 0 ? Expanded( flex: 1, child: Consumer< BaseListProvider>( builder: (_, provider, __) { return MyListView( key: Key('expert_comment_list'), pageSize: 4, normal: false, itemCount: provider.list.length, stateType: provider.stateType, onRefresh: _onRefresh, loadMore: _loadMore, hasMore: provider.hasMore, itemBuilder: (_, index) { return Container( child: Column( children: [ index == 0 ? Column(children: [ Container( padding: EdgeInsets.only( left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth( 15), top: ScreenUtil() .setWidth(10), bottom: ScreenUtil() .setWidth( 10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours .line), ), ), child: Row( mainAxisAlignment: MainAxisAlignment .start, children: < Widget>[ Container( padding: EdgeInsets .only( right: 5), child: LoadAssetImage( // image: AssetImage(i['img']), "expert_three", width: ScreenUtil() .setWidth( 32), height: ScreenUtil() .setWidth( 32), // alignment: Alignment.centerLeft, ), ), Text( "专家简介", style: TextStyle( fontSize: ScreenUtil() .setSp(17)), textAlign: TextAlign .start, ), // Text( // "奥的斯", // style: TextStyle( // color:Color(0xff999999), // fontSize:18 // ), // textAlign:TextAlign.start, // ), ]), ), !kaiType ? Container( width: width, padding: EdgeInsets.only( left: ScreenUtil() .setWidth( 20), right: ScreenUtil() .setWidth( 15), top: ScreenUtil() .setWidth( 10)), child: Text( detailObj .introduction ?? '暂无', style: TextStyle( color: Color( 0xff999999), fontSize: ScreenUtil() .setSp(14)), textAlign: TextAlign .start, maxLines: 2, overflow: TextOverflow .ellipsis, ), ) : Container( width: width, padding: EdgeInsets.only( left: ScreenUtil() .setWidth( 20), right: ScreenUtil() .setWidth( 15), top: ScreenUtil() .setWidth( 10)), child: Text( detailObj .introduction ?? '暂无', style: TextStyle( color: Color( 0xff999999), fontSize: ScreenUtil() .setSp(14)), textAlign: TextAlign .start, ), ), !kaiType ? InkWell( onTap: () { setState(() { kaiType = true; }); }, child: Row( children: [ Expanded( child: Container()), Container( color: Color( 0x195887FF), padding: EdgeInsets.only( right: 5, left: 5, bottom: 3, top: 3), // width: width, child: Text( "展开", style: TextStyle( color: Color(0xff5887FF), fontSize: ScreenUtil().setSp(14)), textAlign: TextAlign.center, ), ), SizedBox( width: 5, ) ], )) : Container( child: null, ), Container( padding: EdgeInsets.only( left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth( 15), top: ScreenUtil() .setWidth(10), bottom: ScreenUtil() .setWidth( 10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours .line), ), ), child: Row( mainAxisAlignment: MainAxisAlignment .start, children: < Widget>[ Container( padding: EdgeInsets .only( right: 5), child: LoadAssetImage( // image: AssetImage(i['img']), "expert_two", width: ScreenUtil() .setWidth( 32), height: ScreenUtil() .setWidth( 32), // alignment: Alignment.centerLeft, ), ), Text( "执业经历", style: TextStyle( fontSize: ScreenUtil() .setSp(17)), textAlign: TextAlign .start, ), // Text( // "奥的斯", // style: TextStyle( // color:Color(0xff999999), // fontSize:18 // ), // textAlign:TextAlign.start, // ), ]), ), Container( width: width, padding: EdgeInsets.only( left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth( 15), top: ScreenUtil() .setWidth(10), bottom: ScreenUtil() .setWidth( 10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 5, color: ThemeUtils .getDialogTextFieldColor( context)), ), ), child: Text( detailObj .proficiency ?? '', style: TextStyle( color: Color( 0xff999999), fontSize: ScreenUtil() .setSp( 14)), textAlign: TextAlign.start, ), ), Container( padding: EdgeInsets.only( left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth( 15), top: ScreenUtil() .setWidth(10), bottom: ScreenUtil() .setWidth( 10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours .line), ), ), child: Row( mainAxisAlignment: MainAxisAlignment .start, children: < Widget>[ Container( padding: EdgeInsets .only( right: 5), child: LoadAssetImage( // image: AssetImage(i['img']), "expert_one", width: ScreenUtil() .setWidth( 32), height: ScreenUtil() .setWidth( 32), // alignment: Alignment.centerLeft, ), ), Text( "用户评价", style: TextStyle( fontSize: ScreenUtil() .setSp(17)), textAlign: TextAlign .start, ), ]), ), ]) : Container(child: null), Container( child: Container( padding: EdgeInsets.only( top: ScreenUtil() .setWidth(10), left: ScreenUtil() .setWidth(20), right: ScreenUtil() .setWidth(20), bottom: ScreenUtil() .setWidth(10)), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colours.line), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment .start, children: [ Row( mainAxisAlignment: MainAxisAlignment .spaceBetween, children: [ Row( children: < Widget>[ Text( provider.list[index].mobile != null ? (provider.list[index].mobile).replaceRange( 3, 7, "****") : "", style: TextStyle( color: Color( 0xff666666), fontSize: ScreenUtil().setSp(16)), textAlign: TextAlign .start, ), Container( width: 6, child: null, ), // provider.list[index].comment!=""? // Text( // "采纳", // style: TextStyle( // color:Colors.red, // fontSize:ScreenUtil().setSp(14) // ), // textAlign:TextAlign.start, // ) // : // Text(""), ]), Text( provider.list[index].createTime != null ? DateUtils.instance.getFormartData( timeSamp: provider .list[ index] .createTime, format: "yyyy-MM-dd") : '', style: TextStyle( color: Color( 0xff999999), fontSize: ScreenUtil() .setSp( 14)), textAlign: TextAlign .start, ), ]), Container( child: Text( provider.list[index] .comment ?? '', style: TextStyle( color: Color( 0xff333333), fontSize: ScreenUtil() .setSp( 14)), textAlign: TextAlign.start, ), ), Container( height: ScreenUtil() .setWidth(10), decoration: BoxDecoration( color: Colors.red, ), child: Transform.rotate( origin: Offset( ScreenUtil() .setWidth( 25), ScreenUtil() .setWidth( 20)), angle: math.pi / 2, child: CustomPaint( painter: ChatBoxPainter( color: Color( 0xffF8F8F8), width: ScreenUtil().setWidth( 10), height: ScreenUtil().setWidth(20))))), Container( padding: EdgeInsets.only( top: ScreenUtil() .setWidth(10), bottom: ScreenUtil() .setWidth( 10), left: ScreenUtil() .setWidth(5), right: ScreenUtil() .setWidth( 5)), color: Color(0xffF8F8F8), child: Text( "问题描述:" + (provider .list[ index] .expression != null ? provider .list[ index] .expression : ""), style: TextStyle( color: Color( 0xff999999), fontSize: ScreenUtil() .setSp( 14)), textAlign: TextAlign.start, ), ), ]), )) ], ), ); }, ); })) : Container( child: null, ), Container( height: ScreenUtil().setWidth(80), ), ], ), Positioned( bottom: 0, left: 0, child: Container( width: width, padding: EdgeInsets.only( top: ScreenUtil().setWidth(15), bottom: ScreenUtil().setWidth(15), left: ScreenUtil().setWidth(25), right: ScreenUtil().setWidth(25)), color: ThemeUtils.getDialogTextFieldColor(context), child: Container( height: ScreenUtil().setWidth(44), decoration: BoxDecoration( borderRadius: BorderRadius.circular( ScreenUtil().setWidth(22)), // gradient: const LinearGradient(colors: [ // Color(0xFF00D9FF), // Color(0xFF0287FF) // ] // ), color: Colours.blue_app_main), child: FlatButton( // padding: EdgeInsets.all(15.0), child: detailObj.serviceFee != null ? Text( "线上咨询(¥${detailObj.serviceFee}元/次)") : Text("线上咨询(¥0元/次)"), textColor: Colors.white, onPressed: () { setExpertName(detailObj.name ?? ""); setExpertFee(detailObj.serviceFee ?? 0.0); NavigatorUtils.push(context, "${BbsRouter.buyService}?id=${widget.id}"); }, ), ), )) ], ) : Center( child: Text("正在加载..."), ))), ); } getLevel(level) { String img; if (level == 1) { img = "L1@2x"; } else if (level == 2) { img = "L2@2x"; } else if (level == 3) { img = "L3@2x"; } else if (level == 4) { img = "L4@2x"; } else if (level == 5) { img = "L5@2x"; } return img; } Widget expertDetailWisget() { double width = MediaQuery.of(context).size.width; double height = MediaQuery.of(context).size.height; List textWidgets = [Text('擅长品牌:')]; detailObj.proficiencyBrandName.split(',').forEach((element) { if (element != '') { textWidgets.add(ClipText(title: element)); } // textWidgets.add(ClipText(title: element)); }); return Column( children: [ Container( // height: ScreenUtil().setWidth(150), padding: EdgeInsets.only(bottom: 10), // decoration: BoxDecoration( // gradient: const LinearGradient( // colors: [Color(0xFF00D9FF), Color(0xFF0287FF)]), // ), child: Column( children: [ Container( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: EdgeInsets.only( left: ScreenUtil().setWidth(10), right: ScreenUtil().setWidth(10), top: ScreenUtil().setWidth(5)), decoration: BoxDecoration( borderRadius: BorderRadius.circular( ScreenUtil().setWidth(25)), ), child: Container( width: ScreenUtil().setWidth(50), height: ScreenUtil().setWidth(70), child: Stack( children: [ Container( padding: EdgeInsets.only( left: ScreenUtil().setWidth(3)), child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(50)), child: LoadNetworkImage( // image: AssetImage(i['img']), detailObj.avatarUrl, width: ScreenUtil().setWidth(44), height: ScreenUtil().setWidth(44), // alignment: Alignment.centerLeft, ), ), ), // Positioned( // top: ScreenUtil().setWidth(34), // left: 0, // child: LoadAssetImage( // // image: AssetImage(i['img']), // getLevel(detailObj.expertLevel), // width: ScreenUtil().setWidth(50), // height: ScreenUtil().setWidth(13), // // alignment: Alignment.centerLeft, // ), // ) ], ), )), Expanded( child: Container( padding: EdgeInsets.only( right: ScreenUtil().setWidth(15)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( detailObj.name ?? "", style: TextStyle( color: Color(0xff333333), fontSize: ScreenUtil().setSp(18)), ), StarItemShow( starRating: detailObj.averageScore != null ? double.parse(detailObj .averageScore .toString()) : 0.0, ), ], ), Container( alignment: Alignment.topLeft, child: Wrap( spacing: 2.0, runSpacing: 3.0, children: textWidgets), ), // detailObj.proficiencyBrandName.split(','); // Text( // "擅长品牌:" + // detailObj.proficiencyBrandName ?? // '', // style: TextStyle( // color: Color(0xff666666), // fontSize: ScreenUtil().setSp(14)), // // textAlign:TextAlign.start, // ), detailObj.platformInvitedFlag == 0 ? Container( padding: EdgeInsets.only( left: 5, right: 5), margin: EdgeInsets.only( right: 5, top: 5), // color:Colors.red, decoration: BoxDecoration( borderRadius: BorderRadius.circular(1.0), border: Border.all( width: 0.5, color: Color(0xffB0E2FF), ), ), child: Text( "特邀专家", style: TextStyle( color: Colours.blue_app_main, fontSize: ScreenUtil().setSp(12)), textAlign: TextAlign.center, ), ) : Container( child: null, ), // Row( // children: [ // Expanded( // child: Container( // decoration: BoxDecoration( // color: Color(0x195887FF), // borderRadius: // new BorderRadius.circular( // (5.0))), // padding: EdgeInsets.all(5), // margin: EdgeInsets.only( // right: 5, top: 5), // // color:Colors.red, // // decoration: BoxDecoration( // // borderRadius: BorderRadius.circular(2.0), // // border: Border.all( // // width:0.5, // // color:Color(0xffB0E2FF), // // ), // // color:Colors.white30, // // ), // child: Row( // crossAxisAlignment: // CrossAxisAlignment.start, // children: [ // Icon( // const IconData(0xe64a, // fontFamily: "Iconfont"), // size: 17.0, // color: Color(0x195887FF), // ), // SizedBox( // width: 5, // ), // Expanded( // child: Container( // child: Text( // // "detailObj", // detailObj.address != null // ? detailObj.address // .split(",")[0] // : "", // style: TextStyle( // color: Colours // .blue_app_main, // fontSize: ScreenUtil() // .setSp(12)), // textAlign: TextAlign.left, // // overflow:TextOverflow.ellipsis, // ), // )) // ], // )), // ) // ], // ), ], ))) ]), ), Container( padding: EdgeInsets.only(top: ScreenUtil().setWidth(10)), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Container( child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( detailObj.workDate != null ? detailObj.workDate.toString() : "0", style: TextStyle( color: Color(0xff333333), fontSize: ScreenUtil().setSp(19), fontWeight: FontWeight.w500), textAlign: TextAlign.start, ), Text( " 从业年数", style: TextStyle( color: Color(0xff666666), fontSize: ScreenUtil().setSp(12), fontWeight: FontWeight.w400), textAlign: TextAlign.start, ), ])), Container( child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( detailObj.serviceCounts != null ? detailObj.serviceCounts.toString() : "0", style: TextStyle( color: Color(0xff333333), fontSize: ScreenUtil().setSp(19), fontWeight: FontWeight.w500), textAlign: TextAlign.start, ), Text( " 服务次数", style: TextStyle( color: Color(0xff666666), fontSize: ScreenUtil().setSp(12), fontWeight: FontWeight.w400), textAlign: TextAlign.start, ), ])), // Container( // child:Column( // crossAxisAlignment: CrossAxisAlignment.center, // children:[ // Text( // "99.9", // style: TextStyle( // color:Colors.white, // fontSize:ScreenUtil().setSp(16) // ), // textAlign:TextAlign.start, // ), // Text( // "好评率(%)", // style: TextStyle( // color:Colors.white, // fontSize:ScreenUtil().setSp(14) // ), // textAlign:TextAlign.start, // ), // ] // ) // ), Container( child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( detailObj.adoptCounts != null ? detailObj.adoptCounts.toString() : "0", style: TextStyle( color: Color(0xff333333), fontSize: ScreenUtil().setSp(19), fontWeight: FontWeight.w500), textAlign: TextAlign.start, ), Text( " 采纳次数", style: TextStyle( color: Color(0xff666666), fontSize: ScreenUtil().setSp(12), fontWeight: FontWeight.w400), textAlign: TextAlign.start, ), ])), ])), ], )), ], ); } @override void dispose() { super.dispose(); } void setExpertName(String expertName) async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setString("expertName", expertName); } void setExpertFee(double expertFee) async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setDouble("expertFee", expertFee); } Future _onRefresh() async { _page = 1; await presenter.getExpertCommentList(_page, int.parse(widget.id), getLength: (length) { setState(() { listLength = length; }); }); } Future _loadMore() async { _page++; await presenter.getExpertCommentList(_page, int.parse(widget.id), getLength: (length) {}); } @override ExpertCommentListPresenter createPresenter() { return ExpertCommentListPresenter(); } } class ChatBoxPainter extends CustomPainter { ChatBoxPainter( {@required this.width, @required this.height, @required this.color}); final double width; final double height; final Color color; @override void paint(Canvas canvas, Size size) { Path path = Path() ..moveTo(0, height / 2) ..lineTo(width, height) ..lineTo(width, 0) ..lineTo(0, height / 2); Paint paint = Paint() ..style = PaintingStyle.fill ..color = color; canvas.drawPath(path, paint); } @override bool shouldRepaint(ChatBoxPainter oldDelegate) => false; @override bool shouldRebuildSemantics(ChatBoxPainter oldDelegate) => false; }