You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter实现列表滚动覆盖头部至AppBar底部的问题求助

需求描述

我想要实现这样的效果:列表的白色区域可以滚动覆盖蓝色头部区域,直到到达AppBar底部,效果参考以下截图:




初始尝试代码(TestScreen)

class TestScreen extends StatelessWidget   {
  const TestScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    AppController appController = Provider.of<AppController>(context);
    HomeController homeController = Provider.of<HomeController>(context);
    String selectedCategory = homeController.selectedCategory;
    return SafeArea(
      child: Container(
        //height: 450,
        width: double.infinity,
        decoration: const BoxDecoration(
            image: DecorationImage(
          image: AssetImage('assets/images/home_header.png'),
          alignment: Alignment.topCenter,
          repeat: ImageRepeat.repeatY,
        )),
        child: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.transparent,
            elevation: 0,
            flexibleSpace: Padding(
              padding: const EdgeInsets.only(left: 20, right: 20),
              child: ChiscoAppbar(
                icon: MENU,
                iconAlignment: Alignment.centerLeft,
                title: 'خانه',
                onClick: () {
                  Navigator.pushNamed(context, '/account');
                },
              ),
            ),
          ),
          backgroundColor: Colors.transparent,
          body: Stack(
            children: [
              Positioned(
                child: Container(
                  color: Colors.transparent,
                  height: 200,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Expanded(
                        flex: 3,
                        child: Align(
                            alignment: Alignment.center,
                            child: ChiscoText(
                              text: 'دستگاه‌های هوشمند چیسکو',
                              fontWeight: FontWeight.w500,
                              textColor: Colors.white,
                              fontSize: 16,
                            )),
                      ),
                      Expanded(
                          flex: 1,
                          child: Padding(
                            padding: EdgeInsets.only(left: 20, right: 20),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: const [
                                HeaderItem(
                                  titleText: 'کنترلر',
                                  icon: COOLER,
                                  counterText: '2',
                                ),
                                HeaderItem(
                                  titleText: 'سه راهی',
                                  icon: SOCKET,
                                  counterText: '2',
                                )
                              ],
                            ),
                          )),
                    ],
                  ),
                ),
              ),
              Positioned(
                  top: homeController.customPixel+20 ,
                  bottom: 0,
                  child: Container(
                    color: Styles.backGroundColor,
                    height: MediaQuery.of(context).size.height,
                    width: MediaQuery.of(context).size.width,
                  )),
              NotificationListener<ScrollNotification>(
                onNotification: homeController.scrollNotification,
                child: CustomScrollView(
                  slivers: [
                    SliverToBoxAdapter(
                        child: Container(
                      height: 200,
                      color: Colors.transparent,
                    )),
                    SliverPersistentHeader(
                      delegate: OnTapHeader(),
                      floating: false,
                      pinned: true,
                    ),
                    SliverToBoxAdapter(
                        child: Container(
                      margin: const EdgeInsets.fromLTRB(20, 8, 20, 10),
                      height: 30,
                      child: ListView.builder(
                          physics: const BouncingScrollPhysics(),
                          itemCount: appController.listOfDevicesCategory.length,
                          scrollDirection: Axis.horizontal,
                          primary: true,
                          addSemanticIndexes: false,
                          itemBuilder: (context, index) {
                            String category =
                                appController.listOfDevicesCategory[index];
                            return CategoryListItem(
                              isSelected: selectedCategory == category,
                              category: category,
                            );
                          }),
                    )),
                    DeviceGridList()
                  ],
                ),
              ),
            ],
          ),
          floatingActionButton:Container(
              margin: const EdgeInsets.only(bottom: 16),
              child: const ChiscoSpeedDial()),
          floatingActionButtonLocation: FloatingActionButtonLocation.startDocked,
        ),
      ),
    );
  }
}

使用Sliver组件时,白色区域会折叠蓝色头部区域,无法达到预期效果;且正常状态下白色区域需位于蓝色区域上方,请问如何实现该需求?

更新尝试(使用DraggableScrollableSheet)

