【问题标题】:Flutter ListView scroll to index insufficient scrollingFlutter ListView 滚动索引滚动不足
【发布时间】:2021-07-11 05:57:33
【问题描述】:

我有一个可扩展的列表视图,但我遇到了滚动问题。单独选择或者慢慢滑动都没有问题,但是当你快速滚动选择时就会出现滑动不足的问题。

我添加了一个“dartpad”,以便可以测试代码。可能是什么问题?

代码:https://dartpad.dev/c4015095fc23456619eb20a5edcb0e8b
视频:https://vimeo.com/532603204

【问题讨论】:

    标签: flutter dart flutter-layout flutter-animation dart-pub


    【解决方案1】:

    这是一个有趣的问题,我有一些时间来处理这个问题,并且我在日志中看到滚动控制器似乎更新得很好。但是,由于某种原因,它不起作用,所以我在列表周围放置了滚动视图,并且没有给 ListView.builder 滚动。只有这个要考虑的是列表的最后部分,因为如果你在最后部分,你不想向下滚动更多,因为你不能再向下滚动。

    这可能不是最好的解决方案,但它是我设法放在一起的,希望这会有所帮助。

    import 'dart:developer';
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Scroll Bug Demo',
          home: MainScreen(),
        );
      }
    }
    
    class MainScreen extends StatefulWidget {
      @override
      _MainScreenState createState() => _MainScreenState();
    }
    
    class _MainScreenState extends State<MainScreen> {
      final _demoList = List.generate(100, (index) => 'List Item $index');
      int _expandedIndex = -1;
      final _scrollController = ScrollController();
    
      bool _isExpanded = false;
      bool _isInLastPart = false;
    
      @override
      Widget build(BuildContext context) {
        _isInLastPart = (_expandedIndex > _demoList.length - 15);
    
        final _size = MediaQuery.of(context).size;
        return SafeArea(
          child: Scaffold(
            body: SingleChildScrollView(
              controller: _scrollController,
              child: SizedBox(
                height: (48 * _demoList.length).toDouble() +
                    ((_isExpanded && _isInLastPart) ? 80 : 0).toDouble(),
                width: _size.width,
                child: ListView.builder(
                  physics: NeverScrollableScrollPhysics(),
                  itemBuilder: (context, index) {
                    return GestureDetector(
                      onTap: () => clickItem(index),
                      child: Container(
                        color: Colors.grey,
                        height: (_expandedIndex == index && _isExpanded) ? 120 : 40,
                        margin: EdgeInsets.only(bottom: 8),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            Text(_demoList[index]),
                            if (_expandedIndex == index && _isExpanded)
                              Column(
                                children: <Widget>[
                                  Text('text'),
                                  Text('text'),
                                  Text('text'),
                                  Text('text'),
                                  Text('text'),
                                ],
                              ),
                          ],
                        ),
                      ),
                    );
                  },
                  itemCount: _demoList.length,
                ),
              ),
            ),
          ),
        );
      }
    
      clickItem(int index) {
        setState(() {
          if (_expandedIndex == index)
            _isExpanded = !_isExpanded;
          else
            _isExpanded = true;
          _expandedIndex = index;
        });
        if (_expandedIndex < _demoList.length - 15) {
          // log("expanded index_: $_expandedIndex, index: $index, jump to: ${index * 48.toDouble()}/${99 * 48.toDouble()}, scroll> ${_scrollController.position.pixels},isExpanded: $_isExpanded");
          _scrollController.jumpTo(index * 48.toDouble());
        } else {
          if (_isExpanded) {
            // log("expanded index_: $_expandedIndex, index: $index, jump to: ${83 * 48.toDouble() + 8}/${99 * 48.toDouble()}, scroll> ${_scrollController.offset},isExpanded: $_isExpanded");
    
            _scrollController.jumpTo(83 * 48.toDouble() + 80 + 8);
          } else {
            // log("expanded index_: $_expandedIndex, index: $index, jump to: ${83 * 48.toDouble() + 80 + 8}/${99 * 48.toDouble()}, scroll> ${_scrollController.offset}, isExpanded: $_isExpanded");
            _scrollController.jumpTo(83 * 48.toDouble() + 8);
          }
        }
      }
    }
    

    【讨论】:

    • 谢谢,这是一个非常有趣的解决方案 :) 但它有效!
    猜你喜欢
    • 2022-11-15
    • 2022-01-25
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 2020-03-18
    • 2020-11-27
    • 1970-01-01
    • 2020-12-30
    相关资源
    最近更新 更多