I am using a CustomScrollView and trying to add a like button in the SliverAppBar actions which by tapping on it, its shape changes. I am making the changes inside setState. But despite that the build method is being called, UI is not being updated.
TextButton(
onPressed: () {
bool added = courseStore.addToUserFavoriteCourses(widget.courseDetails);
added ?
setState(() {
iconData = Icons.favorite;
}) :
setState(() {
iconData = Icons.favorite_border;
});
},
child: Icon(
iconData,
size: 20,
color: Colors.white,
),
)
The above code is not saving state of iconData yet.
The state of like/unlike needs to be moved up into a parent widget scope. Its value can then be referenced below in children like TextButton.
When TextButton is rebuilt (changing from unlike to like & back) it can use the state that persists above it.
Notice below how iconData lives in the State widget. This widget designed to hold state for its children.
You can copy paste this code into a Flutter/Dart file to test:
import 'package:flutter/material.dart';
// ↓ Use this as your button
class StatefulButton extends StatefulWidget {
final double size;
final Color color;
StatefulButton({this.size = 20, this.color = Colors.black});
#override
_StatefulButtonState createState() => _StatefulButtonState();
}
class _StatefulButtonState extends State<StatefulButton> {
IconData iconData = Icons.favorite_border;
// ↑ Move your state up to here
#override
Widget build(BuildContext context) {
return Center(
child: TextButton(
child: Icon(
iconData,
size: widget.size,
color: widget.color,
),
onPressed: toggleLike,
),
);
}
void toggleLike() {
setState(() {
iconData = iconData == Icons.favorite ? Icons.favorite_border : Icons.favorite;
});
}
}
/// Just a container page for the example above
class TextButtonStatePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TextButtonState'),
),
body: StatefulButton()
);
}
}
Here's an example of using the StatefulButton above inside a CustomScrollView. The CustomScrollView code I stole straight from the Flutter docs website. The only edit I've made is to add the StatefulButton above into each sliver, to show it changing its state when clicked.
/// Flutter code sample for CustomScrollView
import 'package:flutter/material.dart';
import 'text_button_state.dart';
/// This is the stateful widget that the main application instantiates.
class CustomScrollviewPage extends StatefulWidget {
CustomScrollviewPage({Key key}) : super(key: key);
#override
_CustomScrollviewPageState createState() => _CustomScrollviewPageState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _CustomScrollviewPageState extends State<CustomScrollviewPage> {
List<int> top = [];
List<int> bottom = [0];
#override
Widget build(BuildContext context) {
const Key centerKey = ValueKey('bottom-sliver-list');
return Scaffold(
appBar: AppBar(
title: const Text('Press on the plus to add items above and below'),
leading: IconButton(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
top.add(-top.length - 1);
bottom.add(bottom.length);
});
},
),
),
body: CustomScrollView(
center: centerKey,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.blue[200 + top[index] % 4 * 100],
height: 100 + top[index] % 4 * 20.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Item: ${top[index]}'),
StatefulButton() // ← STATEFUL BUTTON HERE
],),
);
},
childCount: top.length,
),
),
SliverList(
key: centerKey,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.blue[200 + bottom[index] % 4 * 100],
height: 100 + bottom[index] % 4 * 20.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Item: ${bottom[index]}'),
StatefulButton() // ← STATEFUL BUTTON HERE
],
),
);
},
childCount: bottom.length,
),
),
],
),
);
}
}
Related
ive created a text and icon button, onpressing that icon
modal bottom sheet gets generated, in that
and ive created a separate dart file with text field and a submit button
when giving an input on text field and after clicking on submit button the given input string will be printed below
atlast i called the function in first dart file
but i want the text to be printed on the main scaffold page.
Below is the main code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:practice1/StatefulModalbtn.dart';
void main() {
runApp(Modalbtn());
}
class Modalbtn extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Modal Bottom Test'),
),
body: Column(
children: <Widget>[Mymodal()],
),
),
);
}
}
class Mymodal extends StatelessWidget {
const Mymodal({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'Press the icon to select the Tractor model',
style: TextStyle(fontSize: 15),
),
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
child: Column(
children: <Widget>[StatefulModalbtn()],
),
);
});
},
icon: Icon(Icons.add),
iconSize: 20,
)
],
),
);
}
}
and below code is for creating a text field and submit button
import 'package:flutter/material.dart';
class StatefulModalbtn extends StatefulWidget {
const StatefulModalbtn({Key? key}) : super(key: key);
#override
_StatefulModalbtnState createState() => _StatefulModalbtnState();
}
class _StatefulModalbtnState extends State<StatefulModalbtn> {
TextEditingController textController = TextEditingController();
String displayText = "";
#override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: textController,
maxLines: null,
),
ElevatedButton(
onPressed: () {
setState(() {
displayText = textController.text;
});
},
child: Text('Submit')),
Text(
displayText,
style: TextStyle(fontSize: 20),
),
],
);
}
}
and below is the output link
this is the output im achieving but i want the "Hello World" to be printed on top/main screen, right after the + add icon screen
How should i solve this ??
I just slightly edited your code
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),
),
],
),
),
);
}
}
and the child class is
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)'),
);
}
}
I have a unique .dart page
At the beginning I would like to have a counter on a common AppBar, a "button 1" which allows to increment my counter, and another button which directs me to another class.
On this class, I would like to review the counter without it being reset to zero, it must keep the starting increment.
With the "button 2" which is in this new class, I would like to be able to continue to increment this same counter.
I have 2 problems (beginner):
the AppBar shows me an error for the counter
I can't increment from "button 1" and "button 2" which are
in a different class from the counter. So I also have an error concerning these 2 buttons.
Can you help me by giving me a maximum of explanations please because I am new to Flutter.
Thanks in advance.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class TestClass1 extends StatefulWidget {
#override
TestClass1State createState() => TestClass1State();
}
class TestClass2 extends StatefulWidget {
#override
TestClass2State createState() => TestClass2State();
}
class Counter extends StatefulWidget {
const Counter({Key? key}) : super(key: key);
#override
CounterState createState() => CounterState();
}
class AppBarShared extends StatelessWidget implements PreferredSizeWidget {
final Color backgroundColor = Colors.red;
final Text title;
final AppBar appBar;
final List<Widget> widgets;
const AppBarShared({required this.title, required this.appBar, required this.widgets});
#override
Widget build(BuildContext context) {
return AppBar(
title: title,
backgroundColor: backgroundColor,
actions: <Widget>[Counter()],
);
}
#override
Size get preferredSize => new Size.fromHeight(appBar.preferredSize.height);
}
class CounterState extends State<Counter> {
int _counter = 1;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child:Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
)
);
}
}
class TestClass1State extends State<TestClass1> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarShared(
title: Text('title'),
appBar: AppBar(),
widgets: [this.widget],
),
//backgroundColor: Color(0xffe80fd3),
body: Container (
child: Stack(
children: [
IconButton (
iconSize: 40,
onPressed: _incrementCounter,
icon:Icon(Icons.arrow_upward, color:Colors.amber)
),
button1(),
],
),
),
);
}
Container button1() {
return Container(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton (
iconSize: 40,
onPressed: () => Navigator.pushReplacement(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => TestClass2(),
transitionDuration: Duration.zero,
),
),
icon:Icon(Icons.arrow_upward, color:Colors.amber)
)
],
),
);
}
}
class TestClass2State extends State<TestClass2> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarShared(
title: Text('title 2'),
appBar: AppBar(),
widgets: [this.widget],
),
//backgroundColor: Color(0xffe80fd3),
body: Container(
child: Stack(
children: [
IconButton (
iconSize: 40,
onPressed: _incrementCounter,
icon:Icon(Icons.arrow_upward, color:Colors.amber)
),
button2(),
],
),
),
);
}
Container button2() {
return Container(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
IconButton(
iconSize: 40,
onPressed: () => Navigator.pushReplacement(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => TestClass1(),
transitionDuration: Duration.zero,
),
),
icon: Icon(Icons.arrow_upward, color: Colors.amber)
)
],
),
);
}
}
I have a short ListView of a maximum of 10 items. Each list item will contain a DropDownButton which will hold around 1K DropDownMenuItems for selections.
In native Android, I was able to implement one that performed very smoothly, but with Flutter it takes a while to build the ListView which causes the UI to freeze.
In my case, I will need to rebuild the ListView upon every change in one of its items, so It will be a major issue.
Is there a way to make the ListView build faster, or at least be able to display a ProgressBar till it builds?
N.B: Using --profile configuration to simulate a release version improves the performance a lot, but still there is a sensed freeze.
Here's my sample code which you can directly copy/paste if you want to test it yourself.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool showList = false;
final List<DropdownMenuItem<int>> selections = List.generate(
1000,
(index) => DropdownMenuItem<int>(
value: index,
child: Text("$index"),
),
);
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
width: double.infinity,
child: Column(
children: [
ElevatedButton(
child: Text("toggle list visibility"),
onPressed: () {
setState(() {
showList = !showList;
});
},
),
Expanded(
child: showList
? ListView.builder(
cacheExtent: 2000,
itemCount: 10,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Container(
height: 200,
color: Colors.green,
child: Column(
children: [
Text("List Item: $index"),
DropdownButton<int>(
onChanged: (i) {},
value: 1,
items: selections,
),
],
),
),
),
);
})
: Text("List Not Built"),
),
],
),
),
),
);
}
}
Load dropdown when clicking the button.
Add this widget on your main List View
InkWell(
onTap: () {
showDialog(
context: context,
builder: (_) {
return VendorListAlert(selectVendor: selectVendorTap);
});
},
child: // create a widget, looks like your drop down
),
Handle tap event
void selectVendorTap(pass your model){
// logic
}
Sample for custom Alert
No need to create a mutable widget, the immutable widget is better.
class VendorListAlert extends StatefulWidget {
final Function selectVendor;
const VendorListAlert({Key key, this.selectVendor}) : super(key: key);
#override
_VendorListAlertState createState() => _VendorListAlertState();
}
class _VendorListAlertState extends State<VendorListAlert> {
List<UserModel> _searchVendor = [];
#override
void initState() {
super.initState();
_searchVendor = List.from(ypModel);
}
#override
Widget build(BuildContext context) {
return AlertDialog(
content: Container(
width: width,
child: ListView.builder(
shrinkWrap: true,
itemCount: _searchVendor.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: InkWell(
onTap: () {
widget.selectVendor(_searchVendor[index]);
Navigator.pop(context);
},
child:
),
);
},
),
),
);
}
}
is there anyone who can help me ?
I am currently on a project where i want to visualize pathfinding-algorithms by using flutter (i want to use it as app later on).
My Problem:
I have a gridPaper and it's perfectly formatted for my needs... but how can i make the single elements in it accessible by clicking on them ?
I want to create a 'wall' between the start- and endnode to make it harder for the pathfinding-algorithm. (if that makes sense)
But at first i need to create a start- end endnode as well.
Here is what i have so far:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final appTitle = 'Path Finder';
final Color gridColor = Colors.lightBlue[100];
#override
Widget build(BuildContext context) {
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(title)),
body: GridPaper(
child: Container(),
color: Colors.lightBlue[100],
interval: 20,
divisions: 1,
subdivisions: 1,
),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Startpunkt'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Ziel'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
);
}
}
LG Robsen
Since your GridPaper is defined with intervals of 20, it will be quite easy to use the localPosition of the details of an onTapDown callback provided by a GestureDetector on the whole GridPaper:
Full source code
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final appTitle = 'Path Finder';
final Color gridColor = Colors.lightBlue[100];
#override
Widget build(BuildContext context) {
return MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}
class MyHomePage extends HookWidget {
final double cellSize = 20.0;
final String title;
MyHomePage({
Key key,
this.title,
}) : super(key: key);
#override
Widget build(BuildContext context) {
final _activated = useState<List<Offset>>([]);
void _toggle(Offset offset) {
if (!_activated.value.remove(offset)) _activated.value.add(offset);
_activated.value = [..._activated.value];
}
return Scaffold(
appBar: AppBar(title: Text(title)),
body: GestureDetector(
onTapDown: (details) => _toggle(details.localPosition ~/ cellSize),
child: GridPaper(
child: Stack(
children: [
Container(color: Colors.white),
..._activated.value.map((offset) {
print('OFFSET: $offset');
return Positioned(
left: offset.dx * cellSize,
top: offset.dy * cellSize,
width: cellSize,
height: cellSize,
child: ColoredBox(color: Colors.green.shade200),
);
}).toList(),
],
),
color: Colors.lightBlue[100],
interval: cellSize,
divisions: 1,
subdivisions: 1,
),
),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can scroll
// through the options in the drawer if there isn't enough vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Startpunkt'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
ListTile(
title: Text('Ziel'),
onTap: () {
// Update the state of the app
// ...
// Then close the drawer
Navigator.pop(context);
},
),
],
),
),
);
}
}
In the code below, I have a method myMenu on a card. How do I navigate to another page when the card is tapped? There are going to be several of these cards which will link to its own page content. Each time I add a function to for an example it gives an error. How do I do it properly?
import 'package:flutter/material.dart';
import 'package:tarjous_app/gridview_demo.dart';
void main(List<String> args) {
runApp(
new MaterialApp(home: TarjousAle(), debugShowCheckedModeBanner: false));
}
class TarjousAle extends StatefulWidget {
#override
_TarjousAleState createState() => _TarjousAleState();
}
class _TarjousAleState extends State<TarjousAle> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("Study Plan"),
backgroundColor: Colors.amber,
),
body: Container(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
MyMenu(
title: "Records",
icon: Icons.account_balance_wallet,
shape: Colors.brown,
),
MyMenu(
title: "Academy",
icon: Icons.account_balance,
shape: Colors.grey,
),
],
),
),
);
}
}
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape});
final String title;
final IconData icon;
final MaterialColor shape;
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => GridViewDemo()),
),
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
In the inkwell widget, I add a function that works for all the cards. But what I really want it for each card to navigate to its own page. E.g Records should navigate to its own records page, the same thing for Academy to academy page
You could receive the page in the constructor and then go to that page, like this:
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape, this.page});
final Widget page;
...
}
Then, in onTap:
onTap: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => page),
)
So now you can do this:
MyMenu(
...
page: GridViewDemo1(),
),
MyMenu(
...
page: GridViewDemo2(),
)
Note that to navigate to some page, your context must contain a Navigator instance of parent. So if you try to navigate directly from MaterialApp, you might run into issues. I will not belabour the point here since it was explained very well in this thread, but it is something to keep in mind in case you happen to run into it.
Edited to address comments:
I'd do something like this for your case. Named routes make it easy to specify which route you'd like the card to take you to, which you kind of need to do if you want the same widget to take you to different routes.
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(
new MaterialApp(
home: TarjousAle(),
debugShowCheckedModeBanner: false,
routes: {
GridViewDemo.route: (context) => GridViewDemo(),
AnotherDemo.route: (context) => AnotherDemo(),
},
),
);
}
class TarjousAle extends StatefulWidget {
#override
_TarjousAleState createState() => _TarjousAleState();
}
class _TarjousAleState extends State<TarjousAle> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("Study Plan"),
backgroundColor: Colors.amber,
),
body: Container(
child: GridView.count(
crossAxisCount: 3,
children: <Widget>[
MyMenu(
title: "Records",
icon: Icons.account_balance_wallet,
shape: Colors.brown,
route: GridViewDemo.route
),
MyMenu(
title: "Academy",
icon: Icons.account_balance,
shape: Colors.grey,
route: AnotherDemo.route
),
],
),
),
);
}
}
class MyMenu extends StatelessWidget {
MyMenu({this.title, this.icon, this.shape, this.route});
final String title;
final IconData icon;
final MaterialColor shape;
final String route;
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: () => Navigator.pushNamed(context, route),
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
class GridViewDemo extends StatelessWidget {
static String route = '/demo';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.brown,
appBar: AppBar(title: Text('Grid view demo')),
body: Center(
child: Text('Grid view demo'),
),
);
}
}
class AnotherDemo extends StatelessWidget {
static String route = '/another';
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(title: Text('Another demo')),
body: Center(
child: Text('Another demo'),
),
);
}
}
You can read more about the basics of navigation in official docs, and also another docs page if you fancy the named routes.
Wrap the card with GestureDetector and you can use opnTap property.
for more details Official Documentation
Try wrapping your Card in a GestureDetector like below:
GestureDetector (
child: Card(),
onTap: () {},
),
wrap the card with InkWell widget and define your navigator.push in the onTap method.
class CardWidget extends StatelessWidget {
final Function onTapCard;
const CardWidget({Key key, #required this.onTapCard}) : super(key: key);
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(9.0),
child: InkWell(
onTap: onTapCard,
splashColor: Colors.amberAccent,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
icon,
size: 80.0,
color: shape,
),
Text(title, style: new TextStyle(fontSize: 18.0))
],
),
),
),
);
}
}
then we have our list here
class CardList extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
CardWidget(
onTapCard: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => YourSecondPage()),
),
),
CardWidget(
onTapCard: Navigator.push(
context,
MaterialPageRoute(builder: (context) => YourThirdPage()),
),
),
],
);
}
}