i have create quiz app, my question page is working properly but i want to display all wrong answers with their correct answers on the result page .I tried to get answers but give me so many errors. first i want display score then click show review answers to see the result page like this that u show on picture i want like this my score and result page
here is my question page
enter code here
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:quiz_app/controllers/profile_controllers.dart';
import 'package:quiz_app/widgets/common_components/appbar.dart';
import 'widgets/pallete.dart';
import 'widgets/rounded_button.dart';
void main() {
runApp(QuestionSample2());
}
class ChosenModel {
final int questionNumber;
final String questionAnswer;
ChosenModel(this.questionNumber, this.questionAnswer);
#override
String toString() {
return '{questionNumber: ${questionNumber}, questionAnswer: ${questionAnswer}}';
}
}
class QuestionControl extends GetxController {
List questions = [
{
"id": 1,
"question":
"Flutter is an open-source UI software development kit created by ______",
"options": ['Apple', 'Google', 'Facebook', 'Microsoft'],
"answer": "Google",
},
{
"id": 2,
"question": "When google release Flutter.",
"options": ['Jun 2017', 'July 2017', 'May 2017', 'May 2018'],
"answer": "Jun 2017",
},
{
"id": 3,
"question": "A memory location that holds a single letter or number.",
"options": ['Double', 'Int', 'Char', 'Word'],
"answer": "Char",
},
{
"id": 4,
"question": "What command do you use to output data to the screen?",
"options": ['Cin', 'Count', 'Cout', 'Output'],
"answer": "Output",
},
].obs;
List<ChosenModel> chosenAnswers = [];
RxList groupValue = [-1, 0, 5, 9, 13].obs;
RxList value = [
[0, 1, 2, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]
].obs;
RxInt qnIndex = 1.obs;
}
class QuestionSample2 extends StatelessWidget {
QuestionSample2({Key? key}) : super(key: key);
final QuestionControl controller = Get.put(QuestionControl());
ProfileController _questionController = Get.put(ProfileController());
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: const Color.fromARGB(255, 0, 0, 0),
appBar: quizeAppbar(),
body: Padding(
padding: const EdgeInsets.fromLTRB(5, 15, 5, 10),
child: Column(
children: [
Obx(
() => Text(
controller.qnIndex.toString() +
'/' +
controller.questions.length.toString(),
style: Theme.of(context)
.textTheme
.headline4!
.copyWith(color: Colors.white)),
),
SizedBox(height: 20),
SizedBox(
height: 600.0,
child: PageView.builder(
itemCount: controller.questions.length,
onPageChanged: (pageNumber) {
controller.qnIndex.value = pageNumber + 1;
},
itemBuilder: (context, snapshot) {
var options = controller.questions[snapshot]['options'];
return Container(
margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 88, 79, 79),
borderRadius: BorderRadius.circular(15),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Spacer(
flex: 1,
),
Text(
controller.questions[snapshot]['question']
.toString(),
style: Theme.of(context)
.textTheme
.headline5!
.copyWith(color: Colors.white),
),
Spacer(
flex: 2,
),
Container(
height: 400.0,
child: ListView.builder(
itemCount: 4,
itemBuilder: (context, index) => ButtonBar(
alignment: MainAxisAlignment.center,
children: <Widget>[
Obx(
() => Container(
width: 300,
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border.all(
color: controller.groupValue[
snapshot] ==
controller.value[snapshot]
[index]
? kblue
: Color.fromARGB(
255, 117, 110, 110),
width: 2),
borderRadius:
BorderRadius.circular(15),
),
child: RadioListTile<int>(
activeColor: kblue,
title: Row(
children: [
Text(
options[index].toString(),
style: Theme.of(context)
.textTheme
.headline5!
.copyWith(
color: Colors.white),
),
Spacer(),
],
),
controlAffinity:
ListTileControlAffinity
.trailing,
groupValue:
controller.groupValue[snapshot],
value: controller.value[snapshot]
[index],
onChanged: (newValue) {
controller.groupValue[snapshot] =
newValue as int;
controller.chosenAnswers.add(
ChosenModel(
controller.questions[
snapshot]['id']
as int,
options[index]
.toString()));
print(controller.chosenAnswers);
}),
),
),
],
),
),
),
],
),
);
}),
),
Spacer(),
Obx(
() => controller.questions.length == controller.qnIndex.value
? const RoundedButton(
buttonName: 'Done',
page: '',
)
: Container(),
),
Spacer(),
],
),
),
),
);
}
}
enter code here
Related
I have a form that allows the user to create addition cards at a tap of a button. Each card contains three form fields. How do i get the data from the forms to a json or to a list?
Hopefully get it to this format
"supplier_former_business": [
{
"name_of_company": "John Bull",
"year": 2018,
"amount": 28556
},
{
"name_of_company": "Gini Bull",
"year": 2019,
"amount": 1225
}
]
Here is the code that i have written so far but I am not sure how to get the values from the form fields in the cards.
class CustomerCurrentSuppliers extends StatefulWidget {
const CustomerCurrentSuppliers({Key key}) : super(key: key);
#override
_CustomerCurrentSuppliersState createState() => _CustomerCurrentSuppliersState();
}
class _CustomerCurrentSuppliersState extends State<CustomerCurrentSuppliers> {
int counter=1;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: kPrimaryColor,
title: const Text('Suppliers Data'),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
FloatingActionButton(
child: Icon(
Icons.arrow_forward
),
onPressed: () {
print(counter);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SupplierSchemeUnderConsideration()
),
);
//...
},
heroTag: null,
),
SizedBox(
height: 10,
),
FloatingActionButton(
child: Icon(
Icons.add
),
onPressed: () {
setState(() { //setState is used to update the UI
counter++;
});
},
heroTag: null,
)
]
),
body: Padding(
padding: const EdgeInsets.only(top: 38.0, right: 20, left: 20),
child: ListView.builder(
itemCount: counter, //updating counter will update the UI with new card
itemBuilder: (context,index){
return Card(
child:
Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: FormBuilderTextField(
name: 'Region',
decoration: InputDecoration(
labelText: "Supplier",
border: OutlineInputBorder()),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(context),
]),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: DropdownButtonHideUnderline(
child: FormBuilderDropdown(
name: 'dropdown',
hint: Text("Year"),
isExpanded: true,
items: [
"2018",
"2019",
"2020",
"2021",
].map((option) {
return DropdownMenuItem(
child: Text("$option"),
value: option,
);
}).toList(),
),
),
),
SizedBox(height: 20,),
Padding(
padding: const EdgeInsets.all(8.0),
child: FormBuilderTextField(
name: 'Region',
decoration: InputDecoration(
labelText: "Amount",
border: OutlineInputBorder()),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(context),
]),
),
),
],
),
elevation: 8,
);
}),
),
);
}
}
Status response code is 200 but the ListView is not displayed and stuck on the CircularProgressIndicator.
When I had 2 items in the Json data it was displaying just fine but as I added another item it doesn't show up!
I've tried removing ListView.separated and using ListView.builder instead and also tried using StreamBuilder but I don't seem to be using it correctly as I'm fairly new to Flutter. If I do have to use StreamBuilder can I be guided through how to use it properly here? Thank You.
Here's my API_manager.dart file:
import 'package:http/http.dart' as http;
import 'package:aritic/models/contactsModel.dart';
// ignore: camel_case_types
class API_Manager {
Future<ContactsModel> getContacts() async {
var client = http.Client();
var contactsModel;
String contacts_url =
'https://exampleapi.com';
String basicAuth = 'Basic auth key example';
try {
var response = await client.get(contacts_url,
headers: <String, String>{'authorization': basicAuth});
print(response.statusCode);
if (response.statusCode == 200) {
var jsonString = response.body;
var jsonMap = json.decode(jsonString);
contactsModel = ContactsModel.fromJson(jsonMap);
}
} catch (Exception) {
return contactsModel;
}
return contactsModel;
}
}
My UI Code:
import 'package:aritic/models/contactsModel.dart';
import 'package:aritic/services/api_manager.dart';
class ContactsPage extends StatefulWidget {
#override
_ContactsPageState createState() => _ContactsPageState();
}
class _ContactsPageState extends State<ContactsPage>
with SingleTickerProviderStateMixin {
Future<ContactsModel> _contactsModel;
TabController _tabController;
#override
void initState() {
// TODO: implement initState
super.initState();
_tabController = TabController(length: 2, initialIndex: 0, vsync: this);
_tabController.addListener(_handleTabIndex);
_contactsModel = API_Manager().getContacts();
}
#override
void dispose() {
_tabController.removeListener(_handleTabIndex);
_tabController.dispose();
super.dispose();
}
void _handleTabIndex() {
setState(() {});
}
#override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('Contacts'),
bottom: PreferredSize(
child: Align(
alignment: Alignment.centerLeft,
child: TabBar(
controller: _tabController,
isScrollable: true,
unselectedLabelColor: Colors.white.withOpacity(0.3),
indicatorColor: Colors.white,
tabs: [
Tab(
child: Text('Contacts'),
),
Tab(
child: Text('Companies'),
)
],
),
),
preferredSize: Size.fromHeight(40.0)),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: IconButton(
icon: Icon(Icons.search),
color: Colors.white,
onPressed: () {},
),
),
],
),
body: TabBarView(controller: _tabController, children: <Widget>[
Container(
height: double.infinity,
child: FutureBuilder<ContactsModel>(
future: _contactsModel,
builder: (BuildContext context,
AsyncSnapshot<ContactsModel> snapshot) {
if (snapshot.hasData) {
return ListView.separated(
shrinkWrap: true,
padding: const EdgeInsets.all(6),
itemCount: snapshot.data.contacts.length,
itemBuilder: (BuildContext context, int index) {
List keys = snapshot.data.contacts.keys.toList();
List values =
snapshot.data.contacts.values.toList();
var contact = values[index];
return InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => ViewContact()));
},
child: Container(
height: 50,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
contact.owner.firstName +
" " +
contact.owner.lastName,
style: TextStyle(fontSize: 16),
),
Text(
contact.owner.username,
style: TextStyle(fontSize: 14),
),
SizedBox(
height: 5,
),
],
),
),
);
},
separatorBuilder: (BuildContext context, int index) {
return SizedBox(
height: 5,
);
},
);
} else
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.blueGrey[700],
valueColor: AlwaysStoppedAnimation<Color>(
Colors.cyan)));
})),
Container(
height: double.infinity,
child: ListView(
padding: const EdgeInsets.all(6),
children: <Widget>[
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => ViewCompany()));
},
child: Container(
height: 50,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'example company name',
style: TextStyle(fontSize: 16),
),
Text(
'example company domain',
style: TextStyle(fontSize: 14),
)
],
),
),
),
SizedBox(
height: 5,
),
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (_) => ViewCompany()));
},
child: Container(
height: 50,
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'example company name',
style: TextStyle(fontSize: 16),
),
Text(
'example company domain',
style: TextStyle(fontSize: 14),
)
],
),
),
),
],
)),
]),
floatingActionButton: _bottomButtons(),
));
}
Widget _bottomButtons() {
return _tabController.index == 0
? FloatingActionButton(
shape: StadiumBorder(),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return AddContacts();
}));
},
backgroundColor: Colors.cyan,
child: Icon(
Icons.person_add,
color: Colors.white,
))
: FloatingActionButton(
shape: StadiumBorder(),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return AddCompany();
}));
},
backgroundColor: Colors.cyan,
child: Icon(
Icons.add,
color: Colors.white,
),
);
}
}
Json sample(complete json too big to upload here):
{
"total": "187144",
"contacts": {
"897": {
"isPublished": true,
"id": 897,
"fields": {
"core": {
"points": {
"id": "47",
"label": "Points"
},
"firstname": {
"id": "2",
"label": "First Name",
"value": "Jason"
},
"lastname": {
"id": "3",
"label": "Last Name",
"value": "Lamuda"
},
"...": {
"..." : "..."
}
},
"ipAddresses": [
{
"ip": "70.127.91.131",
"ipDetails": {
"city": "Bradenton",
"region": "Florida",
"timezone": "America/New_York",
}
},
"...": {
"..." : "..."
}
Output Screen(stuck on CircularProgressIndicator): here
create a function like
Future getContacts()async{
_contactsModel = API_Manager().getContacts();
}
then inside your initState
getContacts().then((value){
setState((){});
})
I'm having trouble displaying 'option' and getting (print in terminal) the 'id' of the chosen option.
How can I retrieve the json as map and use it effectively in flutter_form_builder?
Here is the json object:
{
id: 7,
poll: What is the capital of Egypt?,
created_at: 2020-10-22 10:53:41,
votes_count: 4,
likes_count: 0,
options: [
{
id: 20,
option: Tunis,
pollId: 7,
votes_count: 1
}, {
id: 21,
option: Cairo,
pollId: 7,
votes_count: 3
}, {
id: 22,
option: New York,
pollId: 7,
votes_count: 0
}],
user_name: salem,
user_image: null,
topics: []
}
Here is my poll_details page:
import 'package:flutter/material.dart';
import 'package:circular_profile_avatar/circular_profile_avatar.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:like_button/like_button.dart';
import '../services/poll_services.dart';
import '../widgets/loading_widget.dart';
class PollDetails extends StatefulWidget {
final id;
PollDetails({this.id});
#override
_PollDetailsState createState() => _PollDetailsState(id);
}
class _PollDetailsState extends State<PollDetails> {
var id;
_PollDetailsState(this.id);
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
#override
void initState() {
super.initState();
optionsList.clear();
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(title: Text("Details")),
body: FutureBuilder(
future: singlePoll(id),
builder: (context, snapshot) {
if(snapshot.hasData){
return ListView(
padding: EdgeInsets.fromLTRB(18, 40, 18, 0),
children: [
Padding(
padding: EdgeInsets.only(bottom: 20),
child: Container(
padding: EdgeInsets.fromLTRB(10, 40, 0, 40),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10.0),
border: Border.all(
color: Theme.of(context).primaryColor,
width: 5.0,
style: BorderStyle.solid
)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if(imgPath(snapshot.data) == null) CircleAvatar(radius: 35,child: Image.asset('images/avatar.png'))
else CircularProfileAvatar(
imgPath(snapshot.data),
radius: 35,
borderWidth: 3.0,
borderColor: Colors.white,
backgroundColor: Colors.transparent,
foregroundColor: Colors.transparent,
errorWidget: (context, url, error) => Container(child: Icon(Icons.error)),
placeHolder: (context, url) => Container(
width: 50,
height: 50,
child: Text("Loading image..."),
)
),
SizedBox(width: 10.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
userName(snapshot.data),
style: TextStyle(fontSize: 20)
),
Flexible(
fit: FlexFit.loose,
child: Text(
votesCount(snapshot.data).toString()+" participants to this poll",
style: TextStyle(fontSize: 13)
)
)
]
)
)
]
)
)
),
///////////////////////////////// POLLS //////////////////////////////////////////////
FormBuilder(
key: _fbKey,
autovalidateMode: AutovalidateMode.always,
child: FormBuilderRadioGroup(
attribute: 'options',
decoration: InputDecoration(labelText: 'Choose only one:'),
validators: [FormBuilderValidators.required()],
orientation: GroupedRadioOrientation.vertical,
options: [
for (var i in optionsList) i['option'].toString()
]
.map((option) => FormBuilderFieldOption(value: option))
.toList(growable: false),
)
),
RaisedButton(
child: Text("Submit"),
onPressed: () async{
_fbKey.currentState.save();
if (_fbKey.currentState.validate()) {
// Loading().show(context);
var option = _fbKey.currentState.value['options'];
print(option);
// var resp = await createPoll(question, tagS, choiceS);
// if(resp['status'] == "success"){
// Navigator.pop(context); //pop dialog
// } else {
// Navigator.pop(context); //pop dialog
// }
}
}
),
//////////////////////////// Like Button ///////////////////////////////
Row(
children: [
LikeButton(
size: 40,
circleColor:
CircleColor(start: Colors.red, end: Colors.red),
bubblesColor: BubblesColor(
dotPrimaryColor: Colors.red,
dotSecondaryColor: Colors.red,
),
likeBuilder: (bool isLiked) {
return Icon(
Icons.favorite,
color: isLiked ? Colors.red : Colors.grey,
size: 40,
);
},
likeCount: likes(snapshot.data),
countBuilder: (int count, bool isLiked, String text) {
var color = isLiked ? Colors.red : Colors.grey;
Widget result;
if (count == 0) {
result = Text(
"0",
style: TextStyle(color: color),
);
} else
result = Text(
text,
style: TextStyle(color: color),
);
return result;
}
),
Expanded(child: Text(" have liked this. Show some love, too!"))
]
),
Column(
children: [
// optionsList.forEach((element) => Text('option'))
for (var i in optionsList) Text(i['option'].toString())
]
),
RaisedButton(
child: Text("data"),
onPressed: (){singlePoll(id);}
)
]
);
}else {
return Center(child: CircularProgressIndicator());
}
}
)
)
);
}
}
And here is the request I use to get the response:
Future singlePoll(int id) async {
String url = baseUrl+"poll/get";
var stringID = id.toString();
var token = await storage.read(key: "jwt");
try{
final response = await http.post(
url,
headers: {'Accept':'application/json', 'Authorization':token},
body: {'pollId':stringID}
);
var dataToJson = jsonDecode(response.body);
for (var option in dataToJson['options']){
var optionID = option['id'];
var optionTitle = option['option'].toString();
var votesCount = option['votes_count'];
optionsList.add(option);
}
print(dataToJson);
return dataToJson;
} catch (e){
print('error caught: $e');
}
}
As you can see, I used a work around to get the list and display it.
Any suggestion is valuable.
Thanks in advance...
You need to use setState() in here:
setState() {
var optionID = option['id'];
var optionTitle = option['option'].toString();
var votesCount = option['votes_count'];
optionsList.add(option);
}
You can read more from the official document and look at here.
I want to display only the units with univ_spec_sub_id as 53 from the JSON returned into a Listview. I have tried implementing some code but it doesn't work. Is there any other way i can get the desired output?
This is the JSON being returned after hitting an URL :
"unit": [
{
"unit_id": "268",
"univ_spec_sub_id": "53",
"no_chapters": "13",
"unit_name": "File Handling and Dictionaries",
},
{
"unit_id": "300",
"univ_spec_sub_id": "53",
"no_chapters": "14",
"unit_name": "Decision Control Statements",
},
{
"unit_id": "298",
"univ_spec_sub_id": "59",
"no_chapters": "16",
"unit_name": "Electromagnetism",
},
{
"unit_id": "299",
"univ_spec_sub_id": "59",
"no_chapters": "0",
"unit_name": "Coming Soon",
},
This is the code i implemented.In this i have passed the unit JSON array as list and the univ_spec_sub_id using constructor:
checkid(int index){
if(widget.data[index]["univ_spec_sub_id"]== widget.univ_sub){
articles(index);
}
}
Container articles(int index){
return Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
GestureDetector(
child: Card(
child: Container(
child: Text(widget.data[index]["unit_no"]),
padding: const EdgeInsets.all(20),
),
),
onTap: (){
print(widget.univ_sub);
},)
],
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo[700],
body: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 110, 0),
child: Container(
padding: EdgeInsets.fromLTRB(0, 30, 200, 0),
child: IconButton(icon: Icon(Icons.arrow_back),
color: Colors.black,
onPressed: (){
Navigator.pop(context);
},
),
),
),
SizedBox(height: 10,),
Text('Programming and ',
style: TextStyle(color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold),
),
Text(' Problem Solving (IT) ',
style: TextStyle(color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(height: 40,),
Container(
height: MediaQuery.of(context).size.height - 185,
decoration: BoxDecoration(
color: Colors.white70,
borderRadius: BorderRadius.only(topLeft: Radius.circular(75.0)),
),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 100, 0, 0),
child: Expanded(
child: ListView.builder(
itemCount: widget.data.length,
itemBuilder: (BuildContext context,int index){
return Container(
child: checkid(index),
);
}),
),
),
)
],
),
);
Just check out the example that I have created.
json that you have given : Just validated from my side
{
"unit": [{
"unit_id": "268",
"univ_spec_sub_id": "53",
"no_chapters": "13",
"unit_name": "File Handling and Dictionaries"
},
{
"unit_id": "300",
"univ_spec_sub_id": "53",
"no_chapters": "14",
"unit_name": "Decision Control Statements"
},
{
"unit_id": "298",
"univ_spec_sub_id": "59",
"no_chapters": "16",
"unit_name": "Electromagnetism"
},
{
"unit_id": "299",
"univ_spec_sub_id": "59",
"no_chapters": "0",
"unit_name": "Coming Soon"
}
]
}
This is t the model class for the json
// To parse this JSON data, do
//
// final unit = unitFromJson(jsonString);
import 'dart:convert';
Unit unitFromJson(String str) => Unit.fromJson(json.decode(str));
String unitToJson(Unit data) => json.encode(data.toJson());
class Unit {
Unit({
this.unit,
});
List<UnitElement> unit;
factory Unit.fromJson(Map<String, dynamic> json) => Unit(
unit: List<UnitElement>.from(json["unit"].map((x) => UnitElement.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"unit": List<dynamic>.from(unit.map((x) => x.toJson())),
};
}
class UnitElement {
UnitElement({
this.unitId,
this.univSpecSubId,
this.noChapters,
this.unitName,
});
String unitId;
String univSpecSubId;
String noChapters;
String unitName;
factory UnitElement.fromJson(Map<String, dynamic> json) => UnitElement(
unitId: json["unit_id"],
univSpecSubId: json["univ_spec_sub_id"],
noChapters: json["no_chapters"],
unitName: json["unit_name"],
);
Map<String, dynamic> toJson() => {
"unit_id": unitId,
"univ_spec_sub_id": univSpecSubId,
"no_chapters": noChapters,
"unit_name": unitName,
};
}
This is the main ui for it :
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:json_parsing_example/models.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.amber),
home: FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
#override
_FirstPageState createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
List<UnitElement> unitList = List();
#override
void initState() {
super.initState();
loadData();
}
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
loadData() async {
String jsonString = await loadFromAssets();
final unit = unitFromJson(jsonString);
unitList = unit.unit;
}
#override
Widget build(BuildContext context) {
return Container(
child: RaisedButton(
child: Text('Second'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(
data: unitList,
univ_sub: "53",// This 53 is hardcoded you can add as per //your code
),
),
);
},
),
);
}
}
class SecondPage extends StatefulWidget {
final String univ_sub;
final List<UnitElement> data;
const SecondPage({Key key, this.univ_sub, this.data}) : super(key: key);
#override
_SecondPageState createState() => _SecondPageState();
}
class _SecondPageState extends State<SecondPage> {
Widget checkid(int index) {
if (widget.data[index].univSpecSubId == widget.univ_sub) {
return articles(index);
}
}
Container articles(int index) {
return Container(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
GestureDetector(
child: Card(
child: Container(
child: Text(widget.data[index].unitId),
padding: const EdgeInsets.all(20),
),
),
onTap: () {
print(widget.univ_sub);
},
)
],
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.indigo[700],
body: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 110, 0),
child: Container(
padding: EdgeInsets.fromLTRB(0, 30, 200, 0),
child: IconButton(
icon: Icon(Icons.arrow_back),
color: Colors.black,
onPressed: () {
Navigator.pop(context);
},
),
),
),
SizedBox(
height: 10,
),
Text(
'Programming and ',
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold),
),
Text(
' Problem Solving (IT) ',
style: TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 40,
),
Container(
height: MediaQuery.of(context).size.height - 185,
decoration: BoxDecoration(
color: Colors.white70,
borderRadius: BorderRadius.only(topLeft: Radius.circular(75.0)),
),
child: Padding(
padding: EdgeInsets.fromLTRB(0, 100, 0, 0),
child: ListView.builder(
shrinkWrap: true,
itemCount: widget.data.length,
itemBuilder: (BuildContext context, int index) {
return Container(
child: checkid(index),
);
}),
),
)
],
),
);
}
}
Just check it out and let me know if it works.
I am new to flutter this error is giving me a serious nightmare. I have a card list of items called Anchors. These items are coming from the shared preference file which belongs to the logged-in user. In the shared preference Json file, each anchor has one or more distribution centers nested to it. All in a JSON form stored in the shared Preference. Now, I was able to iterate over the anchors respectfully at the first screen but the challenge I am having is when I click on view anchor details button instead of taking me to the details page where I can view the details of that anchor and iterate over the distribution centers of that anchor it doesn't but instead it takes the whole anchors there. I tried to parse only one id to the details page so I can Iterate over the nested objects of that anchor but still its not working. The error message says: type 'int' is not a subtype of type 'List' But if I remove [i]['Oid'] from the link to the details screen it takes the whole data there. They are all on two different screens. Please can anybody help me?
JSON format of:
"Anchors": [
{
"Oid": 11,
"Name": "MAIZE ASSOCIATION OF NIGERIA",
"Acronym": "MAAN",
"DistributionCentres": [
{
"Oid": 11,
"Name": "Logo Centre (Zone A)",
"Address": "Private Warehouse, Ugba, Logo LGA"
},
{
"Oid": 12,
"Name": "Makurdi Centre (Zone B)",
"Address": "Ministry of Agric, Makurdi "
},
{
"Oid": 13,
"Name": "Oturkpo Centre (Zone C)",
"Address": "Private Warehouse, Oturkpo"
},
{
"Oid": 15,
"Name": "Borno MAAN centre",
"Address": "Bolori Store, Flavour Mill, Behind Vita Foam, Maiduguri"
},
{
"Oid": 18,
"Name": "Bauchi Centre",
"Address": "BASPD, Dass Road, Bauchi"
}
],
"NoOfDistributionCentres": 5
},
{
"Oid": 2,
"Name": "MAIZE GROWERS, PROCESSORS AND MARKETERS ASSOCIATION OF NIGERIA",
"Acronym": "MAGPAMAN",
"DistributionCentres": [
{
"Oid": 2,
"Name": "Guma Centre",
"Address": "P 32, 2nd Avenue Federal Housing Estate, N/Bank, Makurdi"
},
{
"Oid": 3,
"Name": "Logo Centre",
"Address": "Terhemen Akema Storage Facility, Ugba, Logo LGA"
},
{
"Oid": 5,
"Name": "Oturkpo Centre",
"Address": "Grain Store, Lower Benue Okele Project, Otukpo"
},
{
"Oid": 6,
"Name": "Gboko Centre",
"Address": "K3 New Road, Opposite former coca cola plant. Solar Schools Street, Gboko"
},
{
"Oid": 7,
"Name": "Gwer East Centre",
"Address": "Ahua Shardye's Warehouse, Behind Sylkan Filling Station, Ikpayongo , G/East LGA"
},
{
"Oid": 8,
"Name": "Kwande Centre",
"Address": "KM 3, Adagi Road, Adikpo"
},
{
"Oid": 9,
"Name": "Ohimini Centre",
"Address": "Ajoga Oglewu, Ohimini"
},
{
"Oid": 10,
"Name": "Oju Centre",
"Address": "Behind Town Hall, Ohuhu owo, Oju LGA"
}
],
"NoOfDistributionCentres": 8
}
],
Anchors Page:
import 'package:erg_app/Details.dart';
import 'package:flutter/material.dart';
import 'package:erg_app/Widgets/nav-drawer.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MaterialApp(
home: AnchorsPage(),
));
class AnchorsPage extends StatefulWidget {
#override
_MyHomeState createState() => _MyHomeState();
}
List<Anchor> _parseAnchors(Map<String, dynamic> map) {
final anchors = <Anchor>[];
for (var anchorMap in map['Anchors']) {
final anchor = Anchor.fromMap(anchorMap);
anchors.add(anchor);
}
return anchors;
}
class Anchor {
final int oId;
final String name;
final String acronym;
final List<DistributionCenter> distributionCenters;
const Anchor({
#required this.oId,
#required this.name,
#required this.acronym,
#required this.distributionCenters,
});
factory Anchor.fromMap(Map<String, dynamic> map) {
final distributionCenters = <DistributionCenter>[];
for (var distribution in map['DistributionCentres']) {
final distributionCenter = DistributionCenter.fromMap(distribution);
distributionCenters.add(distributionCenter);
}
return Anchor(
oId: map['Oid'] as int,
name: map['Name'] as String,
acronym: map['Acronym'] as String,
distributionCenters: distributionCenters,
);
}
}
class DistributionCenter {
final int id;
final String name;
final String address;
const DistributionCenter({
#required this.id,
#required this.name,
#required this.address,
});
factory DistributionCenter.fromMap(Map<String, dynamic> map) {
return DistributionCenter(
id: map['Oid'] as int,
name: map['Name'] as String,
address: map['Address'] as String,
);
}
}
class _MyHomeState extends State<AnchorsPage> {
var user;
var userData;
List anchors = [];
#override
void initState() {
_getUserAnchor();
super.initState();
}
_getUserAnchor() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var userJson = localStorage.getString('loginRes');
user = json.decode(userJson);
setState(() {
anchors = user['Anchors'];
});
print(anchors);
setState(() {
userData = anchors;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
title: Text('Anchors Details'),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
padding: const EdgeInsets.fromLTRB(10, 30, 10, 10),
child: ListView(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Icon(Icons.card_membership,
size: 35, color: Colors.orange[400]),
Text(
'Assigned Anchors',
style: TextStyle(color: Colors.orange[400], fontSize: 25),
),
],
),
ListView.builder(
shrinkWrap: true,
itemCount: anchors.length,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
return Padding(
padding: const EdgeInsets.all(10.0),
////////////// 1st card///////////
child: Card(
elevation: 4.0,
color: Colors.grey[100],
margin: EdgeInsets.only(
left: 10, right: 10, top: 20, bottom: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Container(
padding: EdgeInsets.only(left: 15, top: 20, bottom: 10),
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: 50.0,
height: 50.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.cover,
image: AssetImage(
'assets/images/user.png')))),
),
SizedBox(
width: 20,
),
Text(
anchors[i]['Acronym'],
textAlign: TextAlign.center,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 20,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
],
),
Container(width: 10),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Allocated Farmers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 70, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Validated Farmers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 70, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Non Validated Farmers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 40, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Distribution Centers:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 60, top: 12),
child: Text(
anchors[i]['Oid'].toString(),
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.grey[700],
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Row(
children: <Widget>[
Padding(
padding:
const EdgeInsets.only(left: 10, top: 10),
child: Text(
'Daily Inventory Status:',
textAlign: TextAlign.left,
style: TextStyle(
color: Color(0xFF9b9b9b),
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
Padding(
padding:
const EdgeInsets.only(left: 50, top: 12),
child: Text(
'3',
textAlign: TextAlign.left,
style: TextStyle(
color:Colors.green,
fontSize: 14.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
],
),
Container(
height: 20,
),
Row(
children: <Widget>[
/////////// Buttons /////////////
Padding(
padding: const EdgeInsets.all(10.0),
child: FlatButton(
child: Padding(
padding: EdgeInsets.only(
top: 8,
bottom: 8,
left: 10,
right: 8),
child: Text(
'View Details',
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
color: Colors.blueGrey,
shape: new RoundedRectangleBorder(
borderRadius:
new BorderRadius.circular(
20.0)),
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
detailsPage(value : anchors[i]['Oid'])));
},
),
),
/////////// End of Buttons /////////////
],
),
],
),
),
),
);
})
],
),
),
);
}
}
Details Page:
import 'package:flutter/material.dart';
class detailsPage extends StatefulWidget {
List value;
detailsPage({Key key, #required this.value}) : super(key: key);
#override
_detailsPageState createState() => _detailsPageState(value);
}
class _detailsPageState extends State<detailsPage> {
List value;
_detailsPageState(this.value);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Anchors Details Page"),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
child: ListView(
children: <Widget>[
Text(value[1]['Name']),
Text(value[1]['Oid'].toString()),
ListView.builder(
shrinkWrap: true,
itemCount: value[1]['DistributionCentres'].length,
//context:context, //it saying the name parameter context is not defined
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
return Text(value[1]['DistributionCentres'][i]['Name']);
})
],
),
),
);
}
}
Image of what I want to achieve below:
first screen onPressed get the index and assigned it to variable, or you can just pass i varibale too,
onPressed: () {
Navigator.push(context,new MaterialPageRoute(builder: (context) =>
detailsPage(i))); },
In detailed page
class detailsPage extends StatefulWidget {
final int selectedIndex;
detailsPage(this.selectedIndex,{Key key}) : super(key: key);
#override
_detailsPageState createState() => _detailsPageState();
}
place that you want to use the previous page passsed index,
return Text(value[widget.selectedIndex]['DistributionCentres'][i]['Name']);
Hope this will help..
The problem seems to be here
detailsPage(value : anchors[i]['Oid'])
You're passing Oid as parameter that is an Int. But look that the constructor for detailsPage
List value;
detailsPage({Key key, #required this.value}) : super(key: key);
The parameter value is a List. It's hard for me to know what you're trying to do... but you will need to fix this type mismatch.
EDIT
It seems that value parameter should be of type Map<String,dynamic>
class detailsPage extends StatefulWidget {
Map<String, dynamic> value;
detailsPage({Key key, #required this.value}) : super(key: key);
#override
_detailsPageState createState() => _detailsPageState(value);
}
class _detailsPageState extends State<detailsPage> {
Map<String, dynamic> value;
_detailsPageState(this.value);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Anchors Details Page"),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Colors.green,
),
body: Container(
child: ListView(
children: <Widget>[
Text(value['Name']),
Text(value['Oid'].toString()),
ListView.builder(
shrinkWrap: true,
itemCount: value['DistributionCentres'].length,
//context:context, //it saying the name parameter context is not defined
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
return Text(value['DistributionCentres'][i]['Name']);
})
],
),
),
);
}
}
And then you should do
detailsPage(value : anchors[i])));