简体   繁体   中英

(Flutter) Infinite Scroll `ListView.builder` with Finite Content

1. The Problem

How do I make my ListView.builder be able to scroll to empty space both to the top and to the bottom?

For example, I have a list of custom widgets, and I would like the user to be able to get the top card on the list — which is at the top of the screen — closer to his thumb by scrolling to it, while Flutter renders the top space with an empty background.

2. What I've tried so far

The basic shape of my code is a basic implementation of the ListView.builder constructor:

ListView.builder(
  itemCount: widgetsList.length,
  itemBuilder: (context, index){
    return widgetsList[index];
  },
),

I've tried fiddling with some of the ListView.builder 's properties and also some workarounds so far:

  1. At first, I thought that either shrinkWrap: true or physics: AlwaysScrollableScrollPhysics() — maybe I have to set the parent parameter of AlwaysScrollableScrollPhysics() ? — would do the job, but none of them seem to work.
  2. I've also tried to do this artifially by creating empty Container s both on the top and the bottom of the list, and adding something like dragStartBehavior: DragStartBehavior.values[1] — I don't think that's how you use the .values property actually — to make the list start from the second value, but it didn't work.

If I understand it correctly, your best bet would be using a CustomScrollView with an expandable space in the SliverAppBar .

Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: [
         SliverAppBar(
           automaticallyImplyLeading: false, // gets rid of the back arrow
           expandedHeight: 250, // the collapsible space you want to use 
           flexibleSpace: FlexibleSpaceBar(
             background: Container(
               color: Colors.transparent
             ),
           ),
         ),
         SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) {
              // put your widgetsList here
            },
            childCount: widgetsList.length,
          ),
        ),
      ]
    ),
  );
}

That is possible to be achived with your " Container workaround". You could use a ScrollController and have its initialScrollOffset where the top Container ends. It is something I only later found out through this other StackOverflow question .

  1. Declare your ScrollController inside your widget's class.
     ScrollController scrollController = ScrollController( initialScrollOffset: 10, // or whatever offset you wish keepScrollOffset: true, );
  2. Add the controller to your ListView
     ListView.builder( controller: scrollController, itemCount: widgetsList.length, itemBuilder: (context, index){ return widgetsList[index]; }, ),

Additionally, you may even want to create animations for the background scrolling action. That is possible through using the .animateTo method inside your widget's initState .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM