Need to categorize Data from json - json

I am reading json data that Contain some items (and Items have some categories I wanna show data on the basis of categories like using same widget again and again just have to change category name only Here What I have done so far it show all the items.
Also Added image for items.
Widget buildItems(List<[![Items]> items) => GridView.builder(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 4.0,
mainAxisSpacing: 20.0,
mainAxisExtent: 170,
),
//itemCount: items.length,
itemCount: itemCount,
itemBuilder: (context, index) {
final item = items[index];
int random = Random().nextInt(items.length);
print(random);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: InkWell(
onTap: () => Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) =>
DetailScreen(item: item))),
// => Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) =>
// ProductPage(product: product))),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: const [
BoxShadow(
color: Colors.black38,
// spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 5.0)),
BoxShadow(color: Colors.white, offset: Offset(-1, 0)),
BoxShadow(color: Colors.white, offset: Offset(2, 0)),
]),
child: Column(
children: [
SizedBox(
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10)),
child: Image.network(
'$imageLink${item.imageUrl}',
fit: BoxFit.fill,
width: double.infinity,
height: 110,
),
),
),
SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
margin:
const EdgeInsets.only(left: 5, top: 10),
height: 40,
width: 40,
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.network(
'$iconLink${item.logo}',
fit: BoxFit.fill)),
),
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Container(
width: 120,
margin: const EdgeInsets.only(
top: 7, left: 5),
child: Flexible(
child: SizedBox(
child: Text('${item.name}',
overflow: TextOverflow.ellipsis,
style: Theme.of(context)
.textTheme
.bodyText1),
),
),
// Flexible(
// child: Text(
// product.name,
// style: const TextStyle(
// fontWeight: FontWeight.bold,
// color: Colors.black,
// fontSize: 14),
// ),
// ),
),
),
const SizedBox(
height: 2,
),
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Text('${item.subcategory}',
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(
color: kButtonBackground)),
),
],
),
],
),
],
),
),
],
),
),
)
// ListTile(
// onTap: () => Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) =>
// ProductPage(product: product))),
// title: Text(product.name),
// ),
);
},
);
//------------------------------ JSON SAMPLE
[ {
"name": "Item1",
"category": "Apple",
"subcategory": "Productivity",
"imageUrl": "Banner.jpg",
"logo": "logo.png",
"description": "falkr."
},
{
"name": "ABC",
"category": "Testing1",
"subcategory": "Productivity",
"imageUrl": "banner.jpg",
"logo": "System.png",
"description": "Testing."
}
]
//-------------------------------
https://i.stack.imgur.com/iX9Hh.png

#Talal, you have to filter the list based on the selected category, like below
List<Items> categorySpecificItems = allItems.where((item) => item.category == selectedCategory).toList()
Now pass the categorySpecificItems to buildItems on the change of selected category and use some state handling to render the UI.
Hope this works!

Related

Creating a dynamic array of boxes in listview in Flutter?

