Reputation: 338
I have a list in Page_2.dart
:
final List<Trans> transactions = [
Trans(false, 20),
];
that takes a custom class widget, Trans
that takes a Boolean and a double and displays them in a Row
, and I have button to add a new element to transactions
,
RaisedButton(
onPressed: () {
setState(
() {
transactions.add(
Trans(true, -50));
},
);
},
child: const Text("Add Transaction"),
),
and I want to have a button inside page_3.dart
that does the same thing which is adding a new adding a new Trans
to transactions
Upvotes: 1
Views: 1900
Reputation: 7100
Usually there are two methods of widget interaction: callbacks (when one widget provides a callback and other one call it back) or streams (when one widget provides a stream controller and other one uses those controller to send events to stream). Callbacks and events are processed by widget-initiator.
ValueSetter
parameter in Page3
widget and create it like:// in Page2
final page3 = Page3(callback: (trans) {
transactions.add(trans);
}
// in Page3
onPressed: () {
widget.callback(Trans(...)); // if Page3 us stateful
}
StreamController<Trans> state member in
Page2and pass it as parameter to
Page3`.// in Page2
@override
void initState() {
super.initState();
controller.stream.listen((trans) {
transactions.add(trans);
});
}
// in Page3
onPressed: () {
widget.controller.add(Trans(...));
}
Upvotes: 0
Reputation: 6029
All you need to do is pass the function 'add transaction' from 'Page 2' to 'Page 3'. You have to make sure that the function 'add transaction' accepts 'Trans' as a parameter and it also calls setState for Page 2. In Page 3 you have to pass your 'Trans(true, -50)' as the parameter to the 'add transaction' function that is received from 'Page 2'. The 'add transaction' function may be run in the onPressed method of RaisedButton on 'Page 3'. Please see the code below :
import 'package:flutter/material.dart';
import 'dart:math' as math;
final Color darkBlue = const Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
extension Ex on double {
double toPrecision(int n) => double.parse(toStringAsFixed(n));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text("Flutter Demo App"),
),
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
void _addTransaction(Trans transaction) {
setState(() {
transactions.add(transaction);
});
}
final List<Trans> transactions = [
const Trans(myBool: false, myDouble: 20),
const Trans(myBool: true, myDouble: -50),
const Trans(myBool: false, myDouble: 110),
const Trans(myBool: false, myDouble: 35.5),
];
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
height: MediaQuery.of(context).size.height * .7,
child: Scrollbar(
showTrackOnHover: true,
child: ListView.builder(
itemCount: transactions.length,
itemBuilder: (context, index) {
return ListTile(
title: transactions[index],
);
},
),
),
),
RaisedButton(
onPressed: () {
final rnd = math.Random();
_addTransaction(
Trans(
myBool: rnd.nextBool(),
myDouble: rnd.nextDouble().toPrecision(2) + rnd.nextInt(100),
),
);
},
child: const Text("Add Transaction"),
),
RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Page3(addTran: _addTransaction),
),
);
},
child: const Text("Page 3"),
),
],
);
}
}
class Trans extends StatelessWidget {
final myBool;
final myDouble;
const Trans({Key key, this.myBool, this.myDouble}) : super(key: key);
@override
Widget build(BuildContext context) {
return Row(
children: [
Text("Transaction: ${myBool.toString()} ${myDouble.toString()}")
],
);
}
}
class Page3 extends StatefulWidget {
final Function addTran;
const Page3({Key key, this.addTran}) : super(key: key);
@override
_Page3State createState() => _Page3State();
}
class _Page3State extends State<Page3> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Page 3"),
),
body: Center(
child: RaisedButton(
onPressed: () => widget.addTran(
const Trans(myBool: true, myDouble: 50),
),
child: const Text("Add Transaction"),
),
),
);
}
}
Note : even though in my example code above the widget 'Page 3' is in the same file. You may make a separate library for 'Page 3' as usual by importing material.dart.
Upvotes: 2