如何创建综合浏览量重叠效果?

时间:2019-09-22 15:48:07

标签: flutter dart flutter-layout

我需要创建一个重叠的综合浏览量集合,但是由于项目的绘制/布局顺序,第二页始终显示在第一页的前面。有没有一种创建收藏夹列表的方式,使第一项与其他项重叠?

PAGE BUILDER ->

 Widget buildList(PreloadPageController pageController, List data,
      double currentPosition) {
    return AspectRatio(
      aspectRatio: 12.0 / 15.0,
      child: PreloadPageView.builder(
        itemCount: data.length,
        controller: pageController,
        preloadPagesCount: 2,
        itemBuilder: (context, index) {
          return CardWidget(
              page: index,
              currentPage: currentPosition,
          );
        },
      ),
    );
  }


CARD WIDGET ->
Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, contraints) {
      final double padding = 20.0;

      var delta = currentPage - page;
      var start = padding * delta.abs() * 10;

      var top = padding + padding * max(-delta, 0.0);
      var bottom = padding + padding * max(-delta, 0.0);

      //print(start);
      return Transform.translate(
        offset: Offset(-start, 0),
        child: Container(
          padding: EdgeInsets.only(top: top, bottom: bottom),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(16.0),
            child: Container(
              color: _randomColor(page),
            ),
          ),
        ),
      );
    });
  }

我期望创建一个收集效果,因此第二页将位于第一页的后面,但是实际上第二页总是与第一页重叠。 我可以在PageView.builder中使用reverse,但是此集合必须是一个无穷大列表,当它到达末尾时将加载更多数据,并且使用reverse时,代码将更加棘手。

我正在实现这一目标:

wrong result

但是我想要的是红色卡片后面的蓝色卡片。

2 个答案:

答案 0 :(得分:1)

现在,要创建重叠效果,您要偏移 next -Page,使其与 cur -Page重叠,然后您发现了, 下一个页面在视觉上重叠,而不是所需的重叠

然后,除了偏移量之外,您是否尝试裁剪掉下一个-页面的重叠部分?这可以模拟重叠的效果。

现在,我尝试复制您的样本,但不确定您的PreloadPageController(也许还有其他详细信息),因此我的样本可能看起来有些毛病。此外,我对裁剪小部件并不完全熟悉。但是我碰到了这个可能的解决方案,我所做的就是用另一个ClipRect包装它:

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints) {
      final double padding = 20.0;

      var delta = widget.currentPage - widget.myPage;
      var start = padding * delta.abs() * 10;

      var top = padding + padding * max(-delta, 0.0);
      var bottom = padding + padding * max(-delta, 0.0);

      return ClipRect(
        child: Transform.translate(
          offset: Offset(-start, 0),
          child: Container(
            padding: EdgeInsets.only(top: top, bottom: bottom),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(16.0),
              child: Container(
                color: redOrBlue(widget.myPage),
              ),
            ),
          ),
        ),
      );
    });
  }

这个额外的ClipRect基本上会剪掉您的偏移部分。随时根据需要进行探索和修改!

enter image description here

答案 1 :(得分:0)

有一个Overlay小部件,但它可能会引起更多的麻烦,尤其是在规模方面。您可以将页面包装在ClipRect中,但是只有列表末尾的小部件才需要它。因此,在构建器函数中,设置一个布尔值:

clipNeeded = (controller.page + 0.5) <= index;

然后在新的ClipRect小部件中:

clipper: clipNeeded ? CustomRect() : null,

然后,您需要创建该CustomRect类,并扩展CustomClipper<Rect>

所需的确切数学信息取决于实现方式,但是在此从左到右滚动的示例中,它将类似于

class CustomRect extends CustomClipper<Rect>{

  @override
  Rect getClip(Size size) {
    double leftLine = /* some calculation */;
    return Rect.fromLTRB(leftLine, 0.0, size.width, size.height);
  }
  @override
  bool shouldReclip(CustomRect oldClipper) {
    return true;
  }
}