Reputation: 1549
Let's say I have 2 cards and one is shown on screen at a time. I have a button that replaces the current card with other cards. Now assume that there is some data on card 1 and some data on card 2 and I don't want to destroy the data on each of them or I don't want to rebuild any of them again.
I tried using Stack Widget and overlapping one on top of others with a boolean on the top card. The value of this boolean is reversed by calling setstate
when the button is pressed. The issue is as soon as I press the button, the new card rebuilds all over again and then shown or initState
is called again, which I don't want. Any Solution?
EDIT: Sample Code:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var toggleFlag = false;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child: toggleFlag
? CustomWidget(color: Colors.blue)
: CustomWidget(color: Colors.red),
),
floatingActionButton: new FloatingActionButton(
onPressed: _toggleCard,
tooltip: 'Increment',
child: new Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _toggleCard() {
setState(() {
toggleFlag = !toggleFlag;
});
}
}
class CustomWidget extends StatefulWidget {
var color;
CustomWidget({this.color});
@override
State<StatefulWidget> createState() {
return new MyState();
}
}
class MyState extends State<CustomWidget> {
@override //I don't want this to be called again and again
Widget build(BuildContext context) {
return new Container(
height: 100.0,
width: 100.0,
color: widget.color,
);
}
}
Upvotes: 3
Views: 3207
Reputation: 11
just wrap that Widget inside a Visibility widget then set "maintainSate" to true
Visibility(
visible: toggleFlag,
maintainState: true,
child: const CustomWidget(),
)
Upvotes: 1
Reputation: 81
1-Solution: You have an array of widgets like this
final widgetList[widget1(), widget2()]
int currentIndex = 0;
IndexedStack (
index: currentIndex,
children: widgetList,
));
2-Solution:
With the Stack
widget
int currentIndex = 0;
Stack(
children: [
Offstage(
offstage: currentIndex != 0,
child: bodyList[0],
),
Offstage(
offstage: currentIndex != 1,
child: bodyList[1],
),
Offstage(
offstage: currentIndex != 2,
child: bodyList[2],
),
],
)
3-Solution: You need to add this to your stateful widget state
AutomaticKeepAliveClientMixin <Widgetname> like this
class _WidgetState extends State <Widgetname> with AutomaticKeepAliveClientMixin <Widgetname> {
@override
bool get wantKeepAlive => true;
}
Upvotes: 8
Reputation: 44056
Stateless widgets are always considered to be perishable. If you want to preserve state, use a StatefulWidget and a State subclass.
Upvotes: -4