Reputation: 47
Background
I'm building an app to help primary school teachers. This app allows the user to select letters from the alphabet and when they continue to the next screen the letters they select should show as flippable cards. One side has the letter, the other side has an image. These cards should take up the whole screen and the user can swipe to the next card.
The Issue
When the user selects multiple letters they are entered into a list. When they tap the button to move to the next screen (with the flippable cards) they are served the following error message:
"type '_InternalLinkedHashMap>' is not a subtype of type 'List'"
The Code
Below is the code for the letter selection screen:
import 'package:flutter/material.dart';
import 'package:project_teacher/pages/allcards.dart';
class ChooseLetters extends StatefulWidget {
@override
_ChooseLettersState createState() => _ChooseLettersState();
}
class _ChooseLettersState extends State<ChooseLetters> {
List<String> alphabets = ['a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z'],
selection = [];
List alphabetCards = [AlphabetCard(),BAlphabetCard(),CAlphabetCard(),DAlphabetCard(),EAlphabetCard(),FAlphabetCard(),
GAlphabetCard(),HAlphabetCard(),IAlphabetCard(),JAlphabetCard(),KAlphabetCard(),LAlphabetCard(),MAlphabetCard(),NAlphabetCard(),OAlphabetCard(),PAlphabetCard(),
QAlphabetCard(),RAlphabetCard(),SAlphabetCard(),TAlphabetCard(),UAlphabetCard(),VAlphabetCard(),WAlphabetCard(),XAlphabetCard(),YAlphabetCard(),ZAlphabetCard()],
selectionCards = [];
@override
void initState(){
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [Colors.blueGrey[300], Colors.blueGrey])
),
padding:EdgeInsets.all(15),
alignment: Alignment.center,
child:GridView.builder(
gridDelegate:SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount:4,
mainAxisSpacing: 10, crossAxisSpacing: 10,
),
itemCount:alphabetCards.length,
itemBuilder:(con,ind){
return InkWell(
onTap:(){
setState((){
if(selectionCards.contains(alphabetCards[ind]))
selectionCards.remove(alphabetCards[ind]);
else
selectionCards.add(alphabetCards[ind]);
});
print(selectionCards);
},
child: Container(
padding:EdgeInsets.all(10),
alignment:Alignment.center,
decoration:BoxDecoration(
color:selectionCards.contains(alphabetCards[ind]) ? Colors.orange : Colors.white,
borderRadius:BorderRadius.circular(0)
),
child:Text(alphabets[ind],
style: TextStyle(
color:Colors.black,
fontSize: 50
)
)
),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/tabbedcards', arguments: {
'selectionOfCards': selectionCards
});
},
backgroundColor: Colors.red,
),
);
}
}
And this is the code for the flippable card screen:
import 'package:flutter/material.dart';
class TabbedCards extends StatefulWidget {
@override
_TabbedCardsState createState() => _TabbedCardsState();
}
class _TabbedCardsState extends State<TabbedCards> {
List selectionOfCards;
@override
Widget build(BuildContext context) {
selectionOfCards = ModalRoute.of(context).settings.arguments;
return MaterialApp(
home: DefaultTabController(
length: selectionOfCards.length,
child: Scaffold(
body: TabBarView(
children: selectionOfCards
),
),
),
);
}
}
Thank you for reading and any help you may give.
Upvotes: 0
Views: 169
Reputation: 27197
You have to make few change to make it work.
List<String> alphabets = ['a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z'],
selection = [];
here, you are trying to crate list of string and adding selection = [] ?
List<String> alphabets = ['a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p',
'q','r','s','t','u','v','w','x','y','z'];
Now Provide type to List of Widgets.
List<Widget> alphabetCards = [
AlphabetCard(),
BAlphabetCard(),
CAlphabetCard(),
DAlphabetCard(),
EAlphabetCard(),
....
];
List<Widget> selectionCards = <Widget>[];
Now change your tab view as follow.
class _TabbedCardsState extends State<TabbedCards> {
Map<String, List> selectionOfCards;
List<Widget> data;
@override
Widget build(BuildContext context) {
selectionOfCards = ModalRoute.of(context).settings.arguments;
data = selectionOfCards['selectionOfCards'];
print(data.toString());
return MaterialApp(
home: DefaultTabController(
length: data.length,
child: Scaffold(
body: TabBarView(
children: data,
),
),
),
);
}
}
Full Working demo Code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {'/tabbedcards': (context) => TabbedCards()},
home: ChooseLetters(),
);
}
}
class ChooseLetters extends StatefulWidget {
@override
_ChooseLettersState createState() => _ChooseLettersState();
}
class _ChooseLettersState extends State<ChooseLetters> {
List<String> alphabets = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'
];
List<Widget> alphabetCards = [
AlphabetCard(),
BAlphabetCard(),
CAlphabetCard(),
DAlphabetCard(),
EAlphabetCard(),
];
List<Widget> selectionCards = <Widget>[];
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [Colors.blueGrey[300], Colors.blueGrey])),
padding: EdgeInsets.all(15),
alignment: Alignment.center,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
),
itemCount: alphabetCards.length,
itemBuilder: (con, ind) {
return InkWell(
onTap: () {
setState(() {
print("print ${alphabetCards[ind].toString()}");
if (selectionCards.contains(alphabetCards[ind]))
selectionCards.remove(alphabetCards[ind]);
else
selectionCards.add(alphabetCards[ind]);
});
print(selectionCards);
},
child: Container(
padding: EdgeInsets.all(10),
alignment: Alignment.center,
decoration: BoxDecoration(
color: selectionCards.contains(alphabetCards[ind])
? Colors.orange
: Colors.white,
borderRadius: BorderRadius.circular(0)),
child: Text(alphabets[ind],
style: TextStyle(color: Colors.black, fontSize: 50))),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.pushNamed(context, '/tabbedcards',
arguments: {'selectionOfCards': selectionCards});
},
backgroundColor: Colors.red,
),
);
}
}
class AlphabetCard extends StatelessWidget {
const AlphabetCard({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text(" A hello"),
);
}
}
class BAlphabetCard extends StatelessWidget {
const BAlphabetCard({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text(" B hello"),
);
}
}
class CAlphabetCard extends StatelessWidget {
const CAlphabetCard({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text(" C hello"),
);
}
}
class DAlphabetCard extends StatelessWidget {
const DAlphabetCard({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text(" D hello"),
);
}
}
class EAlphabetCard extends StatelessWidget {
const EAlphabetCard({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Text(" E hello"),
);
}
}
class TabbedCards extends StatefulWidget {
@override
_TabbedCardsState createState() => _TabbedCardsState();
}
class _TabbedCardsState extends State<TabbedCards> {
Map<String, List> selectionOfCards;
List<Widget> data;
@override
Widget build(BuildContext context) {
selectionOfCards = ModalRoute.of(context).settings.arguments;
data = selectionOfCards['selectionOfCards'];
print(data.toString());
return MaterialApp(
home: DefaultTabController(
length: data.length,
child: Scaffold(
body: TabBarView(
children: data,
),
),
),
);
}
}
Upvotes: 1
Reputation: 80944
Change this:
List selectionCards
Into this:
Map selectionCards
The arguments that you are retrieving here ModalRoute.of(context).settings.arguments
is of type Map
Upvotes: 0