赞
踩
闲来无事,不小心下载了携程app,还幻想可以去旅游一番,奈何自己运气不好,自从高考时第一次吹空调导致自己拉肚子考试,物理,数学考了一半就交卷,英语2B铅笔除了问题,导致原来120多分变成50分,本来能上一本的我只能上个大专,家里没钱也不允许留级,只能去了最近比较火的宿迁学院,哈哈,只能自己在这里瞎写找理由了,哎,现在因为当初的运气不好导致现在专科找工作难的要死,虽然自考了本,奈何人家不要啊,不承认啊,简历只要被学习的本科前面加上自考2字压根没有面试,不加上到了最后交流水学历资料的时候又被卡死,这种情况遇到的太多太多,我现在的心情只能用一个诗来描述,那就是: 一句诗:”哎“
啥都不说了,直接上代码:
import 'package:flutter/material.dart'; import '../../widgets/xy_app_bar.dart'; class XieChengHomePage extends StatefulWidget { const XieChengHomePage({Key? key}) : super(key: key); @override State<StatefulWidget> createState() { return XieChengHomePageState(); } } class XieChengHomePageState extends State<XieChengHomePage> with TickerProviderStateMixin { late TabController tabController; List<String> tabs = [ "飞机票", "火车高铁票", "公交车", ]; @override void initState() { super.initState(); tabController = TabController(length: 3, vsync: this); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( backgroundColor: Colors.red, appBar: XYAppBar( title: "Trapezoid Indicator Example", onBack: () { Navigator.pop(context); }, ), body: Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), child: CustomTabbarWidget( tabController: tabController, tabs: tabs, ), ), Expanded( child: TabBarView( controller: tabController, children: const [ Center(child: Text('Tab 1 Content')), Center(child: Text('Tab 2 Content')), Center(child: Text('Tab 3 Content')), ], ), ), ], )), ); } } class CustomTabbarWidget extends StatefulWidget { final TabController tabController; final List<String> tabs; const CustomTabbarWidget({ Key? key, required this.tabController, required this.tabs, }) : super(key: key); @override State<StatefulWidget> createState() { return CustomTabbarState(); } } class CustomTabbarState extends State<CustomTabbarWidget> { @override void initState() { super.initState(); widget.tabController.addListener(() { setState(() {}); }); } @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { var tabWidth = constraints.maxWidth / widget.tabs.length; var currentWidth = tabWidth * 1.5; var offset = (constraints.maxWidth - currentWidth) / (widget.tabs.length - 1); return Container( width: constraints.maxWidth, child: Stack( children: [ SizedBox( width: constraints.maxWidth, height: 60, ), Positioned( bottom: 0, left: 0, right: 0, child: Container( height: 50, decoration: BoxDecoration( color: Colors.white.withAlpha(80), borderRadius: const BorderRadius.only( topLeft: Radius.circular(8), topRight: Radius.circular(8), ), ), child: Row( children: widget.tabs.asMap().keys.map((index) { return AnimatedContainer( duration: const Duration(milliseconds: 200), width: index == widget.tabController.index ? currentWidth : offset, child: InkWell( key: ObjectKey(index), onTap: () { widget.tabController.animateTo(index); setState(() {}); }, child: Container( alignment: Alignment.center, child: Text( widget.tabs[index], style: const TextStyle(fontSize: 14), ), ), ), ); }).toList(), ), ), ), AnimatedPositioned( duration: const Duration(milliseconds: 300), left: widget.tabController.index * offset, bottom: 0, child: IgnorePointer( child: ClipPath( clipper: TrapezoidClipper(tabController: widget.tabController), child: Container( height: 60, alignment: Alignment.center, width: currentWidth, decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(8), topRight: Radius.circular(8)), ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: Center( child: Text( widget.tabs[widget.tabController.index], style: const TextStyle( fontSize: 18, color: Colors.blue), ), ), ), TextUnderline( text: widget.tabs[widget.tabController.index], style: const TextStyle( fontSize: 18, color: Colors.blue), lineColor: Colors.blue, height: 4), ], )), ), ), ), ], ), ); }); } } class TrapezoidClipper extends CustomClipper<Path> { TrapezoidClipper({required this.tabController}); TabController tabController; @override Path getClip(Size size) { var isLeft = tabController.index == 0; var isRight = tabController.index == tabController.length - 1; double inset = size.width * 0.1; double radius = 8.0; // path.moveTo(isLeft ? 0 : inset, 0); // path.lineTo(isRight ? size.width : size.width - inset, 0); // path.lineTo(size.width, size.height); // path.lineTo(0, size.height); final path = Path() ..moveTo(radius, 0) // 移动到起始点 ..lineTo(size.width - radius, 0) // 顶边线 ..quadraticBezierTo(size.width, 0, size.width, radius) // 右上角圆角 ..lineTo(size.width, size.height - radius) // 右边线 ..quadraticBezierTo( size.width, size.height, size.width - radius, size.height) // 右下角圆角 ..lineTo(radius, size.height) // 底边线 ..quadraticBezierTo(0, size.height, 0, size.height - radius) // 左下角圆角 ..lineTo(0, radius) // 左边线 ..quadraticBezierTo(0, 0, radius, 0); // 左上角圆角 path.close(); return path; } @override bool shouldReclip(CustomClipper<Path> oldClipper) => true; } class TextUnderline extends StatelessWidget { const TextUnderline({ Key? key, required this.text, required this.style, required this.lineColor, required this.height, }) : super(key: key); final String text; final TextStyle style; final Color lineColor; final double height; @override Widget build(BuildContext context) { final textPainter = TextPainter( text: TextSpan( text: text, style: style, ), textDirection: TextDirection.ltr, ); textPainter.layout(); var textWidth = textPainter.width; return Container( width: textWidth, height: height, decoration: BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(height), ), color: lineColor, ), ); } }
github.com/yixiaolunhui/flutter_xy
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。