Home > Software engineering >  How to navigate pageview pages with overwrite back button in AppBar?
How to navigate pageview pages with overwrite back button in AppBar?

Time:09-14

I have a pageview view and it works with sliding. But how do I integrate this back button as leading: Icon(backbutton), when navigating between forms in the pageview? Thanks

screen1.dart

import 'package:app/src/features/examples/components/body.dart';

class OnboardingExampleFlowPage extends StatelessWidget {
  static String routeName = "/onboarding_example_flow";

  const OnboardingExampleFlowPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        elevation: 1,
        backgroundColor: AppColors.monochromeWhite,
        title: Text(context.l10n.buttonBack),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {},
        ),
      ),
      body: const Body(),
    );
  }
}

Body has pageview:

body.dart


class _BodyState extends State<Body> {
  int currentPage = 0;
  final PageController controller = PageController();
  @override
  void dispose() {
    super.dispose();
    controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final List<Widget> formPages = <Widget>[
      ExampleContent01(controller: controller),
      ExampleContent02(controller: controller),
      ExampleContent03(controller: controller),
      ExampleContent04(controller: controller),
    ];
    return SafeArea(
      child: SizedBox(
        child: Column(
          children: [
            const SizedBox(height: 6),
            AppStepper(
              currentPage: currentPage,
              length: formPages.length,
              noSkip: true,
            ),
            Expanded(
              child: Padding(
                padding: EdgeInsets.symmetric(
                  horizontal: getProportionateScreenWidth(20),
                ),
                child: PageView(
                  controller: controller,
                  onPageChanged: (value) => setState(() => currentPage = value),
                  children: formPages,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

These forms: There are contents in ExampleScreens, but I did not add their code because there are AppBar and Pageview in the code I added.

here is view: enter image description here want to be able to go back inside pageview.

Thanks a lot!

CodePudding user response:

Just move the controller up, to the parent widget, so it's possible to navigate the pages with it.

Check out the enter image description here

The code is going to be like the following:

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const OnboardingExampleFlowPage(),
      scrollBehavior: MyCustomScrollBehavior(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class OnboardingExampleFlowPage extends StatefulWidget {
  static String routeName = "/onboarding_example_flow";

  const OnboardingExampleFlowPage({Key? key}) : super(key: key);

  @override
  State<OnboardingExampleFlowPage> createState() =>
      _OnboardingExampleFlowPageState();
}

class _OnboardingExampleFlowPageState extends State<OnboardingExampleFlowPage> {
  final PageController controller = PageController();

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        elevation: 1,
        title: const Text('Back'),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {
            controller.previousPage(
              duration: const Duration(milliseconds: 250),
              curve: Curves.easeOut,
            );
          },
        ),
      ),
      body: Body(controller: controller),
    );
  }
}

class Body extends StatefulWidget {
  const Body({super.key, required this.controller});

  final PageController controller;

  @override
  State<Body> createState() => _BodyState();
}

class _BodyState extends State<Body> {
  int currentPage = 0;

  @override
  Widget build(BuildContext context) {
    const List<Widget> formPages = [
      Center(child: Text('Page 1')),
      Center(child: Text('Page 2')),
      Center(child: Text('Page 3')),
      Center(child: Text('Page 4')),
    ];
    return SafeArea(
      child: SizedBox(
        child: Column(
          children: [
            const SizedBox(height: 6),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20),
                child: PageView(
                  controller: widget.controller,
                  onPageChanged: (value) => setState(() => currentPage = value),
                  children: formPages,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// Enables scrolling with mouse dragging
class MyCustomScrollBehavior extends MaterialScrollBehavior {
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}

CodePudding user response:

Dont have body widget in separate file

Put it in the _OnboardingExampleFlowPageState instead.

And it is the _OnboardingExampleFlowPageState that should have controller and currentIndex variables.

So on leading button click you'll do something like this:

  onPressed: () {
                        if (currentPage > 0) {
                          controller.previousPage(
                            duration: const Duration(milliseconds: 200),
                            curve: Curves.easeOut,
                          );
                          setState(() {
                            currentPage--;
                          });
                        }
                      },
  • Related