I am really confused as per what should I do, I am pretty bad with the layout of flutter.
I want to create boxes in the listview according to the number of strings (addresses) I have in another class - what is the best practice or approach for that?
Here Is the Image of the APP
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'AddData.dart';
import 'package:donation_yoga/services/json_service.dart';
//import 'package:provider/provider.dart';
class Map extends StatefulWidget {
#override
State<StatefulWidget> createState() => _MapState();
}
class _MapState extends State<Map> {
/* Getting Live Location */
Completer<GoogleMapController> _controllerGoogleMap = Completer();
GoogleMapController newGoogleMapController;
Position currentPosition;
var geoLocator = Geolocator();
void locatePosition() async {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
currentPosition = position;
LatLng latLngPos = LatLng(position.latitude, position.longitude);
CameraPosition cameraPosition =
CameraPosition(target: latLngPos, zoom: 15.0);
newGoogleMapController
.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
}
static final CameraPosition _kGooglePlex = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 14.4746,
);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
myLayoutWidget(),
_buildContainer(),
_createForm(context),
],
),
);
}
Widget myLayoutWidget() {
return Container(
child: GoogleMap(
mapType: MapType.normal,
myLocationButtonEnabled: true,
initialCameraPosition: _kGooglePlex,
myLocationEnabled: true,
zoomGesturesEnabled: true,
onMapCreated: (GoogleMapController controller) {
_controllerGoogleMap.complete(controller);
newGoogleMapController = controller;
locatePosition();
},
),
);
}
}
Widget _buildContainer() {
return Align(
alignment: Alignment.bottomLeft,
child: Container(
margin: EdgeInsets.symmetric(vertical: 20.0),
height: 150.0,
child: ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
SizedBox(width: 10.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: _boxes(
"https://lh5.googleusercontent.com/p/AF1QipO3VPL9m-b355xWeg4MXmOQTauFAEkavSluTtJU=w225-h160-k-no",
40.738380,
-73.988426,
Centres.first),
),
SizedBox(width: 10.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: _boxes(
"https://lh5.googleusercontent.com/p/AF1QipMKRN-1zTYMUVPrH-CcKzfTo6Nai7wdL7D8PMkt=w340-h160-k-no",
40.761421,
-73.981667,
Centres.second),
),
SizedBox(width: 10.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: _boxes(
"https://images.unsplash.com/photo-1504940892017-d23b9053d5d4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60",
40.732128,
-73.999619,
Centres.third),
),
],
),
),
);
}
Widget _boxes(String _image, double lat, double long, String restaurantName) {
return GestureDetector(
onTap: () {},
child: Container(
child: new FittedBox(
child: Material(
color: Colors.white,
elevation: 14.0,
borderRadius: BorderRadius.circular(24.0),
shadowColor: Color(0x802196F3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: 180,
height: 200,
child: ClipRRect(
borderRadius: new BorderRadius.circular(24.0),
child: Image(
fit: BoxFit.fill,
image: NetworkImage(_image),
),
),
),
Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: myDetailsContainer1(restaurantName),
),
),
],
)),
),
),
);
}
Widget myDetailsContainer1(String restaurantName) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Container(
child: Text(
restaurantName,
style: TextStyle(
color: Color(0xff6200ee),
fontSize: 24.0,
fontWeight: FontWeight.bold),
)),
),
SizedBox(height: 5.0),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
child: Text(
"4.1",
style: TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
)),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStar,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Icon(
FontAwesomeIcons.solidStarHalf,
color: Colors.amber,
size: 15.0,
),
),
Container(
child: Text(
"(946)",
style: TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
)),
],
)),
SizedBox(height: 5.0),
Container(
child: Text(
"This is ",
style: TextStyle(
color: Colors.black54,
fontSize: 18.0,
),
)),
SizedBox(height: 5.0),
Container(
child: Text(
"Closed \u00B7 Opens 17:00 Thu",
style: TextStyle(
color: Colors.black54, fontSize: 18.0, fontWeight: FontWeight.bold),
)),
],
);
}
Widget _createForm(BuildContext context) {
return Align(
alignment: Alignment(-0.2, -1.0),
child: TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddData()),
);
},
child: Text("Create")),
);
}
Here is my Other Class.
class Centres {
static const String first = 'This is our first location';
static const String second = 'This is our Second location';
static const String third = 'This is our Third locations';
}
The data in this class is gonna come from server.
You can use a ListView.builder to create a list of your boxes, just provide an item count that means how many widgets it will create and use the index to access each value you want to take from the lists of values.
I know i did not use you Centres class, unless you really need it to be a class, i find it easier to use a list with the values you need
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
final List<String> entries = <String>['A', 'B', 'C'];
final List<String> centres = [
'first location',
'second location',
'third location'
];
final List<double> latitudes = [40.732128, 40.732128, 40.732128];
final List<double> longitudes = [-73.999619, -73.999619, -73.999619];
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return _boxes(
entries[index],
latitudes[index],
longitudes[index],
centres[index],
);
});
}
}
You can use both ListView.builder() and PageView.builder(). in ListView you can stay in between two boxes but PageView only stays on one box. both have the itemCount and itemBuilder.

Flutter ListView condition only Displays the first item in a list

