【问题标题】:Flutter ListView scroll animation overlapping sibling widgetFlutter ListView 滚动动画重叠兄弟小部件
【发布时间】:2021-01-14 01:45:44
【问题描述】:

希望有人可以帮助解决这个问题,这不是错误,只是我很傻。

当列表视图没有占据屏幕的整个长度并在列中时,它会出现非常奇怪的行为。

向下滚动时,最大范围的动画会持续存在并重叠。我假设这是一个错误,而不是设计使然。

这是重现的简单代码。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp(
    items: List<MessageItem>.generate(
      33,
      (i) => MessageItem("Sender $i", "Message body $i"),
    ),
  ));
}

class MyApp extends StatelessWidget {
  final List<MessageItem> items;

  MyApp({Key key, @required this.items}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final title = 'Mixed List';

    return MaterialApp(
      title: title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Column(
          children: [
            Expanded(
              child: Container(),
            ),
            Expanded(
              child: ListView.builder(
                itemCount: items.length,
                itemBuilder: (context, index) {
                  final item = items[index];

                  return ListTile(
                    title: item.buildTitle(context),
                    subtitle: item.buildSubtitle(context),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

/// A ListItem that contains data to display a message.
class MessageItem {
  final String sender;
  final String body;

  MessageItem(this.sender, this.body);

  Widget buildTitle(BuildContext context) => Text(sender);

  Widget buildSubtitle(BuildContext context) => Text(body);
}

【问题讨论】:

    标签: flutter listview animation overlap


    【解决方案1】:

    所以最终代码将是。我已经添加了滚动 phisycs BouncingScrollPhysics

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp(
        items: List<MessageItem>.generate(
          33,
          (i) => MessageItem("Sender $i", "Message body $i"),
        ),
      ));
    }
    
    class MyApp extends StatelessWidget {
      final List<MessageItem> items;
    
      MyApp({Key key, @required this.items}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        final title = 'Mixed List';
    
        return MaterialApp(
          title: title,
          home: Scaffold(
            appBar: AppBar(
              title: Text(title),
            ),
            body: Column(
              children: [
                Expanded(
                  child: Container(
                  ),
                ),
                Expanded(
                  child: ListView.builder(
                    physics: BouncingScrollPhysics(
                        parent: AlwaysScrollableScrollPhysics()),
                    itemCount: 50,
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text("${index + 1}"),
                        subtitle: Text("${index + 1}"),
                      );
                    },
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    /// A ListItem that contains data to display a message.
    class MessageItem {
      final String sender;
      final String body;
    
      MessageItem(this.sender, this.body);
    
      Widget buildTitle(BuildContext context) => Text(sender);
    
      Widget buildSubtitle(BuildContext context) => Text(body);
    }
    

    【讨论】:

    • 感谢您的回复。但我想要那个容器。我的问题是重叠到上部容器中。正如您在 gif 中看到的那样,蓝色的 blob 携带到上部容器上。我想在顶部固定内容,在下半部分滚动内容
    • 放一些固定高度的容器,如果你设置Expanded,它会像gif一样
    • 在固定容器高度的情况下,这就是它的作用ibb.co/NWKZc16。我再次通过使用嵌套滚动视图解决了这个问题。对于应该直截了当的事情,这是一个过于复杂的解决方案。
    • 可以停止总溢出
    【解决方案2】:

    我不确定这是否是错误。或者,如果我的解决方案是正确的方法,或者不是。但这项工作

    
      @override
      Widget build(BuildContext context) {
        return NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              SliverOverlapAbsorber(
                handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                sliver: SliverAppBar(
                  backgroundColor: Colors.white,
                  toolbarHeight: 200,
                  pinned: true,
                  forceElevated: innerBoxIsScrolled,
                ),
              ),
            ];
          },
          body: Container(
              child: SafeArea(
            top: false,
            bottom: false,
            child: Builder(
              builder: (BuildContext context) {
                return CustomScrollView(
                  key: PageStorageKey<String>("name"),
                  slivers: <Widget>[
                    SliverOverlapInjector(
                      handle:
                          NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                    ),
                    SliverPadding(
                      padding: const EdgeInsets.all(8.0),
                      sliver: SliverFixedExtentList(
                        itemExtent: 48.0,
                        delegate: SliverChildBuilderDelegate(
                          (BuildContext context, int index) {
                            return ListTile(
                              title: Text('Item $index'),
                            );
                          },
                          childCount: 30,
                        ),
                      ),
                    ),
                  ],
                );
              },
            ),
          )),
        );
      }
    

    我不喜欢这样的原因是我将非栏内容放在 AppBar 中。

    如果有人有更好的解决方案,请告诉我。

    【讨论】:

    • 附言。再好不过了。将应用栏高度设置为 0。并将其放在一列中!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 2019-09-15
    • 2019-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多