Flutter: Listview get full size of scrollcontroller after adding item to list & scroll to end

前端 未结 2 1817
慢半拍i
慢半拍i 2021-01-15 08:11

This post describes a very similar problem, but the answer there doesn\'t solve all problems:

I have a potentially long List, where the user can add new items (on at

相关标签:
2条回答
  • 2021-01-15 08:39

    I combined scroll to maxScrollExtent with Scrollable.ensureVisible and each of them fixed the flaws of the other.

    import 'package:flutter/material.dart';
    import 'package:flutter/scheduler.dart';
    
    class MyList extends StatefulWidget {
      MyList({Key key}) : super(key: key);
    
      @override
      _MyListState createState() => _MyListState();
    }
    
    class _MyListState extends State<MyList> {
      final ScrollController _scrollController = ScrollController();
      final lastKey = GlobalKey();
      List<String> items;
    
      @override
      void initState() {
        super.initState();
        items = List<String>.generate(8, (i) => "Item $i");
      }
    
      void add() {
        setState(() {
          items.add("new Item ${items.length}");
        });
        SchedulerBinding.instance.addPostFrameCallback((_) => scrollToEnd());
      }
    
      void scrollToEnd() async {
        await _scrollController.animateTo(
            _scrollController.position.maxScrollExtent,
            duration: const Duration(milliseconds: 350),
            curve: Curves.easeOut);
        Scrollable.ensureVisible(lastKey.currentContext);
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            title: "List",
            home: Scaffold(
              body: ListView.builder(
                controller: _scrollController,
                itemCount: items.length,
                shrinkWrap: true,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text('${items[index]}'),
                    key: index == items.length - 1 ? lastKey : null,
                  );
                },
              ),
              floatingActionButton: FloatingActionButton(
                onPressed: () {
                  add();
                },
                child: Icon(Icons.add),
              ),
            ));
      }
    }
    

    Scrollable.ensureVisible itself cannot provide visibility if the item has not yet been created, but copes with them when item is very close.

    0 讨论(0)
  • 2021-01-15 08:44

    Specifying a too large scrollPosition works without errors, the ScrollController then automatically scrolls to the final maximum value. I define a _scrollController and execute the following command:

    _scrollController.animateTo(
        _scrollController.position.maxScrollExtent + 200,
        duration: const Duration(milliseconds: 350),
        curve: Curves.easeOut);
    

    or

    _scrollController.jumpTo(_scrollController.position.maxScrollExtent + 200);
    
    0 讨论(0)
提交回复
热议问题