1

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);
                    },
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
Sean
  • 13
  • 2

1 Answers1

0

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.

pixel
  • 577
  • 1
  • 1
  • 11
  • Hi Pixel, thank you for your suggestion. Unfortunately it doesn't work as desired. Whilst scrolling through the carousel the lastPageIndex is updated as you stated however, when leaving the page and returning the lastPageIndex variable is once again set to 0 on reloading the page. – Sean Jun 30 '23 at 22:23
  • Yeah, as the whole class is rebuild you need to use some singleton kind of thing, which will have the current index and will be used to give the value to the local lastPageIndex variable. you know about singleton right? – pixel Jul 03 '23 at 05:26