my_header.dart 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_svg/flutter_svg.dart';
  3. /// Description: login header
  4. /// Time : 05/11/2023 Thursday
  5. /// Author : liuyuqi.gov@msn.cn
  6. class MyHeader extends StatefulWidget {
  7. final String image;
  8. final String textTop;
  9. final String textBottom;
  10. final double offset;
  11. const MyHeader(
  12. {super.key,
  13. required this.image,
  14. required this.textTop,
  15. required this.textBottom,
  16. required this.offset});
  17. @override
  18. State<MyHeader> createState() => _MyHeaderState();
  19. }
  20. class _MyHeaderState extends State<MyHeader> {
  21. @override
  22. Widget build(BuildContext context) {
  23. return ClipPath(
  24. clipper: MyClipper(offset: widget.offset),
  25. child: Container(
  26. padding: const EdgeInsets.only(left: 40, top: 50, right: 20),
  27. height: 350,
  28. width: double.infinity,
  29. decoration: const BoxDecoration(
  30. gradient: LinearGradient(
  31. begin: Alignment.topRight,
  32. end: Alignment.bottomLeft,
  33. colors: [
  34. Color(0xFF3383CD),
  35. Color(0xFF11249F),
  36. ],
  37. ),
  38. image: DecorationImage(
  39. image: AssetImage("assets/images/virus.png"),
  40. ),
  41. ),
  42. child: Column(
  43. crossAxisAlignment: CrossAxisAlignment.end,
  44. children: [
  45. const SizedBox(
  46. height: 30,
  47. ),
  48. Expanded(
  49. child: Stack(
  50. children: [
  51. Positioned(
  52. top: 20 - widget.offset / 2,
  53. left: 0,
  54. child: SvgPicture.asset(
  55. widget.image,
  56. width: 270,
  57. fit: BoxFit.fitWidth,
  58. alignment: Alignment.bottomLeft,
  59. ),
  60. ),
  61. Positioned(
  62. top: 50 - widget.offset / 2,
  63. left: 0,
  64. child: Text(
  65. "${widget.textTop} \n${widget.textBottom}",
  66. style: const TextStyle(
  67. fontSize: 25,
  68. fontWeight: FontWeight.w500,
  69. color: Colors.white,
  70. ),
  71. ),
  72. ),
  73. Container(), // I dont know why it can work without container
  74. ],
  75. ),
  76. ),
  77. ],
  78. ),
  79. ),
  80. );
  81. }
  82. }
  83. /// Description: 自定义形状,弧线
  84. ///
  85. class MyClipper extends CustomClipper<Path> {
  86. /// 偏移量
  87. final double offset;
  88. const MyClipper({required this.offset});
  89. @override
  90. Path getClip(Size size) {
  91. var path = Path();
  92. path.lineTo(0, size.height * 0.8);
  93. path.quadraticBezierTo(
  94. size.width / 2, size.height * 0.9, size.width, size.height * 0.8);
  95. path.lineTo(size.width, 0);
  96. path.close();
  97. return path;
  98. }
  99. @override
  100. bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
  101. return false;
  102. }
  103. }