美文网首页Flutter
flutter列表常见的两种吸附置顶效果

flutter列表常见的两种吸附置顶效果

作者: 编程的猫 | 来源:发表于2020-11-25 16:01 被阅读0次
    效果一: SVID_20201125_154558_1.gif

    完整代码代码:

    import 'package:flutter/material.dart';
    
    class CustomScrollView1 extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return CustomScrollView1State();
      }
    }
    
    class CustomScrollView1State extends State<CustomScrollView1>
        with SingleTickerProviderStateMixin {
      List<Widget> _tabs = <Widget>[
        Tab(
          text: "Home",
        ),
        Tab(
          text: "Profile",
        )
      ];
    
      List<Widget> _tabViews = <Widget>[
        Center(child: Text("Home")),
        Center(child: Text("Profile")),
      ];
    
      TabController _tabController;
    
      @override
      void initState() {
        super.initState();
        this._tabController = TabController(length: _tabs.length, vsync: this);
      }
    
      @override
      void dispose() {
        this._tabController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            slivers: <Widget>[
              SliverPersistentHeader(
                floating: true,
                pinned: true,
                delegate: SliverCustomHeaderDelegate(
                  collapsedHeight: 43.0,
                  expandedHeight: 220.0,
                  paddingTop: 27.0,
                  coverImgUrl:
                      "http://img1.mukewang.com/5c18cf540001ac8206000338.jpg",
                  title: "练习",
                ),
              ),
              SliverFillRemaining(
                child: TabBarView(
                  controller: this._tabController,
                  children: _tabViews,
                ),
              ),
            ],
          ),
        );
      }
    }
    
    class SliverCustomHeaderDelegate extends SliverPersistentHeaderDelegate {
      final double collapsedHeight;
    
      ///折叠的高度
      final double expandedHeight;
    
      ///展开的高度
      final double paddingTop;
      final String coverImgUrl;
      final String title;
    
      SliverCustomHeaderDelegate({
        this.collapsedHeight,
        this.expandedHeight,
        this.paddingTop,
        this.coverImgUrl,
        this.title,
      });
    
      Color makeStickyHeaderBgColor(shrinkOffset) {
        final int alpha = (shrinkOffset / (this.maxExtent - this.minExtent) * 255)
            .clamp(0, 255)
            .toInt();
        return Color.fromARGB(alpha, 255, 255, 255);
      }
    
      Color makeStickyHeaderTextColor(shrinkOffset, isIcon) {
        if (shrinkOffset <= 50) {
          return isIcon ? Colors.white : Colors.transparent;
        } else {
          final int alpha = (shrinkOffset / (this.maxExtent - this.minExtent) * 255)
              .clamp(0, 255)
              .toInt();
          return Color.fromARGB(alpha, 0, 0, 0);
        }
      }
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return Container(
          height: this.maxExtent,
          width: MediaQuery.of(context).size.width,
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              // 背景图
              Container(child: Image.network(this.coverImgUrl, fit: BoxFit.cover)),
              // 收起头部
              Positioned(
                left: 0,
                right: 0,
                top: 0,
                child: Container(
                  color: this.makeStickyHeaderBgColor(shrinkOffset), // 背景颜色
                  child: SafeArea(
                    bottom: false,
                    child: Container(
                      height: this.collapsedHeight,
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          IconButton(
                            icon: Icon(
                              Icons.arrow_back_ios,
                              color: this.makeStickyHeaderTextColor(
                                  shrinkOffset, true), // 返回图标颜色
                            ),
                            onPressed: () => Navigator.pop(context),
                          ),
                          Text(
                            this.title,
                            style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.w500,
                              color: this.makeStickyHeaderTextColor(
                                  shrinkOffset, false), // 标题颜色
                            ),
                          ),
                          IconButton(
                            icon: Icon(
                              Icons.share,
                              color: this.makeStickyHeaderTextColor(
                                  shrinkOffset, true), // 分享图标颜色
                            ),
                            onPressed: () {},
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    
      @override
      double get maxExtent => this.expandedHeight;
    
      @override
      double get minExtent => this.collapsedHeight + this.paddingTop;
    
      @override
      bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
        return true;
      }
    }
    
    
    效果二: SVID_20201125_155856_1.gif

    完整代码:

    import 'package:flutter/material.dart';
    
    class CustomScrollView1 extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return CustomScrollView1State();
      }
    }
    
    class CustomScrollView1State extends State<CustomScrollView1>
        with SingleTickerProviderStateMixin {
      List<Widget> _tabs = <Widget>[
        Tab(
          text: "Home",
        ),
        Tab(
          text: "Profile",
        )
      ];
    
      List<Widget> _tabViews = <Widget>[
        Center(child: Text("Home")),
        Center(child: Text("Profile")),
      ];
    
      TabController _tabController;
    
      @override
      void initState() {
        super.initState();
        this._tabController = TabController(length: _tabs.length, vsync: this);
      }
    
      @override
      void dispose() {
        this._tabController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            slivers: <Widget>[
              SliverAppBar(
                floating: true,
                snap: true,
                pinned: true,
                expandedHeight: 250.0,
                flexibleSpace: FlexibleSpaceBar(
                  title: Text("标题"),
                  background: Image(
                    image: AssetImage("images/sealand.jpeg"),
                    fit: BoxFit.cover,
                  ),
                ),
              ),
              SliverPersistentHeader(
                floating: true,
                pinned: true,
                delegate: StickyTabBarDelegate(
                  TabBar(
                    controller: _tabController,
                    labelColor: Colors.black,
                    tabs: _tabs,
                  ),
                ),
              ),
              SliverFillRemaining(
                child: TabBarView(
                  controller: this._tabController,
                  children: _tabViews,
                ),
              ),
            ],
          ),
        );
      }
    }
    
    class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
      final TabBar child;
    
      StickyTabBarDelegate(this.child);
    
      @override
      Widget build(
          BuildContext context, double shrinkOffset, bool overlapsContent) {
        return this.child;
      }
    
      @override
      double get maxExtent => this.child.preferredSize.height;
    
      @override
      double get minExtent => this.child.preferredSize.height;
    
      @override
      bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
        return true;
      }
    }
    

    相关文章

      网友评论

        本文标题:flutter列表常见的两种吸附置顶效果

        本文链接:https://www.haomeiwen.com/subject/pmeniktx.html