gpt4 book ai didi

flutter - Flutter-如何制作一个自定义小部件,以将页脚添加到接收到的可滚动小部件中?

转载 作者:行者123 更新时间:2023-12-03 03:59:17 26 4
gpt4 key购买 nike

我正在创建一个自定义小部件,该控件将页脚作为最后一项添加到收到的任何可滚动小部件中。

理想的用法是这样的:

ScrollableWithFooter(
child: ListView.builder(...),
footer: Text('Footer'),
)

ScrollableWithFooter(
child: GridView.builder(...),
footer: Text('Footer'),
)

ScrollableWithFooter(
child: CustomListView.builder(...),
footer: Text('Footer'),
)

ScrollableWithFooter(
child: SingleChildScrollView.builder(...),
footer: Text('Footer'),
)

ScrollableWithFooter(
child: StaggeredGridView.builder(...),
footer: Text('Footer'),
)

这是我采用的方法:
class ScrollableWithFooter extends StatefulWidget {
final ScrollView child;
final Widget footer;

ScrollableWithFooter({Key key, this.child, this.footer}) : super(key: key);

@override
State<StatefulWidget> createState() => ScrollableWithFooterState();
}

class ScrollableWithFooterState extends State<ScrollableWithFooter> {
final _scrollController = ScrollController();

@override
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
scrollDirection: widget.child.scrollDirection,
itemCount: 2,
itemBuilder: (context, index) {
if (index == 0) {
return widget.child;
}
return widget.footer;
},
);
}
}

请注意,它具有 ScrollController,因为我需要知道该页脚是否对其他功能可见。

问题
  • widget.child必须包装其内容,否则:Vertical viewport was given unbounded height。我尝试用widget.childWrap包装IntrinsicHeight,但是不起作用。我唯一能做的就是如果assert没有widget.child,则制作一个shrinkWrap: true
  • 无需滚动widget.child,否则自定义窗口小部件将不会滚动,因为widget.childListView包装。我尝试用widget.childIgnorePointer包装GestureDetector,但无法点击这些项目。如果assert不是widget.child,我唯一能做的就是制作一个phyisics
  • 如果NeverScrollableScrollPhysics具有widget.child,则由于controller不应该滚动,因此我必须将该widget.child传递给父controller,但我会得到:ListView。我唯一能做的就是允许自定义窗口小部件接收ScrollController attached to multiple scroll views,如果controller具有assert,则制作一个widget.child

  • 问题
  • 如何解决这些问题?
  • 这是一个好方法吗?
  • 我还能采取什么其他方法?
  • 最佳答案

    通过查看ScrollView类,我找到了解决方案:

    在自定义窗口小部件中,不必使用收到的widget.child,而是创建一个新的Scrollable小部件,方法是:

  • Scrollable将具有NeverScrollableScrollPhysics
  • Scrollable将没有controller
  • Scrollable将返回带有以下内容的ShrinkWrappingViewport:axisDirection中的sliverswidget.child

  • 这是自定义小部件的实现:
    var _scrollController = ScrollController();

    @override
    void initState() {
    super.initState();
    _scrollController = widget.child.controller ?? _scrollController;
    }

    @override
    Widget build(BuildContext context) {
    return ListView.builder(
    controller: widget.child.controller,
    scrollDirection: widget.child.scrollDirection,
    itemCount: 2,
    itemBuilder: (context, index) {
    if (index == 0) {
    return Scrollable(
    physics: NeverScrollableScrollPhysics(),
    axisDirection: widget.child.getDirection(context),
    viewportBuilder: (context, offset) {
    return ShrinkWrappingViewport(
    axisDirection: widget.child.getDirection(context),
    offset: offset,
    slivers: widget.child.buildSlivers(context),
    );
    },
    );
    }
    return widget.footer;
    },
    );
    }

    编辑:这是一个简化的替代方法:
    @override
    Widget build(BuildContext context) {
    return Scrollable(
    controller: widget.child.controller,
    axisDirection: widget.child.getDirection(context),
    viewportBuilder: (context, offset) {
    return ShrinkWrappingViewport(
    axisDirection: widget.child.getDirection(context),
    offset: offset,
    slivers: widget.child.buildSlivers(context)
    ..add(SliverList(delegate: SliverChildListDelegate([widget.footer]))),
    );
    },
    );
    }

    以下是一些使用方法的示例:
    final _scrollController = ScrollController();

    // ListView
    ScrollableWithFooter(
    child: ListView.builder(
    controller: _scrollController,
    itemCount: 50,
    itemBuilder: (context, index) => Text('Item $index'),
    ),
    footer: Center(child: Text('Footer')),
    )

    // GridView
    ScrollableWithFooter(
    child: GridView.builder(
    controller: _scrollController,
    itemCount: 50,
    itemBuilder: (context, index) => Text('Item $index'),
    gridDelegate:
    SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
    ),
    footer: Center(child: Text('Footer')),
    )

    让我知道是否有人认为这不好并且有更好的方法。

    关于flutter - Flutter-如何制作一个自定义小部件,以将页脚添加到接收到的可滚动小部件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58486152/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com