I am quite new to Flutter and Dart development.
I am trying to display a list of all of the items in a JSON List that match a particular criteria, with the criteria being a type of alcohol in this case. I have created an IF statement at the top of what the ListBuilder returns, but it only returns the first item in the list when it matches the criteria. For example, I have three objects where the category is "Rum", but it still only returns the first one. Any help or advice would be greatly appreciated! Thank you!
class CocktailCategoryList extends StatefulWidget {
#override
_CocktailListState createState() => _CocktailListState();
}
class _CocktailListState extends State<CocktailCategoryList> {
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: Container(
height: 55,
width: 55,
child: FittedBox(
child: Container(
height: 60,
width: 60,
child: FloatingActionButton(
backgroundColor: Color.fromRGBO(86, 99, 255, 100),
onPressed: () {
},
child: Icon(
Icons.shuffle,
color: Colors.white,
size: 35,
),
),
),
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.miniCenterDocked,
bottomNavigationBar: BottomAppBar(
elevation: 20,
shape: CircularNotchedRectangle(),
child: Container(
height: 55,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
iconSize: 30,
padding: EdgeInsets.only(left: 28),
icon: Icon(
Icons.home,
),
onPressed: () {
Navigator.pop(context);
},
),
IconButton(
iconSize: 30,
padding: EdgeInsets.only(right: 28),
icon: Icon(
Icons.list,
color: Colors.purple[700],
),
onPressed: () {},
),
IconButton(
iconSize: 30,
padding: EdgeInsets.only(left: 28),
icon: Icon(Icons.person),
onPressed: () {},
),
IconButton(
iconSize: 30,
padding: EdgeInsets.only(right: 28),
icon: Icon(Icons.search),
onPressed: () {},
),
],
),
),
),
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(
color: Colors.black,
),
centerTitle: true,
title: Text(
"Cocktails",
style: TextStyle(color: Colors.black),
),
),
body: Center(
child: FutureBuilder(
builder: (context, snapshot) {
var cocktailData = json.decode(snapshot.data.toString());
return ListView.builder(
itemCount: cocktailData == null ? 0 : cocktailData.length,
itemBuilder: (BuildContext context, int index) {
if (cocktailData[index]['category'] == "Rum"){
Column(
children: [
SafeArea(
minimum: EdgeInsets.fromLTRB(15, 0, 15, 0),
child: GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CocktailPage(
cocktailData[index]['name'],
cocktailData[index]['subtitle'],
cocktailData[index]['category'],
cocktailData[index]['instructions'],
cocktailData[index]['image'],
cocktailData[index]['ingredients'],
))),
child: Container(
width: MediaQuery.of(context).size.width,
child: Wrap(children: [
Image(
image: NetworkImage(cocktailData[index]['image']),
),
]),
),
),
),
GestureDetector(
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CocktailPage(
cocktailData[index]['name'],
cocktailData[index]['subtitle'],
cocktailData[index]['category'],
cocktailData[index]['instructions'],
cocktailData[index]['image'],
cocktailData[index]['ingredients'],
))),
child: ListTile(
visualDensity:
VisualDensity(horizontal: 0, vertical: -1),
title: Row(
children: [
Text(
cocktailData[index]['name'],
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(
width: 5,
),
CategoryTag(
cocktailData[index]['category']) //Button Here
],
),
subtitle: Text(cocktailData[index]['subtitle']),
),
),
SizedBox(height: 10)
],
);
}else {
SizedBox();
}
}
);
},
future:
DefaultAssetBundle.of(context).loadString('assets/testJson.json'),
),
),
);
}
}
One thing I noticed is that you are not returning the Column widget in your ListView.builder() inside of the if statement. The anonymous builder function that you provide to the ListView.builder() should always return a widget.

Pagination inside a CustomScrollView - Flutter

I have implemented a CustomScrollview in which i have the SliverGrid whereI'm successfully fetching the data from the server, but i need to provide the pagination over here, i need some assistance as how can acheive that whether by adding a button and incrementing the values or by adding an infinite scroll view and doing the pagination. But how to deal with the UI too is my problem here, so can any one assist me on this.
#override
Widget build(BuildContext context) {
print("Home");
return WillPopScope(
onWillPop: exitApp,
child: Scaffold(
appBar: AppBar(
leading: Image.asset('assets/images/ic_logo.png'),
actions: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: FlatButton.icon(
onPressed: () {},
icon: Icon(Icons.location_on),
label: Text('Mysuru, India'),
textColor: Colors.white,
),
),
],
),
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: SizedBox(
child: _search(),
),
),
SliverToBoxAdapter(
child: SizedBox(
child: FutureBuilder(
future: _getCat(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Categories'),
GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context) => CategoriesScreen()));
},
child: Text('VIEW ALL >', style: TextStyle(decoration: TextDecoration.underline, color: Colors.redAccent),),
)
],
),
),
Container(
height: 120,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(2.0),
child: InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => SubCategoriesScreen(snapshot.data[index].id,snapshot.data[index].title)));
},
child: Container(
width: 100,
child: ListTile(
title: Image.network(
snapshot.data[index].image,
height: 60,
width: 100,
),
subtitle: Container(
alignment: Alignment.topCenter,
child: Text(
snapshot.data[index].title,
style: TextStyle(fontSize: 10),
)),
),
),
),
);
// return Text(snapshot.data[index].id);
}),
),
],
);
}
},
),
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 250.0,
mainAxisSpacing: 0.0,
crossAxisSpacing: 0.0,
childAspectRatio: 0.7,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return GestureDetector(
onTap: () {
print(data[index]['adid']);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProductDetailsScreen(data[index]['adid'])));
},
child: Container(
margin: EdgeInsets.all(5),
decoration:
BoxDecoration(border: Border.all(color: Colors.grey)),
child: Padding(
padding: const EdgeInsets.all(10),
child: Column(
children: <Widget>[
Expanded(
flex: 5,
child: Align(
alignment: Alignment.center,
child: Image.network(
data[index]['adcoverimg'],
fit: BoxFit.cover,
),
),
),
SizedBox(
height: 10,
),
Expanded(
flex: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'\u20B9' + data[index]['ads_price'],
style: TextStyle(fontWeight: FontWeight.bold),
),
Text(
data[index]['adname'],
style: TextStyle(fontWeight: FontWeight.w500),
maxLines: 1,
),
Text(
data[index]['addesc'],
maxLines: 1,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Icon(
Icons.location_on,
size: 18,
),
Text(data[index]['ads_location'])
],
)
],
),
)
],
),
),
),
);
},
childCount: data == null ? 0 : data.length,
),
),
],
),
),
);
}
And this is how I'm fetching the data from the server
Future<String> getProducts() async {
String url = Constant.productsUrl;
Map<String, String> headers = {'Content-Type': 'application/json'};
final response = await http.get(url, headers: headers);
setState(() {
var jsonResponse = json.decode(response.body);
data = jsonResponse['record'];
});
}
And this is my URL http://url.com/Web_Api/viewads/startindex/limit/cityname