我尝试使用DraggableScrollableSheet来实现列表,但内部嵌套Column后效果异常,效果如下:

对应的HomeScreen代码:

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    AppController appController = Provider.of<AppController>(context);
    HomeController homeController = Provider.of<HomeController>(context);
    String selectedCategory = homeController.selectedCategory;
    return SafeArea(
      child: Container(
        //height: 450,
        width: double.infinity,
        decoration: const BoxDecoration(
            image: DecorationImage(
          image: AssetImage('assets/images/home_header.png'),
          alignment: Alignment.topCenter,
        )),
        child: Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.transparent,
            elevation: 0,
            flexibleSpace: Padding(
              padding: const EdgeInsets.only(left: 20, right: 20),
              child: ChiscoAppbar(
                icon: MENU,
                iconAlignment: Alignment.centerLeft,
                title: 'خانه',
                onClick: () {
                  Navigator.pushNamed(context, '/account');
                },
              ),
            ),
          ),
          backgroundColor: Colors.transparent,
          body: Stack(
            children: [
              Positioned(
                child: Container(
                  color: Colors.transparent,
                  height: 200,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Expanded(
                        flex: 3,
                        child: Align(
                            alignment: Alignment.center,
                            child: ChiscoText(
                              text: 'دستگاه‌های هوشمند چیسکو',
                              fontWeight: FontWeight.w500,
                              textColor: Colors.white,
                              fontSize: 16,
                            )),
                      ),
                      Expanded(
                          flex: 1,
                          child: Padding(
                            padding: EdgeInsets.only(left: 20, right: 20),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: const [
                                HeaderItem(
                                  titleText: 'کنترلر',
                                  icon: COOLER,
                                  counterText: '2',
                                ),
                                HeaderItem(
                                  titleText: 'سه راهی',
                                  icon: SOCKET,
                                  counterText: '2',
                                )
                              ],
                            ),
                          )),
                    ],
                  ),
                ),
              ),
              Positioned(
                child: DraggableScrollableSheet(
                  expand: true,
                  minChildSize: 0.70,
                  maxChildSize: 0.95,
                  initialChildSize: 0.70,
                  builder: (context, scrollController) {
                    return Container(
                      decoration: BoxDecoration(
                          color: Colors.blue[100],
                          borderRadius: const BorderRadius.only(
                              topLeft: Radius.circular(25),
                              topRight: Radius.circular(25))),
                      child: SingleChildScrollView(
                        controller: scrollController,
                        child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                            ListHandlerView(),
                            Container(
                              margin: const EdgeInsets.fromLTRB(20, 8, 20, 10),
                              height: 30,
                              child: ListView.builder(
                                  shrinkWrap: true,
                                  physics: const BouncingouncingScrollPhysics(),
                                  itemCount:
                                      appController.listOfDevicesCategory.length,
                                  scrollDirection: Axis.horizontal,
                                  primary: true,
                                  addSemanticIndexes: false,
                                  itemBuilder: (context, index) {
                                    String category = appController
                                        .listOfDevicesCategory[index];
                                    return CategoryListItem(
                                      isSelected: selectedCategory == category,
                                      category: category,
                                    );
                                  }),
                            ),
                            Container(
                              decoration: BoxDecoration(
                                  color: Colors.blue[100],
                                  borderRadius: const BorderRadius.only(
                                      topLeft: Radius.circular(25),
                                      topRight: Radius.circular(25))),
                              child: ListView.builder(
                                shrinkWrap: true,
                                itemCount: 25,
                                controller: scrollController,
                                itemBuilder: (BuildContext context, int index) {
                                  return ListTile(title: Text('Item $index'));
                                },
                              ),
                            ),
                          ],
                        ),
                      ),
                    );
                  },
                ),
              )
            ],
          ),
          floatingActionButton: Container(
              margin: const EdgeInsets.only(bottom: 16),
              child: const ChiscoSpeedDial()),
          floatingActionButtonLocation: FloatingActionButtonLocation.startDocked,
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者MehdiAbolhassani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 08:06:20