How do I ensure that the user continues where they left off in the application in Flutter?

62 Views Asked by At

I made a book reading page with the Page_Flip widget, but when the user leaves the application and re-enters the book page, I want it to continue from where it left off. How can I keep the user's information? I tried features such as Onflip, currentPage, but the widget I use does not support them.

// HomeScreen.dart

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

final _controller = GlobalKey<PageFlipWidgetState>();

class AChristmasCarol extends StatefulWidget {
  const AChristmasCarol({super.key});

  @override
  State<AChristmasCarol> createState() => _AChristmasCarolState();
}

class _AChristmasCarolState extends State<AChristmasCarol> {
  final List<String> imagePaths = [
    'assets/books/A Christmas Carol/page 1.png',
    'assets/books/A Christmas Carol/page 2.png',
    'assets/books/A Christmas Carol/page 3.png',
    'assets/books/A Christmas Carol/page 4.png',
    'assets/books/A Christmas Carol/page 5.png',
    'assets/books/A Christmas Carol/page 6.png',
    'assets/books/A Christmas Carol/page 7.png',
    'assets/books/A Christmas Carol/page 8.png',
    'assets/books/A Christmas Carol/page 9.png',
    'assets/books/A Christmas Carol/page 10.png',
    // Add more pages as needed
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageFlipWidget(
        key: _controller,
        backgroundColor: Colors.white,
        lastPage: Container(
            color: Colors.white, child: const Center(child: Text('The End!'))),
        children: [
          for (var imagePath in imagePaths) _buildDemoPage(imagePath),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.looks_one_outlined),
        onPressed: () {
          _controller.currentState?.goToPage(1);
        },
      ),
    );
  }

  Widget _buildDemoPage(String imagePath) {
    return Scaffold(
      body: Image.asset(
        imagePath,
        fit: BoxFit.cover,
      ),
    );
  }
}
1

There are 1 best solutions below

0
Suraj Kumar On BEST ANSWER

You can utilise the sharedPreference to store and retrieve the LastLeftOverPageIndex. You can download the library from here

you have to store the current page number when user exit the application using or navigate to different screen using deactivate method and restore the store the previously stored index when user enter the screen using initState Method;

I have modified your code

class BookDemo extends StatefulWidget {
  const BookDemo({super.key});

  @override
  State<BookDemo> createState() => _BookDemoState();
}

class _BookDemoState extends State<BookDemo> {
  final _controller = GlobalKey<PageFlipWidgetState>();

  // sharedPreferences to store lastLeftOverPage Index
  final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  // last left over page index
  int lastLeftOverPageIndex = 0;

  // SharedPreference key to retrieve the  value of lastLeftOverPageIndex
  String lastLeftOverPageNoPrefKey = "_lastLeftOverPageNoPrefKey";

  final List<String> imagesPath = [
    "assets/images/image_1.png",
    "assets/images/image_2.png",
    "assets/images/image_3.png"
  ];

  Widget _buildDemoPage(String imagePath) {
    return Scaffold(
      body: Image.asset(
        imagePath,
        fit: BoxFit.cover,
      ),
    );
  }

  @override
  void initState() {
    // restore the previous lastLeftOverPageIndex;
    _restoreLeftOverPage();
    super.initState();
  }

  Future<void> _restoreLeftOverPage() async {
    SharedPreferences pref = await _prefs;
    lastLeftOverPageIndex =
        pref.getInt(lastLeftOverPageNoPrefKey)?.toInt() ?? 0;
    // navigate the book page index to lastLeftOverPageIndex
    _controller.currentState?.goToPage(lastLeftOverPageIndex);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageFlipWidget(
        key: _controller,
        backgroundColor: Colors.white,
        initialIndex: lastLeftOverPageIndex,
        lastPage: Container(
            color: Colors.white, child: const Center(child: Text('The End!'))),
        children: [
          for (var imagePath in imagesPath) _buildDemoPage(imagePath),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.looks_one_outlined),
        onPressed: () {
          _controller.currentState?.goToPage(1);
        },
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void deactivate() {
// before disposing the widget save the current page no
    var currentPageNo = _controller.currentState?.pageNumber.toInt() ?? 0;
    saveLastLeftOverPaqePref(currentPageNo);
  }

  Future<void> saveLastLeftOverPaqePref(var lastPage) async {
    SharedPreferences pref = await _prefs;
    pref.setInt(lastLeftOverPageNoPrefKey, lastPage);
  }
}

If my answer worked for you don't forget to mark it.