How can I view the details of an item in a detailed screen - Flutter

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])));

Flutter two levels tabs issue

I created a layout with two levels of tabs. The layout looks fine, but clicking on the second level (the Follower tab) tab, it doesn't work and it actives the Favourites tab.
I created a layout with two levels of tabs. The layout looks fine, but clicking on the second level (the Follower tab) tab, it doesn't work and it actives the Favourites tab.
new Container(
decoration: new BoxDecoration(color: Colors.pinkAccent),
child: new TabBar(
controller: _controller,
tabs: [
new Tab(
text: 'Favorites',
),
new Tab(
text: 'Follows',
),
],
),
),
new Expanded(
child: new TabBarView(
controller: _controller,
children: <Widget>[
new Container(
child: buildGrid(context, Posts),
),
new Container(
child: new Column(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
color: Colors.grey),
child: new TabBar(
controller: tabController,
tabs: [
new Tab(
text: 'Follower',
),
new Tab(
text: 'Following',
),
],
),
),
new Expanded(
child: new TabBarView(
controller: tabController,
children: <Widget>[
new ListView.builder(
itemCount: followerList.length,
itemBuilder: (context, index) {
return Container(
padding: EdgeInsets.only(
left: 10.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
new Row(
children: <Widget>[
new HeroProfile(
followerList[
index]
[
"userID"]),
new Container(
padding:
new EdgeInsets
.only(
left:
10.0),
),
new Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <
Widget>[
new Text(
followerList[
index]
[
'userName'],
style: new TextStyle(
fontFamily: 'Ubuntu',
letterSpacing: 0.5,
// fontWeight: FontWeight.bold,
fontSize: 13.0,
color: Colors.black),
),
new Container(
padding: new EdgeInsets
.only(
bottom:
5.0),
),
new Text(
followerList[
index]
[
'country'],
style: new TextStyle(
fontFamily: 'Ubuntu',
letterSpacing: 0.5,
// fontWeight: FontWeight.bold,
fontSize: 13.0,
color: Colors.lightBlue),
),
],
)
]),
new Divider(),
],
),
);
},
),
new ListView.builder(
itemCount: followerList.length,
itemBuilder: (context, index) {
return Container(
padding: EdgeInsets.only(
left: 10.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <Widget>[
new Row(
children: <Widget>[
new HeroProfile(
followerList[
index]
[
"userID"]),
new Container(
padding:
new EdgeInsets
.only(
left:
10.0),
),
new Column(
crossAxisAlignment:
CrossAxisAlignment
.start,
children: <
Widget>[
new Text(
followerList[
index]
[
'userName'],
style: new TextStyle(
fontFamily: 'Ubuntu',
letterSpacing: 0.5,
fontSize: 13.0,
color: Colors.black),
),
new Container(
padding: new EdgeInsets
.only(
bottom:
5.0),
),
new Text(
followerList[
index]
[
'country'],
style: new TextStyle(
fontFamily: 'Ubuntu',
letterSpacing: 0.5,
fontSize: 13.0,
color: Colors.lightBlue),
),
],
)
]),
new Divider(),
],
),
);
},
),
])),
],
),
)
],
),
),