demo1.dart 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/rendering.dart';
  3. import 'package:luojigou_thinking_core/luojigou_thinking_core.dart';
  4. class Demo1 extends StatefulWidget {
  5. const Demo1({
  6. Key? key,
  7. }) : super(key: key);
  8. @override
  9. State<StatefulWidget> createState() => _Demo1State();
  10. }
  11. class _Demo1State extends State<Demo1> with SingleTickerProviderStateMixin {
  12. late TabController _controller;
  13. @override
  14. void initState() {
  15. super.initState();
  16. _controller = TabController(length: 5, vsync: this);
  17. }
  18. @override
  19. Widget build(BuildContext context) {
  20. return Row(
  21. children: [
  22. SizedBox(
  23. width: 55,
  24. height: double.infinity,
  25. child: ColoredBox(
  26. color: Color(0xFFC8DDFF),
  27. child: Column(
  28. children: [
  29. SizedBox(
  30. width: double.infinity,
  31. height: 44 + MediaQuery.of(context).padding.top,
  32. child: const ColoredBox(
  33. color: Colors.teal,
  34. ),
  35. ),
  36. Expanded(
  37. child: VerticalTabBar(
  38. controller: _controller,
  39. isScrollable: true,
  40. labelStyle: const TextStyle(
  41. color: Color(0xFF75AAFF),
  42. fontSize: 16,
  43. height: 1,
  44. ),
  45. unselectedLabelStyle: const TextStyle(
  46. color: Color(0xFFFFFFFF),
  47. fontSize: 16,
  48. height: 1,
  49. ),
  50. labelColor: const Color(0xFF75AAFF),
  51. unselectedLabelColor: Colors.white,
  52. indicator: _TabDecoration(),
  53. tabs: [
  54. Container(
  55. padding: EdgeInsets.symmetric(horizontal: 4),
  56. height: double.infinity,
  57. color: Colors.transparent,
  58. child: Center(child: const Text('综合区')),
  59. ),
  60. Container(
  61. padding: EdgeInsets.symmetric(horizontal: 4),
  62. height: double.infinity,
  63. color: Colors.transparent,
  64. child: Center(child: const Text('中华文化')),
  65. ),
  66. Container(
  67. padding: EdgeInsets.symmetric(horizontal: 4),
  68. height: double.infinity,
  69. color: Colors.transparent,
  70. child: Center(child: const Text('科学探索')),
  71. ),
  72. Container(
  73. padding: EdgeInsets.symmetric(horizontal: 4),
  74. height: double.infinity,
  75. color: Colors.transparent,
  76. child: Center(child: const Text('自由探索')),
  77. ),
  78. Container(
  79. padding: EdgeInsets.symmetric(horizontal: 4),
  80. height: double.infinity,
  81. color: Colors.transparent,
  82. child: Center(child: const Text('思维探索')),
  83. ),
  84. ],
  85. ),
  86. ),
  87. ],
  88. ),
  89. ),
  90. ),
  91. Expanded(
  92. child: GestureDetector(
  93. onTap: () {
  94. int lastIndex = _controller.index;
  95. int nextIndex = (lastIndex + 1) % _controller.length;
  96. _controller.animateTo(nextIndex);
  97. },
  98. child: ColoredBox(
  99. color: Colors.transparent,
  100. child: SizedBox.expand(),
  101. ),
  102. ),
  103. ),
  104. ],
  105. );
  106. }
  107. }
  108. class _TabDecoration extends Decoration {
  109. @override
  110. BoxPainter createBoxPainter([VoidCallback? onChanged]) {
  111. return _BoxPainter(onChanged);
  112. }
  113. }
  114. class _BoxPainter extends BoxPainter {
  115. _BoxPainter(VoidCallback? onChanged) : super(onChanged);
  116. @override
  117. void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
  118. if (configuration.size == null) return;
  119. final size = configuration.size!;
  120. final paint = Paint()..color = const Color(0xFF75AAFF);
  121. final dotx = offset.dx + size.width / 2;
  122. final doty = offset.dy + size.height - 8;
  123. canvas.drawCircle(Offset(dotx, doty), 2, paint);
  124. double h = 18.8;
  125. double w = 60;
  126. final path = Path();
  127. path.moveTo(dotx - w, doty + 8);
  128. path.lineTo(dotx, doty + 8 + 20);
  129. path.lineTo(dotx + w, doty + 8);
  130. path.reset();
  131. path.moveTo(dotx - w, doty + 8);
  132. path.cubicTo(dotx - w/2-10, doty+8, dotx-w/2+10, doty + 8 + h, dotx, doty + 8 + h);
  133. path.cubicTo(dotx + w/2-10, doty+8+h, dotx+w/2+10, doty + 8 , dotx + w, doty + 8);
  134. canvas.drawPath(path, paint..color = const Color(0xFFC8DDFF));
  135. }
  136. }