So I have been learning flutter in a while and I am stuck in this. Sorry if it is a noobish question. I am currently trying to build something like a Card Tab. The information and widget will be stored in a card.
Imagine something like Tinder, where they have multiple card stack and swipe left and right to navigate.
I plan to create that but I cannot seems to find a way to add/render a new card with a button.
It's like adding something to the list, Flutter will use a ListView builder where we add to the list. But there is no TabBarView builder. Is this something that is not possible to do? I try putting a list inside a tab but it's still wont be the same.
I created some basic skeleton here to help convey my meaning. So the card will be swipe left and right and there is a button in the appBar to add card. Lenght is 2 now and I wanted the button to render the 3rd card. Is this possible?
Thanks in advance!
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new CardStack(),
));
}
class CardStack extends StatefulWidget {
@override
_MainState createState() => new _MainState();
}
class _MainState extends State<CardStack> with SingleTickerProviderStateMixin {
TabController _cardController;
@override
void initState() {
super.initState();
_cardController = new TabController(vsync: this, length: 2);
}
@override
void dispose() {
_cardController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey[300],
appBar: new AppBar(
actions: <Widget>[
new IconButton(
icon: const Icon(Icons.add),
tooltip: 'Add Tabs',
onPressed: null,
),
],
title: new Text("Title Here"),
bottom: new PreferredSize(
preferredSize: const Size.fromHeight(20.0),
child: new Theme(
data: Theme.of(context).copyWith(accentColor: Colors.grey),
child: new Container(
height: 50.0,
alignment: Alignment.center,
child: new TabPageSelector(controller: _cardController),
),
)
)
),
body: new TabBarView(
controller: _cardController,
children: <Widget>[
new Center(
child: new Card(
child: new Container(
height: 450.0,
width: 300.0,
child: new IconButton(
icon: new Icon(Icons.favorite, size: 100.0),
tooltip: 'Favorited',
onPressed: null,
)
),
),
),
new Center(
child: new Card(
child: new Container(
height: 450.0,
width: 300.0,
child: new IconButton(
icon: new Icon(Icons.local_pizza, size: 50.0,),
tooltip: 'Pizza',
onPressed: null,
)
),
),
),
],
),
);
}
}
To make dynamic tab you can use a List and keep appending the list on every button click.
Trick: Clear List and redraw an empty widget and again draw the widgets as per your list.
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new CardStack(),
));
}
class DynamicTabContent {
IconData icon;
String tooTip;
DynamicTabContent.name(this.icon, this.tooTip);
}
class CardStack extends StatefulWidget {
@override
_MainState createState() => new _MainState();
}
class _MainState extends State<CardStack> with TickerProviderStateMixin {
List<DynamicTabContent> myList = new List();
TabController _cardController;
TabPageSelector _tabPageSelector;
@override
void initState() {
super.initState();
myList.add(new DynamicTabContent.name(Icons.favorite, "Favorited"));
myList.add(new DynamicTabContent.name(Icons.local_pizza, "local pizza"));
_cardController = new TabController(vsync: this, length: myList.length);
_tabPageSelector = new TabPageSelector(controller: _cardController);
}
@override
void dispose() {
_cardController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey[300],
appBar: new AppBar(
actions: <Widget>[
new Padding(
padding: const EdgeInsets.all(1.0),
child: new IconButton(
icon: const Icon(
Icons.add,
size: 30.0,
color: Colors.white,
),
tooltip: 'Add Tabs',
onPressed: () {
List<DynamicTabContent> tempList = new List();
myList.forEach((dynamicContent) {
tempList.add(dynamicContent);
});
setState(() {
myList.clear();
});
if (tempList.length % 2 == 0) {
myList.add(new DynamicTabContent.name(Icons.shopping_cart, "shopping cart"));
} else {
myList.add(new DynamicTabContent.name(Icons.camera, "camera"));
}
tempList.forEach((dynamicContent) {
myList.add(dynamicContent);
});
setState(() {
_cardController = new TabController(vsync: this, length: myList.length);
_tabPageSelector = new TabPageSelector(controller: _cardController);
});
},
),
),
],
title: new Text("Title Here"),
bottom: new PreferredSize(
preferredSize: const Size.fromHeight(10.0),
child: new Theme(
data: Theme.of(context).copyWith(accentColor: Colors.grey),
child: myList.isEmpty
? new Container(
height: 30.0,
)
: new Container(
height: 30.0,
alignment: Alignment.center,
child: _tabPageSelector,
),
))),
body: new TabBarView(
controller: _cardController,
children: myList.isEmpty
? <Widget>[]
: myList.map((dynamicContent) {
return new Card(
child: new Container(
height: 450.0,
width: 300.0,
child: new IconButton(
icon: new Icon(dynamicContent.icon, size: 100.0),
tooltip: dynamicContent.tooTip,
onPressed: null,
)),
);
}).toList(),
),
);
}
}
Hope this helps :)