【问题标题】:Flutter uniqe appBar AnimationFlutter uniqe appBar 动画
【发布时间】:2021-02-09 06:36:43
【问题描述】:

我怎样才能使这个应用栏事务和动画如何将页面分成两部分并将向下滑动到向上以使向上消失在后面和对面。

此视频显示了该示例。

https://youtu.be/kIglDIllRjA

【问题讨论】:

    标签: flutter flutter-layout flutter-animation


    【解决方案1】:

    如何将页面拆分为 2 部分,然后将下侧向上滑动以使上侧消失在后面和对面。

    NestedScrollView 与自定义SliverPersistentHeaderDelegates 一起使用

    我做了这个应用栏交易

    您可以用 sliver 计算这一时刻:
    var isPinned = shrinkOffset > maxExtent - minExtent;

    我做了一个简化的例子。我希望会喜欢它。

    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: Scaffold(
            backgroundColor: Colors.white,
            body: MyHomePage(),
          ),
        );
      }
    }
    
    const backgroundColor = Color(0xFFfeeee6);
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key key}) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage>
        with SingleTickerProviderStateMixin {
      TabController tabController;
    
      @override
      void dispose() {
        tabController.dispose();
        super.dispose();
      }
    
      @override
      void initState() {
        tabController = TabController(length: 3, vsync: this);
        tabController.addListener(() {
          setState(() {});
        });
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return NestedScrollView(
          physics: BouncingScrollPhysics(),
          headerSliverBuilder: (_, __) => [
            SliverPersistentHeader(
              delegate: Header(),
              pinned: true,
              floating: true,
            ),
            SliverPersistentHeader(
              delegate: SliverTabBar(tabController: tabController),
              pinned: true,
              floating: false,
            )
          ],
          body: _Body(tab: tabController.index),
        );
      }
    }
    
    class SliverTabBar extends SliverPersistentHeaderDelegate {
      SliverTabBar({this.tabController});
    
      final TabController tabController;
    
      final List<Widget> myTabs = [
        Tab(text: 'Most Selling'),
        Tab(text: 'Waffle'),
        Tab(text: 'Nutella Casserole'),
      ];
    
      @override
      Widget build(
        BuildContext context,
        double shrinkOffset,
        bool overlapsContent,
      ) {
        return DecoratedBox(
          decoration: BoxDecoration(color: Colors.white),
          child: Row(
            children: [
              IconButton(
                onPressed: () => print('menu'),
                icon: Icon(
                  Icons.menu,
                  color: Colors.orange,
                ),
              ),
              TabBar(
                labelPadding: EdgeInsets.symmetric(horizontal: 10),
                isScrollable: true,
                physics: NeverScrollableScrollPhysics(),
                indicatorSize: TabBarIndicatorSize.label,
                controller: tabController,
                labelColor: Colors.black,
                indicatorColor: Colors.orange,
                tabs: myTabs,
              ),
            ],
          ),
        );
      }
    
      @override
      double get maxExtent => 48.0;
    
      @override
      double get minExtent => 48.0;
    
      @override
      bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
    }
    
    class Header extends SliverPersistentHeaderDelegate {
      @override
      Widget build(context, shrinkOffset, overlapsContent) {
        var isPinned = shrinkOffset > maxExtent - minExtent;
        return Container(
          decoration: BoxDecoration(
            color: isPinned ? Colors.white : backgroundColor,
          ),
          child: SafeArea(
            child: Stack(
              children: [
                Positioned(
                  top: 0,
                  left: 0,
                  right: 0,
                  child: Column(
                    children: [
                      Row(
                        children: [
                          ClipRRect(
                            borderRadius: BorderRadius.circular(100),
                            child: Container(
                              color: Colors.white,
                              child: IconButton(
                                onPressed: () => Navigator.of(context).pop(),
                                icon: Icon(
                                  Icons.arrow_back,
                                ),
                              ),
                            ),
                          ),
                          Expanded(
                            child: Visibility(
                              visible: isPinned,
                              child: Text(
                                'Waffleno',
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ),
                          ClipRRect(
                            borderRadius: BorderRadius.circular(100),
                            child: Container(
                              color: Colors.white,
                              child: IconButton(
                                onPressed: () => print('search'),
                                icon: Icon(
                                  Icons.search,
                                ),
                              ),
                            ),
                          )
                        ],
                      ),
                      SizedBox(height: 50),
                      Container(
                        width: double.infinity,
                        color: Colors.white,
                        height: 150,
                        child: Text(
                          'Waffleno',
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.bold,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
      @override
      double get maxExtent => 230;
    
      @override
      double get minExtent => 80;
    
      @override
      bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) => true;
    }
    
    class _Body extends StatelessWidget {
      const _Body({
        Key key,
        @required this.tab,
      }) : super(key: key);
    
      final int tab;
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 300,
          child: [Text('one'), Text('two'), Text('three')][tab],
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-17
      • 1970-01-01
      • 2019-07-30
      • 2020-12-26
      • 2020-04-02
      • 2020-08-04
      • 1970-01-01
      • 2022-12-01
      • 2021-06-23
      相关资源
      最近更新 更多