【问题标题】:GridView appear animationGridView出现动画
【发布时间】:2019-03-03 07:48:30
【问题描述】:

我是新来的颤振???? ????

我正在学习并制作了这个布局。

布局结构:

    App
    │
    └── MaterialApp
        │
        └── Scaffold
            │
            └── AppBar
            │
            └── TabBar
            │   │
            │   └── Tab
            │
            └── Container
                │
                └── Expanded
                │   │
                │   └── TabBarView
                │       │
                │       └── Container
                │           │
                │           └── GridView
                │
                └── Container
                    │
                    └── Column
                        │
                        └── Row
                            │
                            └── CircularButton(A)
                            │
                            └── CircularButton(B)

我想在第一次生成布局时以及当用户选择CircularButton(正在重新生成GridView)时为GridView 设置动画。这个动画怎么实现?

我目前的代码:

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<App> with SingleTickerProviderStateMixin {

  List<String> data = DataClass.dataOne;
  static String selectedData = 'A';

  final List<Tab> myTabs = <Tab>[
    Tab(
      text: 'SELECTED DATA $selectedData',
    ),
  ];

  List<bool> currentSelectedList = DataClass.dataTwo;

  List<bool> changeSelection() {
    return currentSelectedList;
  }

  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: myTabs.length);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'GridView Test',
      theme: ThemeData(
        primaryColor: Color(0xFFD0021B),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            'GridView Test',
            style: TextStyle(
              fontFamily: 'Roboto',
            ),
          ),
          bottom: TabBar(
            controller: _tabController,
            tabs: <Tab>[
              Tab(
                text: 'SELECTED DATA $selectedData',
              ),
            ],
            indicatorColor: Colors.white,
          ),
        ),
        body: Container(
          color: Color(0xFFD0021B),
          child: Column(
            children: <Widget>[
              Expanded(
                child: TabBarView(
                  controller: _tabController,
                  children: [
                    Container(
                      child: Grid(changeSelection()),
                    ),
                  ],
                ),
              ),
              Container(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    Row(
                      mainAxisSize: MainAxisSize.max,
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        circleButton(DataClass.dataOne[0]),
                        circleButton(DataClass.dataOne[1]),
                      ],
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget circleButton(String type) {

    return Padding(
      padding: const EdgeInsets.only(top: 8.0, bottom: 10.0),
      child: FloatingActionButton(
        onPressed: () {
          setState(() {
            switch (type) {
              case 'A':
                selectedData = DataClass.dataOne[0];
                currentSelectedList = DataClass.dataTwo;
                break;
              case 'B':
                selectedData = DataClass.dataOne[1];
                currentSelectedList = DataClass.dataThree;
                break;
            }
          });
        },
        child: Text(
          type,
          style: TextStyle(
            fontFamily: 'Roboto',
            fontSize: 25.0,
            color: Color(0xFFD0021B),
          ),
        ),
        backgroundColor: Colors.white,
      ),
    );
  }

}

class DataClass {
  static List<String> dataOne = ['A', 'B'];

  static List<bool> dataTwo = [true, false, true, false, true, false, true, false];
  static List<bool> dataThree = [true, true, true, true, true, true, true, true];
}

class Grid extends StatelessWidget {
  Grid(this.available);
  final List<bool> available;
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      children: <Widget>[
        Tile(DataClass.dataOne[0], available[0]),
        Tile(DataClass.dataOne[1], available[1]),
        Tile(DataClass.dataOne[0], available[2]),
        Tile(DataClass.dataOne[1], available[3]),
        Tile(' ', true),
        Tile(DataClass.dataOne[0], available[4]),
        Tile(DataClass.dataOne[1], available[5]),
        Tile(DataClass.dataOne[0], available[6]),
        Tile(DataClass.dataOne[1], available[7]),
      ],
      crossAxisCount: 3,
      crossAxisSpacing: 20.0,
      primary: false,
      padding: const EdgeInsets.all(20.0),
      mainAxisSpacing: 1.0,
    );
  }
}

class Tile extends StatelessWidget {
  Tile(this.data, this.enabled);
  final data;
  final enabled;
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(10.0),
      child: FloatingActionButton(
        shape: BeveledRectangleBorder(
          borderRadius: BorderRadius.circular(20.0),
        ),
        onPressed: () {},
        child: data.contains(' ')
            ? Icon(
          Icons.all_out,
          color: Color(0xFF820111),
          size: 50.0,
        )
            : Text(
          data,
          style: TextStyle(
            fontFamily: 'Roboto',
            fontSize: 25.0,
            color: enabled ? Theme.of(context).primaryColor : Color(0xFFFFFFFF),
          ),
        ),
        backgroundColor: enabled ? Color(0xFFFFFFFF) : Color(0xFF999999),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter flutter-layout flutter-animation flutter-gridview


    【解决方案1】:

    您可以通过使用Stack 而不是 GridView 来实现类似的行为 - 这允许我们将小部件相互重叠。要在屏幕上移动 Widget,我们可以使用AnimatedPositioned。

    这是一个完整的示例。

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      bool _expand = false;
      double? top;
      double? left;
      List<double> _listTop = [];
      List<double> _listLeft = [];
    
      // initialize screen position for expanded and retracted widgets
      _initPosition(double screenWidth) {
        for (var x = 0; x < 9; x++) {
          if (x < 3) _listTop.add(0);
          if (x > 2 && x < 6) _listTop.add(screenWidth / 3);
          if (x > 5) _listTop.add((screenWidth / 3) * 2);
    
          if (x % 3 == 0) _listLeft.add(0);
          if (x % 3 == 1) _listLeft.add(screenWidth / 3);
          if (x % 3 == 2) _listLeft.add((screenWidth / 3) * 2);
        }
      }
    
      @override
      Widget build(BuildContext context) {
        // we can only fetch the screen size on build
        _initPosition(MediaQuery.of(context).size.width);
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Expanded(
                  flex: 3,
                  child: Container(
                    color: Colors.greenAccent,
                    child: Stack(
                      alignment: AlignmentDirectional.center,
                      children: List.generate(9, (index) {
                        return AnimatedPositioned(
                          duration: Duration(milliseconds: 800),
                          top: _expand
                              ? _listTop[index]
                              : ((top != null)
                                  ? top
                                  : MediaQuery.of(context).size.width / 3),
                          left: _expand
                              ? _listLeft[index]
                              : ((left != null)
                                  ? left
                                  : MediaQuery.of(context).size.width / 3),
                          child: Card(
                            elevation: 0.5,
                            child: Container(
                              height: MediaQuery.of(context).size.width / 3.5,
                              width: MediaQuery.of(context).size.width / 3.5,
                              color: Colors.lightBlue,
                              child: Center(
                                child: Text(
                                  'Item $index',
                                  style: Theme.of(context).textTheme.headline5,
                                ),
                              ),
                            ),
                          ),
                        );
                      }),
                    ),
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: Row(
                    children: [
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () {
                            setState(() {
                              _expand = true;
                            });
                          },
                          child: Padding(
                            padding: const EdgeInsets.all(16.0),
                            child: Text('+'),
                          ),
                          style: ElevatedButton.styleFrom(
                            shape: CircleBorder(),
                          ),
                        ),
                      ),
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () {
                            setState(() {
                              _expand = false;
                            });
                          },
                          child: Padding(
                            padding: const EdgeInsets.all(16.0),
                            child: Text('-'),
                          ),
                          style: ElevatedButton.styleFrom(
                            shape: CircleBorder(),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ), 
        );
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-28
      • 2021-07-23
      • 1970-01-01
      相关资源
      最近更新 更多