Keep Carousel position between pages

245 Views Asked by At

I have built a Carousel with weather images and text which works fine. However, when I navigate to another page and then navigate back to my page with the carousel the carousel has reverted back to the first position. How can I keep the last position selected when returning to the carousel page? Thank you for any help.

Here's my code:

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPage();
}

class _TestPage extends State<TestPage> {
//This @Overide initState allows for calling functions when the page is built
  @override
  initState() {
    super.initState();
  }

  final double weatherIconWidth = 80;
  final double weatherIconHeight = 90;
  final double weatherFontSize = 12;

  //Create weather images list for Carousel
  final weatherImages = [
    'assets/images/weather/sun.png',
    'assets/images/weather/sun_cloud.png',
    'assets/images/weather/cloud.png',
    'assets/images/weather/light_rain.png',
    'assets/images/weather/heavey_rain.png',
    'assets/images/weather/storm.png',
    'assets/images/weather/snow.png',
  ];
  var weatherList = [
    'Sunny',
    'Sun & Cloud',
    'Cloudy',
    'Showers',
    'Rain',
    'Storms',
    'Ice & Snow'
  ];

//Weather Carousel builder
  Widget buildWeatherImage(String weatherImage, int index) => Container(
        margin: const EdgeInsets.symmetric(horizontal: 5),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Image.asset(weatherImage, fit: BoxFit.cover),
            Text(
              weatherList[index],
              style: TextStyle(
                  fontSize: weatherFontSize, fontWeight: FontWeight.bold),
            ),
          ],
        ),
      );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: (const Text('Carousel')),
        //turn off the appbar left side back arrow
        automaticallyImplyLeading: false,
        //add in back arrow button on right
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.chevron_left),
            onPressed: () {
              Navigator.pop(context);
            },
          )
        ],
      ),
      body:
          //Weather condition information
          Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          // Weather image carousel here:
          Container(
            padding: const EdgeInsets.only(left: 10),
            child: Column(
              children: [
                const Text(
                  'Weather',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(
                  width: weatherIconWidth,
                  child: CarouselSlider.builder(
                    options: CarouselOptions(
                      height: weatherIconHeight,
                      initialPage: 0,
                      viewportFraction: 1,
                      //enlargeCenterPage: true,
                      //enlargeFactor: 0.3
                    ),
                    itemCount: weatherImages.length,
                    itemBuilder: (context, index, realIndex) {
                      final weatherImage = weatherImages[index];
                      return buildWeatherImage(weatherImage, index);
                    },
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
1

There are 1 best solutions below

2
pixel On

Simple, it's happing cause you have given the initialPage as 0. you need to save the current page index when you are navigating to another screen in a variable and give it to the initialPage.

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPage();
}

class _TestPage extends State<TestPage> {
//This @Overide initState allows for calling functions when the page is built
  @override
  initState() {
    super.initState();
  }

  final double weatherIconWidth = 80;
  final double weatherIconHeight = 90;
  final double weatherFontSize = 12;

  //Create weather images list for Carousel
  final weatherImages = [
    'assets/images/weather/sun.png',
    'assets/images/weather/sun_cloud.png',
    'assets/images/weather/cloud.png',
    'assets/images/weather/light_rain.png',
    'assets/images/weather/heavey_rain.png',
    'assets/images/weather/storm.png',
    'assets/images/weather/snow.png',
  ];
  var weatherList = [
    'Sunny',
    'Sun & Cloud',
    'Cloudy',
    'Showers',
    'Rain',
    'Storms',
    'Ice & Snow'
  ];

  int lastPageIndex = 0;

//Weather Carousel builder
  Widget buildWeatherImage(String weatherImage, int index) => Container(
        margin: const EdgeInsets.symmetric(horizontal: 5),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Image.asset(weatherImage, fit: BoxFit.cover),
            Text(
              weatherList[index],
              style: TextStyle(
                  fontSize: weatherFontSize, fontWeight: FontWeight.bold),
            ),
          ],
        ),
      );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          // appbar
          ),
      body:
          //Weather condition information
          Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          // Weather image carousel here:
          Container(
            padding: const EdgeInsets.only(left: 10),
            child: Column(
              children: [
                const Text(
                  'Weather',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(
                  width: weatherIconWidth,
                  child: CarouselSlider.builder(
                    options: CarouselOptions(
                      height: weatherIconHeight,
                      initialPage: lastPageIndex,
                      onPageChanged: (index, reason) => lastPageIndex = index,

                      viewportFraction: 1,
                    ),
                    itemCount: weatherImages.length,
                    itemBuilder: (context, index, realIndex) {
                      final weatherImage = weatherImages[index];
                      return buildWeatherImage(weatherImage, index);
                    },
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

with this line onPageChanged: (index, reason) => lastPageIndex = index you will get the current index of carousel.