如何创建颤动流小部件

时间:2020-08-06 21:29:37

标签: flutter animation flow flowlayout flowlayoutpanel

我正在尝试创建类似Flutter的流布局。我只需要在FlexibleGridView上执行类似this的操作,但是要使用拉伸动画。因此,在我的情况下,我基于元素列表构建矩阵,然后更改元素的位置,但是当我对许多元素执行此操作时,我不知道如何使它们不重叠。

这是我的课程


class UserSuggestion extends StatefulWidget {
  static final String tag = '/user-suggestion';

  UserSuggestion({Key key}) : super(key: key);

  @override
  _UserSuggestionState createState() => _UserSuggestionState();
}

class _UserSuggestionState extends State<UserSuggestion>
    with TickerProviderStateMixin {
  double screenHeight;
  List<Example01Tile> list;
  List<SuggestionCategory> items = [];
  Map<int, List<SuggestionCategory>> suggestionMatrix = {
    0: [],
    1: [],
    2: [],
    3: []
  };
  StreamController onTapListener = StreamController();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    final number = 30;
    items = List.generate(
      number,
      (index) => SuggestionCategory(
        name: index.toString(),
        width: 100,
        height: 100,
      ),
    );
    int rowCount = (items.length / 4).round();
    suggestionMatrix = Map.from(suggestionMatrix.map((key, value) {
      final endIndex = (rowCount * (key + 1));
      return MapEntry(
          key,
          items
              .getRange(rowCount * key,
                  endIndex < items.length ? endIndex : items.length)
              .toList()
              .asMap()
              .entries
              .map((element) {
            final val = element.value;
            final i = element.key;

            return SuggestionCategory(
                name: i.toString(),
                width: 100,
                height: 100,
                x: (i) * 100.0,
                y: (key) * 100.0);
          }).toList());
    }));

    onTapListener.stream.listen((event) {
      calculeteNewTapsPositions(event);
    });
  }

  @override
  Widget build(BuildContext context) {
    final isDesktop = isDisplayDesktop(context);
    screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(body: Center(child: mobile()));
  }

  mobile() {
    return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            "Tell me what noo jiu jkwk?",
            style: Theme.of(context).textTheme.headline2,
          ).paddingOnly(
              top: PADDING_TOP_BIG_SUGGESTION,
              left: PADDING_LR_MEDIUM,
              right: PADDING_LR_MEDIUM),
          Flexible(
            child: grid(),
          ),
        ]);
  }

  grid() {
    return SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Container(
          height: 600,
          width: 800,
          child: Stack(
            fit: StackFit.expand,
            alignment: Alignment.topLeft,
            children: jjjjjj(),
          ),
        ));
  }

  List<Widget> jjjjjj() {
    List<Widget> widgets = [];
    suggestionMatrix.entries.forEach((columns) {
      int iColumn = columns.key;
      List<SuggestionCategory> rowsList = columns.value;
      rowsList.asMap().entries.forEach((rows) {
        int iRow = rows.key;
        SuggestionCategory rowsList = rows.value;
        rowsList.iColumn = iColumn;
        rowsList.iRow = iRow;
        widgets.add(AnimatedPositioned(
          duration: Duration(milliseconds: 600),
          curve: Curves.easeInOut,
          left: rows.value.x,
          top: rows.value.y,
//          bottom: bottom,
//          right: right,
          height: rows.value.height,
          width: rows.value.width,
          child: item(rows.value),
        ));
      });
    });

    return widgets;
  }

  void calculeteNewTapsPositions(SuggestionCategory suggestionCategory) {
    final iRow = suggestionCategory.iRow;
    final iColumn = suggestionCategory.iColumn;
    bool needExpand = suggestionCategory.currentWeight > 1;
    bool isEndExpandIteration = suggestionCategory.currentWeight > 2;
    List<SuggestionCategory> rowList = suggestionMatrix[iColumn];

    //mark for right rows
    rowList.getRange(iRow + 1, rowList.length).forEach((SuggestionCategory e) {
      setState(() {
        if (needExpand) {
          print("right");
          e.x = e.x + 100;
        } else {
          print("back");
          e.x = e.x - 200;
        }
      });
    });

    //mark for left columns
    suggestionMatrix.forEach((key, value) {
      if (key > iColumn) {
        SuggestionCategory e1 = value.elementAt(iRow);
        SuggestionCategory e2 = value.elementAt(iRow + 1);
        SuggestionCategory e3 = value.elementAt(iRow + 2);
        setState(() {
          if (needExpand) {
            e1.y = e1.y + 50;
            e2.y = e2.y + 50;
          } else {
            e1.y = e1.y - 100;
            e2.y = e2.y - 100;
            //e3.y = e3.y - 100;
          }

//          if (isEndExpandIteration && needExpand) {
//            e3.y = e3.y + 100;
//          }
        });
      }
    });
  }

  Widget item(SuggestionCategory e) => AnimatedSize(
        vsync: this,
        duration: Duration(seconds: 1),
        curve: Curves.bounceIn,
        child: Example01Tile(
          backgroundColor: Colors.blueGrey,
          iconData: Icons.hd,
          name: e.name,
        ).addOnTap(
          onTap: () {
            setState(() {
              if (e.currentWeight <= 2) {
                e.currentWeight = e.currentWeight + 1;
                e.height = e.height + 50;
                e.width = e.width + 50;
                //x.y.nextposel
              } else {
                e.currentWeight = 1;
                e.height = 100;
                e.width = 100;
              }
              onTapListener.add(e);
            });
          },
        ),
      );
}
class SuggestionCategory {
  String name;
  StaggeredTile staggeredTile;
  int currentWeight = 1;
  double width;
  double height;
  double x;
  double y;
  int iRow;
  int iColumn;

  SuggestionCategory({this.name, this.width, this.height, this.x, this.y});
}

0 个答案:

没有答案