This article is mainly my page personal center page.

The following is the realization of the mental journey

SliverAppBar

Even if it can not meet the existing needs, holding the idea of learning, to learn about it, its main effect is through the following attributes

// Attributes have different effects
 pinned: true,
 floating: ture,
 snap: true.Copy the code
NestedScrollView CustomScrollView
HeaderSliverBuilder build The slivers property is built

NestedScrollView code example

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool b) {
          return [
            SliverAppBar(
              pinned: true,
              floating: false,
              expandedHeight: 200,
              flexibleSpace: FlexibleSpaceBar(
                collapseMode: CollapseMode.pin,
                background: Container(
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      Container(
                        height: 200,
                        child: Image.network(
                          'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39c71164cc4a455b83ac6f579e2a39c1~tplv-k3u1fbpfcp-watermark.image',
                          fit: BoxFit.fill,
                          height: 220, width: get.width,),),],),),),), bottom: TabBar (Controller: tabController, tabs: <Widget>[new Tab(
                    text: "Dynamic",),new Tab(
                    text: "Article",),new Tab(
                    text: "Boiling point",),new Tab(
                    text: "Other"[,], [,], [; }, body: TabBarView( controller: tabController, children: <Widget>[ ], ), ), ); }Copy the code

CustomScrollView code example

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            pinned: true,
            elevation: 0,
            expandedHeight: 220,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('One morning'),
              background: Image.network(
                'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39c71164cc4a455b83ac6f579e2a39c1~tplv-k3u1fbpfcp-watermark.image',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverPersistentHeader(
            pinned: true,
            delegate: TabBarDelegate(
              child: TabBar(
                labelColor: Colors.black,
                controller: this.tabController,
                tabs: <Widget>[
                  Tab(text: 'dynamic'),
                  Tab(text: 'articles'),
                  Tab(text: 'the boiling point'),
                  Tab(text: 'other'),
                ],
              ),
            ),
          ),
          SliverFillRemaining(
            child: TabBarView(
              controller: this.tabController,
              children: <Widget>[
              ],
            ),
          ),
        ],
      ),
    );
    };
    
class TabBarDelegate extends SliverPersistentHeaderDelegate {
  final TabBar child;

