FlutterFlutter

Flutter 自定义吸顶动画

2020-05-26  本文已影响0人  Charles2018

效果预览:

PREVIEW

我这里没有录制GIF的工具所以勉强看吧 此Demo仅仅是个思路 实际使用时根据UI设计进行更改

源代码

c_tab_bar.dart

import 'package:flutter/material.dart';

class CTabBar extends StatefulWidget {
  final List<Widget> tabs;
  final Color labelColor;
  final bool isScrollable;
  final Decoration indicator;
  final TextStyle labelStyle;
  final Function onScrollEvent;
  final Color unselectedLabelColor;
  final TextStyle unselectedLabelStyle;

  CTabBar(
      {Key key,
      this.tabs,
      this.indicator,
      this.labelStyle,
      this.labelColor,
      this.isScrollable,
      this.onScrollEvent,
      this.unselectedLabelColor,
      this.unselectedLabelStyle})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => CTabBarState();
}

class CTabBarState extends State<CTabBar> with SingleTickerProviderStateMixin {
  TabController tabController;

  @override
  int get index => tabController.index;

  @override
  get indexIsChanging => tabController.indexIsChanging;

  @override
  double get offset => tabController.offset;

  void animateTo(int index) {
    tabController.animateTo(index);
  }

  @override
  void initState() {
    super.initState();
    tabController = TabController(length: widget.tabs.length, vsync: this);
    tabController.addListener(widget.onScrollEvent);
  }

  @override
  Widget build(BuildContext context) {
    return TabBar(
      tabs: widget.tabs,
      controller: tabController,
      indicator: widget.indicator,
      labelColor: widget.labelColor,
      labelStyle: widget.labelStyle,
      isScrollable: widget.isScrollable,
      unselectedLabelColor: widget.unselectedLabelColor,
      unselectedLabelStyle: widget.unselectedLabelStyle,
    );
  }
}
import 'package:flutter/material.dart';

import 'CTabBar.dart';

void main() => runApp(
  MaterialApp(
    home:MyHomePage()
  ),
);

class MyHomePage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => HomeState();
}

class HomeState extends State<MyHomePage>{
  static bool isCollapsed = false;
  ScrollController scrollController = new ScrollController();
  var isPageCanChanged = true;
  GlobalKey<CTabBarState> globalKeyCTabBar = new GlobalKey();
  PageController mPageController = PageController(initialPage: 0);
  static final List<Tab> tabList = [
    Tab(text: '推荐'),
    Tab(text: '热点'),
    Tab(text: '社会'),
    Tab(text: '娱乐')
  ];

  @override
  void initState() {
    super.initState();
    scrollController.addListener(() {
      var offset = scrollController.offset;
      print('offset: $offset');
      if (offset <= 1) {
        setState(() {
          isCollapsed = false;
        });
      } else if (offset >= 1) {
        setState(() {
          isCollapsed = true;
        });
      }
    });
  }

  void onPageChange(int index, {PageController pageController}) async {
    if (pageController != null) {
      isPageCanChanged = false;
      await mPageController.animateToPage(index,
          duration: Duration(milliseconds: 500), curve: Curves.ease);
      isPageCanChanged = true;
    } else {
      globalKeyCTabBar.currentState.animateTo(index);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        alignment: Alignment.topCenter,
        children: <Widget>[
          // 背景
          AnimatedContainer(
            height: isCollapsed ? 120 : 320,
            color: Colors.yellowAccent,
            duration: Duration(milliseconds: 280),
            curve: Curves.fastOutSlowIn,
          ),
          // 搜索栏
          AnimatedContainer(
            height: isCollapsed ? 0 : 180,
            width: MediaQuery.of(context).size.width,
            color: Colors.lightBlue,
            duration: Duration(milliseconds: 280),
            curve: Curves.fastOutSlowIn,
            padding: EdgeInsets.only(top:30,bottom:80),
            child: Container(
              alignment: Alignment.center,
              height: 50,
              color: Colors.purple,
              child: Text(
                "搜索栏",
                textAlign: TextAlign.center,
                textScaleFactor: 2,
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
          ),
          // Tab栏
          AnimatedContainer(
            margin: EdgeInsets.only(top: isCollapsed ? 35 : 110),
            duration: Duration(milliseconds: 500),
            curve: Curves.fastOutSlowIn,
            child:Column(
              children: <Widget>[
                Container(
                  height:30,
                  margin:EdgeInsets.only(bottom:isCollapsed ? 8 : 0),
                  child: CTabBar(
                    key: globalKeyCTabBar,
                    onScrollEvent: () {
                      if (globalKeyCTabBar.currentState.indexIsChanging) {
                        onPageChange(globalKeyCTabBar.currentState.index,
                            pageController: mPageController);
                      }
                    },
                    tabs: tabList,
                    isScrollable: false,
                    indicator: BoxDecoration(
                      gradient:LinearGradient(
                        colors: [Colors.purpleAccent,Colors.blue],
                      ),
                      shape: BoxShape.rectangle,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    labelColor: Colors.white,
                    labelStyle: TextStyle(
                      fontSize: 18,
                      color: Colors.white,
                      fontWeight: FontWeight.bold,
                    ),
                    unselectedLabelColor: Colors.black54,
                    unselectedLabelStyle: TextStyle(
                      fontSize: 18,
                      color: Colors.black54,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
                Expanded(
                  child: PageView.builder(
                    itemCount: tabList.length,
                    onPageChanged: (index) {
                      if (isPageCanChanged) {
                        onPageChange(index);
                      }
                    },
                    controller: mPageController,
                    itemBuilder: (BuildContext context, int index) {
                      return Container(
                        child: ListView(
                          controller: scrollController,
                          children:[1,1,1,1,1,1,1,1,1,1,1,1,1].map<Widget>(
                                (v) => Container(
                              height: 150,
                              margin: EdgeInsets.only(
                                bottom: 10,
                                left: 15,
                                right: 15,
                              ),
                              decoration: BoxDecoration(
                                gradient:LinearGradient(
                                  colors:[
                                    Colors.red,
                                    Colors.purpleAccent,
                                  ],
                                ),
                                shape: BoxShape.rectangle,
                                borderRadius: BorderRadius.circular(15),
                              ),
                            ),
                          ).toList(),
                        ),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
上一篇 下一篇

猜你喜欢

热点阅读