简体   繁体   English

(颤振)无限滚动“ListView.builder”,内容有限

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

1. The Problem 1.问题

How do I make my ListView.builder be able to scroll to empty space both to the top and to the bottom?如何让我的ListView.builder能够滚动到顶部和底部的空白空间?

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.例如,我有一个自定义小部件列表,我希望用户能够通过滚动到列表中的顶部卡片(位于屏幕顶部)更靠近他的拇指,同时Flutter呈现背景为空的顶部空间。

2. What I've tried so far 2.到目前为止我尝试过的

The basic shape of my code is a basic implementation of the ListView.builder constructor:我的代码的基本形状是ListView.builder构造函数的基本实现:

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:到目前为止,我已经尝试摆弄ListView.builder的一些属性以及一些解决方法:

  1. At first, I thought that either shrinkWrap: true or physics: AlwaysScrollableScrollPhysics() — maybe I have to set the parent parameter of AlwaysScrollableScrollPhysics() ?起初,我认为要么shrinkWrap: true要么physics: AlwaysScrollableScrollPhysics() ——也许我必须设置AlwaysScrollableScrollPhysics()parent参数? — 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.我还尝试通过在列表的顶部和底部创建空Container并添加类似dragStartBehavior: DragStartBehavior.values[1]之类的东西来人为地做到这一点——我认为这不是你使用.values的方式属性实际上 - 使列表从第二个值开始,但它不起作用。

If I understand it correctly, your best bet would be using a CustomScrollView with an expandable space in the SliverAppBar .如果我理解正确,您最好的选择是在SliverAppBar中使用具有可扩展空间的CustomScrollView

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".这可以通过您的“ Container解决方法”来实现。 You could use a ScrollController and have its initialScrollOffset where the top Container ends.您可以使用ScrollController并将其initialScrollOffset放在顶部Container结束处。 It is something I only later found out through this other StackOverflow question .这是我后来通过另一个 StackOverflow 问题才发现的。

  1. Declare your ScrollController inside your widget's class.在小部件的 class 中声明ScrollController
     ScrollController scrollController = ScrollController( initialScrollOffset: 10, // or whatever offset you wish keepScrollOffset: true, );
  2. Add the controller to your ListView将 controller 添加到您的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 .这可以通过在小部件的initState中使用.animateTo方法来实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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