  TabBarDelegate({@required 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; }}Copy the code

Even if it doesn’t have the desired effect, is it possible to do so by customizing the header component? Because the build method in SliverPersistentHeaderDelegate a shrinkOffset fields, this is what meaning, look to print:

This value is the offset value of the slide, so that it can be used to do something with transparency. The end result:

Build directly in the TabBarDelegate class

Color headerTextColor(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();
      returnColors.black.withAlpha(alpha); }}int headerBgColor(shrinkOffset) {
    final int alpha = (shrinkOffset / (this.maxExtent - this.minExtent) * 255)
        .clamp(0.255)
        .toInt();
    return alpha;
  }
  
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      height: this.maxExtent,
      width: Get.width,
      child: Stack(
        fit: StackFit.expand,
        children: [
          Container(
            child: Image.network(
                'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39c71164cc4a455b83ac6f579e2a39c1~tplv-k3u1fbpfcp-watermark.image',
                fit: BoxFit.cover),
          ),
          Positioned(
            left: 0,
            right: 0,
            top: 0,
            child: Container(
              color: Colors.white
                  .withAlpha(this.headerBgColor(shrinkOffset)),
              child: SafeArea(
                bottom: false,
                child: Container(
                  height: 40,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      IconButton(
                        icon: Icon(
                          Icons.arrow_back_ios,
                          color: this
                              .headerTextColor(shrinkOffset, true),
                        ),
                        onPressed: () => Navigator.pop(context),
                      ),
                      Expanded(
                          child: Row(
                        children: [
                          Container(
                            height: 28,
                            width: 28,
                            margin: EdgeInsets.only(right: 8),
                            decoration: BoxDecoration(
                                color: Colors.red.withAlpha(
                                    this.headerBgColor(shrinkOffset)),
                                borderRadius: BorderRadius.circular(14)),
                          ),
                          Text(
                            'One morning',
                            style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.w500,
                              color: headerTextColor(
                                  shrinkOffset, false),
                            ),
                          ),
                        ],
                      )),
                      IconButton(
                        icon: Icon(
                          Icons.share,
                          color: this
                              .headerTextColor(shrinkOffset, true),
                        ),
                        onPressed: () {},
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
          Positioned(
              bottom: 0,
              left: 0,
              right: 0,
              child: Container(
                child: this.child,
                decoration: BoxDecoration(color: Colors.blueGrey[100]),
              )),
        ],
      ),
      alignment: Alignment.bottomCenter,
    );
  }

  @override
  double get maxExtent => 500;

  @override
  double get minExtent => Get.context.mediaQueryPadding.top + 88;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }

Copy the code

That’s pretty much it, all that’s left is to build the list, and build the basic information, first of all, the basic information

Positioned(
              bottom: 48,
              left: 0,
              right: 0,
              child: Container(
                width: Get.width,
                height: 180,
                decoration: BoxDecoration(color: Colors.white),
                padding: EdgeInsets.only(left: 20, right: 20),
                child: Column(
                  children: [
                    Padding(padding: EdgeInsets.only(top: 50)),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Row(
                              children: [
                                Text(
                                  'One morning',
                                  style: TextStyle(
                                      fontSize: 18, color: Colors.black),
                                ),
                                Container(
                                  margin: EdgeInsets.only(left: 10),
                                  padding: EdgeInsets.symmetric(
                                      horizontal: 5, vertical: 3),
                                  decoration: BoxDecoration(
                                      color: Colors.blue,
                                      borderRadius: BorderRadius.circular(10)),
                                  child: Text(
                                    'LV2',
                                    style: TextStyle(
                                        fontSize: 12,
                                        color: Colors.white,
                                        fontWeight: FontWeight.bold),
                                  ),
                                )
                              ],
                            ),
                            Text(
                              'One morning',
                              style:
                                  TextStyle(fontSize: 16, color: Colors.grey),
                            ),
                          ],
                        ),
                        FlatButton(
                          onPressed: () {},
                          child: Text(
                            'edit',
                            style: TextStyle(color: Colors.blue),
                          ),
                          shape: StadiumBorder(),
                          padding: EdgeInsets.symmetric(horizontal: 10),
                          color: Colors.grey.withOpacity(0.2),
                        )
                      ],
                    ),
                    Padding(padding: EdgeInsets.only(top: 20)),
                    Row(
                      children: [
                        Container(
                          margin: EdgeInsets.only(left: 0),
                          child: Column(
                            children: [
                              Text(
                                '9999',
                                style: TextStyle(
                                    fontSize: 14, color: Colors.black),
                              ),
                              Text(
                                'attention',
                                style:
                                    TextStyle(fontSize: 12, color: Colors.grey),
                              ),
                            ],
                          ),
                        ),
                        Container(
                          margin: EdgeInsets.only(left: 40),
                          child: Column(
                            children: [
                              Text(
                                '9999',
                                style: TextStyle(
                                    fontSize: 14, color: Colors.black),
                              ),
                              Text(
                                'Followers',
                                style:
                                    TextStyle(fontSize: 12, color: Colors.grey),
                              ),
                            ],
                          ),
                        ),
                        Container(
                            margin: EdgeInsets.only(left: 40),
                            child: Column(
                              children: [
                                Text(
                                  '99999',
                                  style: TextStyle(
                                      fontSize: 14, color: Colors.black),
                                ),
                                Text(
                                  'Digging value',
                                  style: TextStyle(
                                      fontSize: 12, color: Colors.grey),
                                ),
                              ],
                            ))
                      ],
                    )
                  ],
                ),
              )),
          Positioned(
              left: 0,
              right: 0,
              bottom: 190,
              child: UnconstrainedBox(
                alignment: Alignment.centerLeft,
                child: Container(
                  width: 80,
                  height: 80,
                  margin: EdgeInsets.only(left: 20),
                  decoration: BoxDecoration(
                      color: Colors.blue,
                      borderRadius: BorderRadius.circular(40),
                      border: Border.all(color: Colors.white, width: 4)),),)),Copy the code

Now we’re going to build the list page, and that’s a little bit easier, so we’re just going to write a list wiget that we encapsulated in SliverFillRemaining using CommonListWiget

 SliverFillRemaining(
            child: TabBarView(
              controller: tabController,
              children: <Widget>[
                CommonListWiget(
                  networkApi: (currentPage) async {
                    return ['1'.'1'.'1'.'1'];
                  },
                  itemBuilder: (BuildContext context, int position) {
                    return itemWidget(true);
                  },
                ),
                CommonListWiget(
                  networkApi: (currentPage) async {
                    return ['1'.'1'.'1'.'1'];
                  },
                  itemBuilder: (BuildContext context, int position) {
                    return itemWidget(true);
                  },
                ),
                CommonListWiget(
                  networkApi: (currentPage) async {
                    return ['1'.'1'.'1'.'1'];
                  },
                  itemBuilder: (BuildContext context, int position) {
                    return itemWidget(true);
                  },
                ),
                CommonListWiget(
                  networkApi: (currentPage) async {
                    return ['1'.'1'.'1'.'1'];
                  },
                  itemBuilder: (BuildContext context, int position) {
                    return itemWidget(true); },),],),Copy the code

Over ~ ~ ~