Home > Back-end >  How to re-build Page A when a button is pressed in Page B?
How to re-build Page A when a button is pressed in Page B?

Time:07-24

I'm working with IndexedStack in order not to rebuild each page while using BottomNavigationBar

// MAIN.DART
class LoggedHandle extends StatefulWidget {
  const LoggedHandle({Key? key}) : super(key: key);

  @override
  State<LoggedHandle> createState() => _LoggedHandleState();
}

class _LoggedHandleState extends State<LoggedHandle> {
  

 
  double height = AppBar().preferredSize.height;

  int _selectedPage = 1;



 
  

  @override
  void initState() {
    
    });



    super.initState();
  }

  @override
  void dispose() {

    _importo.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      
       
        

      bottomNavigationBar: BottomNavigationBar(
          
          currentIndex: _selectedPage,
          onTap: (int index) {
            setState(() {
              _selectedPage = index;
            });
          },
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.receipt),
              label: 'Schedina',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.account_circle),
              label: 'Account',
            ),
          ]),
      body: IndexedStack(
        index: _selectedPage,
        children:  [BetView(), HomeView(), UserView()],
      ),
    );
  }


}

// HOME.DART

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

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {

  


  @override
  void initState() {

    super.initState();
    
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox.expand(
      child: SingleChildScrollView(
        child: Column(
          children: [


            Padding(
              child: Text("rebuild this")
            ),
            

          ],
        ),
      ),
    );
  }
}

In BetView() I have a ElevatedButton and I would like to rebuild HomeView when it is pressed. Navigation to HomeView() won't rebuild it because of IndexedStack

// BETVIEW
class BetView extends StatefulWidget {
  const BetView({Key? key}) : super(key: key);

  @override
  State<BetView> createState() => _BetViewState();
}

class _BetViewState extends State<BetView> {


  late final TextEditingController _importo;
  

  @override
  void initState() {
   
      



    super.initState();
  }

  @override
  void dispose() {

    
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<BetBloc, BetState>(
      builder: (context, state) {
        if (state is BetLoaded) {
          double quotatotale = 1.0;


          for (BetEntry bet in state.bets) {
            print(bet);
            quotatotale = quotatotale * bet.quota;
          }
          return Column(
            children: [
              
              
                            
              
              Padding(
                padding: const EdgeInsets.all(10.0),
                child: Row(
                  children: [
                    ElevatedButton(
                      style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all(Colors.orange[500]),
                          shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                              RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(8.0),
                              )
                          )
                      ),
                      onPressed: (){
                        
                        // Rebuild HomeView()
                      },
                      child: const Padding(
                        padding: EdgeInsets.all(15),
                        child: Text("Elimina tutte",
                          style: TextStyle(
                              fontSize: 15,
                              color: Colors.white,
                          ),
                        ),
                      ),
                    ),
                    const Spacer(),
                    ElevatedButton(
                      style: ButtonStyle(
                          backgroundColor: MaterialStateProperty.all(Colors.green),
                          shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                              RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(8.0),
                              )
                          )
                      ),
                      onPressed: (){

                      },
                      child: const Padding(
                        padding: EdgeInsets.all(15),
                        child: Text("Conferma",
                          style: TextStyle(
                              fontSize: 15
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          );
        } else {
          return const Text("something wrong");
        }
      },
    );
  }
}

CodePudding user response:

Class A

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main1.dart';

void main() {
  runApp(MaterialApp(
    home: Modalbtn(),
  ));
}

class Modalbtn extends StatefulWidget {
  @override
  _ModalbtnState createState() => _ModalbtnState();
}

class _ModalbtnState extends State<Modalbtn> {
  String value = "0";
  // Pass this method to the child page.
  void _update(String newValue) {
    setState(() => value = newValue);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            IconButton(
              onPressed: () {
                showModalBottomSheet(
                    context: context,
                    builder: (BuildContext context) {
                      return Container(
                        height: 200,
                        child: Column(
                          children: [StatefulModalbtn(update: _update)],
                        ),
                      );
                    });
              },
              icon: Icon(Icons.add),
              iconSize: 20,
            ),
            Text(
              value,
              style: TextStyle(fontSize: 40),
            ),
          ],
        ),
      ),
    );
  }
}

Class B

import 'package:flutter/material.dart';

class StatefulModalbtn extends StatelessWidget {
  final ValueChanged<String> update;
  StatefulModalbtn({required this.update});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => update("100"), // Passing value to the parent widget.

      child: Text('Update (in child)'),
    );
  }
}

CodePudding user response:

You can use a callBack method to trigger homeView action, It would be better using state-management(riverpod/bloc) property, Passing data on constructor will also do the trick

Example of using callBack to update HomeView.

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

  @override
  State<HomeView> createState() => _HomeViewState();
}

class _HomeViewState extends State<HomeView> {
  int _selectedPage = 0;
  int count = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: BottomNavigationBar(
          currentIndex: _selectedPage,
          onTap: (int index) {
            setState(() {
              _selectedPage = index;
            });
          },
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.receipt),
              label: 'Schedina',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
          ]),
      body: IndexedStack(
        index: _selectedPage,
        children: [
          HomeWidget(data: count),
          BetView(
            callback: () {
              count  ;
            },
          ),
        ],
      ),
    );
  }
}

class HomeWidget extends StatefulWidget {
  const HomeWidget({
    Key? key,
    required this.data,
  }) : super(key: key);

  final int data;

  @override
  State<HomeWidget> createState() => _HomeWidgetState();
}

class _HomeWidgetState extends State<HomeWidget> {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.zero,
      child: Text(" ${widget.data} rebuild"),
    );
  }
}

class BetView extends StatefulWidget {
  const BetView({
    Key? key,
    required this.callback,
  }) : super(key: key);

  final VoidCallback callback;

  @override
  State<BetView> createState() => _BetViewState();
}

class _BetViewState extends State<BetView> {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: () {
            widget.callback();
          },
          child: Text("trigger the HomeView"),
        )
      ],
    );
  }
}

Using riverpod


void main(List<String> args) {
  runApp(
    const MaterialApp(
      home: ProviderScope(
        child: HomeView(),
      ),
    ),
  );
}
final myDataProvider = StateProvider<int>(
  (ref) => 0,
);

class HomeWidget extends ConsumerWidget {
  const HomeWidget({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, ref) {
    final providerData = ref.watch(myDataProvider.notifier);
    return Padding(
      padding: EdgeInsets.zero,
      child: Text(" ${providerData.state} rebuild"),
    );
  }
}

class BetView extends ConsumerWidget {
  const BetView({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context, ref) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: () {
            ref.read(myDataProvider.notifier).update((state) => state   1);
          },
          child: Text("trigger the HomeView"),
        )
      ],
    );
  }
}
  • Related