Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create pageview overlapping effect?

I need to create an overlapping pageview collection, but because of draw/layout order of items the second page always shows up in front of first page. There a way to create a collection list that the first items overlapping the others?

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),
            ),
          ),
        ),
      );
    });
  }

I was expecting create a collection effect so the second page would come from behind the first one, but actually second pages always appears overlapping the first. I could use reverse in PageView.builder, but this collection needs to be a infinity list that loads more data when it reaches the end and with reverse the code will be alot trickier.

I'm achieving this:

wrong result

But what I want is the blue card behind the red one.

like image 765
Luís R. Jaeger Avatar asked Nov 07 '22 13:11

Luís R. Jaeger


1 Answers

So right now, to create your overlapping effect, you are offsetting the next-Page so that it overlaps the cur-Page, and as you mentioned, you discover that the next-Page visually over-laps instead of the desired under-lap.

Then, in additional to your offset, have you tried cropping off the overlapping portion of next-Page? This can simulate the effect of under-lapping.

Now, I tried replicating your sample, but I'm uncertain about your PreloadPageController (and maybe other details), so my sample might look glitchy. Additionally, I'm not wholly familiar with cropping widgets. But I bumped into this possible solution, all I did was wrap it with another 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),
              ),
            ),
          ),
        ),
      );
    });
  }

This additional ClipRect basically clips off your offset portion. Feel free to explore and modify as needed!

enter image description here

like image 127
TWL Avatar answered Nov 16 '22 17:11

TWL