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"),
)
],
);
}
}