0

颤振飞镖垫

SliverAppBar在一个内有多个CustomScrollView,屏幕的主体在 内SliverFillRemaining


顶部 SliverAppBar 已固定
中间 SliverAppBar 是一个图像,将在用户滚动时折叠
底部 SliverAppBar 是一个固定的 TabBar,在图像完全折叠后将保持在第一个 SliverAppBar 下方

目前的经验是,最初滚动时,body 滚动到最下面的 SliverAppBar 下。我已经尝试使用 SliverOverlapAbsorber/Injector,但这只是在主体顶部添加了一个空间,以便空间重叠而不是主体,但这不是我想要的。


我希望 body 和 SliverAppBars 一起滚动,直到 Middle SliverAppBar 完全折叠,然后我希望 body 滚动。

我已经为此工作了几个小时,你如何阻止身体在滚动上重叠?

4

1 回答 1

1

为了实现这种滚动行为,它更容易使用NestedScrollView并注意主应用栏不再位于条子中

在此处输入图像描述

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  MyWidgetState createState() => MyWidgetState();
}

class MyWidgetState extends State<MyWidget>
    with SingleTickerProviderStateMixin {
  TabController _tabController;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('title'),
        elevation: 0,
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {},
        ),
      ),
      body: NestedScrollView(
        floatHeaderSlivers: true,
        physics: const BouncingScrollPhysics(),
        body: TabBarView(
          controller: _tabController,
          physics: const NeverScrollableScrollPhysics(),
          children: [
            SingleChildScrollView(
              physics: const NeverScrollableScrollPhysics(),
              child: Column(
                children: List.generate(
                  1000,
                  (index) => Text('Tab One: $index'),
                ),
              ),
            ),
            SingleChildScrollView(
              physics: const NeverScrollableScrollPhysics(),
              child: Column(
                  children: List.generate(
                1000,
                (index) => Text('Tab Two: $index'),
              )),
            )
          ],
        ),
        headerSliverBuilder: (context, innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              pinned: true,
              floating: false,
              elevation: 0,
              toolbarHeight: 0,
              collapsedHeight: null,
              automaticallyImplyLeading: false,
              expandedHeight: MediaQuery.of(context).size.height * .4,
              flexibleSpace: const FlexibleSpaceBar(
                  collapseMode: CollapseMode.parallax,
                  background: Placeholder()),
              titleSpacing: 0,
              primary: false,
            ),
            SliverAppBar(
              pinned: true,
              forceElevated: true,
              primary: false,
              automaticallyImplyLeading: false,
              expandedHeight: 50,
              collapsedHeight: null,
              toolbarHeight: 50,
              titleSpacing: 0,
              title: Align(
                alignment: Alignment.topCenter,
                child: TabBar(
                    controller: _tabController,
                    isScrollable: true,
                    tabs: [
                      const Text('Tab One'),
                      const Text('Tab Two'),
                    ]),
              ),
            ),
          ];
        },
      ),
    );
  }
}
于 2021-05-06T00:22:59.877 回答