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

Flutter问题:SingleChildScrollView中拖动ReorderableListView项时页面不滚动

问题分析与解决方案

问题根源在于你将ReorderableListView嵌套在SingleChildScrollView中并共用同一个ScrollController,导致ReorderableListView自身的拖动自动滚动逻辑被外层滚动组件干扰,无法触发屏幕外的滚动交换。

以下是两种针对性解决方案,可根据你对顶部信息的滚动需求选择:


方案一:顶部信息随列表滚动

该方案下顶部信息会跟随帖子列表一起滚动,同时拖动帖子时可正常触发自动滚动,与屏幕外的帖子交换位置。

修改后的完整代码:

import 'package:flutter/material.dart';

class PostsView extends StatefulWidget {
  const PostsView({super.key});

  @override
  State<PostsView> createState() => _PostsViewState();
}

class _PostsViewState extends State<PostsView> {
  final ScrollController _scrollController = ScrollController();
  List<int> _posts = List.generate(20, (index) => index);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 顶部个人信息区域
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  "My Profile",
                  style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                ),
                Card(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Row(
                        children: [
                          CircleAvatar(
                            radius: 20,
                            backgroundImage: NetworkImage(
                                'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfGaPeS62qusTUFyVchOrh_r2cL4_P8-q3bg&s'),
                          ),
                          SizedBox(width: 10),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text('John Doe'),
                              Text(
                                  "Hello, my name is John. Welcome to my profile."),
                              Text("Followers: 100"),
                              Text("Following: 100"),
                              Text("Posts: 100"),
                              Text("Comments: 100"),
                              Text("Likes: 100"),
                            ],
                          )
                        ],
                      ),
                      Icon(Icons.more_vert)
                    ],
                  ),
                ),
              ],
            ),
          ),
          SizedBox(height: 20),
          // 用Expanded让ReorderableListView占满剩余空间,获得独立滚动能力
          Expanded(
            child: ReorderableListView.builder(
              scrollController: _scrollController,
              itemExtent: 200,
              itemBuilder: (context, index) {
                return ReorderableDelayedDragStartListener(
                  key: ValueKey(_posts[index]),
                  index: index,
                  child: Container(
                    margin: EdgeInsets.only(bottom: 10, left: 16, right: 16),
                    decoration: BoxDecoration(
                      color: Colors.grey.shade200,
                      borderRadius: BorderRadius.circular(10),
                      border: Border.all(color: Colors.black),
                    ),
                    child: Column(
                      children: [
                        Image.network(
                          'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfGaPeS62qusTUFyVchOrh_r2cL4_P8-q3bg&s',
                          width: 100,
                          height: 100,
                        ),
                        Text("Post title: ${_posts[index]}"),
                        Text("Post description: ${_posts[index]}"),
                        Text("Post date: ${_posts[index]}"),
                      ],
                    ),
                  ),
                );
              },
              itemCount: _posts.length,
              onReorder: (oldIndex, newIndex) {
                setState(() {
                  if (newIndex > oldIndex) newIndex -= 1;
                  final item = _posts.removeAt(oldIndex);
                  _posts.insert(newIndex, item);
                });
              },
            ),
          ),
        ],
      ),
    );
  }
}

方案二:顶部信息固定不动

若需要顶部个人信息始终固定在页面顶部,不随列表滚动,可使用Stack实现,同时给ReorderableListView设置顶部内边距避免内容被遮挡。

修改后的完整代码:

import 'package:flutter/material.dart';

class PostsView extends StatefulWidget {
  const PostsView({super.key});

  @override
  State<PostsView> createState() => _PostsViewState();
}

class _PostsViewState extends State<PostsView> {
  final ScrollController _scrollController = ScrollController();
  List<int> _posts = List.generate(20, (index) => index);
  final double _topSectionHeight = 220; // 估算顶部信息区域高度

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          // 帖子列表,设置顶部内边距避开固定的顶部信息
          Padding(
            padding: EdgeInsets.only(top: _topSectionHeight),
            child: ReorderableListView.builder(
              scrollController: _scrollController,
              itemExtent: 200,
              itemBuilder: (context, index) {
                return ReorderableDelayedDragStartListener(
                  key: ValueKey(_posts[index]),
                  index: index,
                  child: Container(
                    margin: EdgeInsets.only(bottom: 10, left: 16, right: 16),
                    decoration: BoxDecoration(
                      color: Colors.grey.shade200,
                      borderRadius: BorderRadius.circular(10),
                      border: Border.all(color: Colors.black),
                    ),
                    child: Column(
                      children: [
                        Image.network(
                          'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfGaPeS62qusTUFyVchOrh_r2cL4_P8-q3bg&s',
                          width: 100,
                          height: 100,
                        ),
                        Text("Post title: ${_posts[index]}"),
                        Text("Post description: ${_posts[index]}"),
                        Text("Post date: ${_posts[index]}"),
                      ],
                    ),
                  ),
                );
              },
              itemCount: _posts.length,
              onReorder: (oldIndex, newIndex) {
                setState(() {
                  if (newIndex > oldIndex) newIndex -= 1;
                  final item = _posts.removeAt(oldIndex);
                  _posts.insert(newIndex, item);
                });
              },
            ),
          ),
          // 固定在顶部的个人信息区域
          Container(
            color: Theme.of(context).scaffoldBackgroundColor,
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  "My Profile",
                  style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                ),
                Card(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Row(
                        children: [
                          CircleAvatar(
                            radius: 20,
                            backgroundImage: NetworkImage(
                                'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfGaPeS62qusTUFyVchOrh_r2cL4_P8-q3bg&s'),
                          ),
                          SizedBox(width: 10),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text('John Doe'),
                              Text(
                                  "Hello, my name is John. Welcome to my profile."),
                              Text("Followers: 100"),
                              Text("Following: 100"),
                              Text("Posts: 100"),
                              Text("Comments: 100"),
                              Text("Likes: 100"),
                            ],
                          )
                        ],
                      ),
                      Icon(Icons.more_vert)
                    ],
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

关键修改说明

  1. 移除外层的SingleChildScrollView,让ReorderableListView拥有独立滚动空间
  2. 给ReorderableListView单独分配ScrollController,避免滚动逻辑冲突
  3. 完善onReorder逻辑,实际实现帖子的重新排序功能

内容的提问来源于stack exchange,提问作者Burak AkşamYatmazSabahKalkmaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 19:47:33