nine_layout.dart 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import 'package:flutter/material.dart';
  2. //九宫格布局
  3. class NineLayout extends StatelessWidget {
  4. final List<Widget> children;
  5. final double width;
  6. final int count;
  7. final double gap;
  8. NineLayout(
  9. {Key? key, this.children, this.width, required this.count, this.gap})
  10. : super(key: key);
  11. @override
  12. Widget build(BuildContext context) {
  13. return Flow(
  14. delegate:
  15. NineLayoutDelegate(context: context, count: count, width: width),
  16. children: children,
  17. );
  18. }
  19. }
  20. class NineLayoutDelegate extends FlowDelegate {
  21. final BuildContext context;
  22. final double width;
  23. final int count;
  24. final double gap;
  25. NineLayoutDelegate({
  26. required this.context,
  27. required this.count,
  28. this.width = 300,
  29. this.gap = 5.0,
  30. });
  31. var columns = 3;
  32. var rows = 3;
  33. double itemW = 0;
  34. double itemH = 0;
  35. double totalW = 0;
  36. @override
  37. void paintChildren(FlowPaintingContext context) {
  38. var x = gap;
  39. var y = 0.0;
  40. /// 需要重新计算,解决刷新值为0的问题
  41. getItemSize();
  42. getColumnsNumber(count);
  43. totalW = (itemW * rows) + (gap * (rows + 1));
  44. //计算每一个子widget的位置
  45. for (int i = 0; i < count; i++) {
  46. var w = context.getChildSize(i).width + x;
  47. if (w < totalW) {
  48. context.paintChild(i,
  49. transform: Matrix4.translationValues(x, y, 0.0));
  50. x += context.getChildSize(i).width + gap;
  51. } else {
  52. x = gap;
  53. y += context.getChildSize(i).height + gap;
  54. context.paintChild(i,
  55. transform: Matrix4.translationValues(x, y, 0.0));
  56. x += context.getChildSize(i).width + gap;
  57. }
  58. }
  59. }
  60. getColumnsNumber(int length) {
  61. if (length <= 3) {
  62. rows = length;
  63. columns = 1;
  64. } else if (length <= 6) {
  65. rows = 3;
  66. columns = 2;
  67. if (length == 4) {
  68. rows = 2;
  69. }
  70. } else {
  71. rows = 3;
  72. columns = 3;
  73. }
  74. }
  75. getItemSize() {
  76. if (count == 1) {
  77. itemW = width;
  78. itemH = itemW / 2;
  79. } else if (count == 2) {
  80. itemW = (width - gap) / 2;
  81. itemH = itemW;
  82. } else if (count == 3) {
  83. itemW = (width - 2 * gap) / 3;
  84. itemH = itemW;
  85. } else if (count == 4) {
  86. itemW = (width - gap) / 2;
  87. itemH = itemW - 20;
  88. } else {
  89. itemW = (width - 2 * gap) / 3;
  90. itemH = itemW;
  91. }
  92. }
  93. getConstraintsForChild(int i, BoxConstraints constraints) {
  94. getItemSize();
  95. return BoxConstraints(
  96. minWidth: itemW, minHeight: itemH, maxWidth: itemW, maxHeight: itemH);
  97. }
  98. getSize(BoxConstraints constraints) {
  99. getColumnsNumber(count);
  100. getItemSize();
  101. double h = (columns * itemH) + ((columns - 1) * gap);
  102. totalW = (itemW * rows) + (gap * (rows + 1));
  103. return Size(totalW, h);
  104. }
  105. @override
  106. bool shouldRepaint(FlowDelegate oldDelegate) {
  107. return oldDelegate != this;
  108. }
  109. }