flutterdartparallax

Parallax effect with page builder in Flutter


I have a PageView.builder and each page has an image in the background. I want to add a parallax effect when changing pages, and I achieved it by giving an Offset in the image Alignment property. The problem is that when the page is about to end it starts to show the background, I suppose it's because due to the given Offset the image ended, so it starts to show the background. What can I do to solve this?

This is my PageView.builder

body: PageView.builder(
                controller: _controller,
                itemCount: _philosophers.length,
                onPageChanged: _onPageChange,
                itemBuilder: (context, index) {
                  final philosopher = _philosophers[index];
                  return Container(
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage(philosopher.image),
                        fit: BoxFit.cover,
                        alignment: Alignment((dx - index) * 1.8, 0),
                      ),
                    ),

This is the PageController

  @override
  void initState() {
    super.initState();
    _controller = PageController();
    _controller.addListener(() {
      setState(() {
        dx = _controller.page ?? 0.0;
      });
    });
  }

Current result

Parallax effect


Solution

  • You can use clamp for horizontal alignment to fix this issue, here is the modified code:

    body: PageView.builder(
      controller: _controller,
      itemCount: _philosophers.length,
      onPageChanged: _onPageChange,
      itemBuilder: (context, index) {
        final philosopher = _philosophers[index];
        final alignmentX = ((dx - index) * 1.8).clamp(-1.0, 1.0);
    
        return Container(
          decoration: BoxDecoration(
            image: DecorationImage(
              image: AssetImage(philosopher.image),
              fit: BoxFit.cover,
              alignment: Alignment(alignmentX, 0),
            ),
          ),
        );
      },
    ),