How to send arguments to another screen? Flutter - json

I am trying to send the arguments of a "participant" to another screen, I could do it with a ListView and load the list of events, but it is not working in the same way with the participants, now if the list works, but when I tap and I want to see the info of the "participant" everything comes out in null:
In this part I create the participant and generate the list to be able to visualize it, and by giving the tap I send the info of this (according to me)
Widget _crearListadoParticipantes() {
return FutureBuilder<List<Participantes>>(
future: eventosProvider.cargarParticipantes(evento, participantes),
builder: (context, snapshot) {
if ( snapshot.hasData ) {
final participantes = snapshot.data;
return ListView.builder(
itemCount: participantes.length,
itemBuilder: (context, i) {
return _crearParticipante(context, participantes[i], evento);
}
);
} else if (snapshot.hasError){
return Center(child: Text("${snapshot.error}"));
} else {
return Center( child: CircularProgressIndicator());
}
},
);
}
Widget _crearParticipante(BuildContext context, Participantes participantes, EventoModel evento) {
return Padding(
padding: EdgeInsets.all(12.0),
child: GestureDetector(
child: RichText(
softWrap: false,
text: TextSpan(
style: TextStyle(
color: Colors.black,
fontFamily: "Lato_LightItalic",
fontStyle: FontStyle.italic,
fontSize: 20.0,
fontWeight: FontWeight.w400
),
children: [
TextSpan(text: ' '+'${participantes.numero}',
style: TextStyle(
fontWeight: FontWeight.w600
)
),
TextSpan(text: " "),
TextSpan(text: '${participantes.apellido} ${participantes.nombre}',)
],
),
),
onTap: () => Navigator.pushNamed(context, 'destalleParticipante', arguments: evento),
),
);
}
And this is where I am supposed to receive the arguments of the participant to whom I tapped, but as I say, a null returns
class DetalleParticipante extends StatefulWidget {
#override
_DetalleParticipanteState createState() => _DetalleParticipanteState();
}
class _DetalleParticipanteState extends State<DetalleParticipante> {
final eventosProvider = new EventosProvider();
EventoModel evento = new EventoModel();
Participantes participantes = new Participantes();
#override
Widget build(BuildContext context) {
final EventoModel eventoData = ModalRoute.of(context).settings.arguments;
if ( eventoData != null ) {
evento = eventoData;
}
print(participantes.nombre);
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(0),
child: AppBar(
backgroundColor: Color(0xFF249FE2),
),
),
backgroundColor: Colors.white,
body: Container(
color: Colors.white,
child: Column(
children: <Widget>[
_encabezadoParticipante(context, AssetImage("assets/icon/info_corredor.png"), participantes, evento),
],
),
),
);
}
Widget _backBottom() {
return FloatingActionButton(
elevation: 0.0,
backgroundColor: Colors.white,
child: Icon(
Icons.arrow_back,
size: 45.0,
color: Colors.black,
),
onPressed: (){
Navigator.pop(context);
},
);
}
Widget _encabezadoParticipante(BuildContext context, AssetImage image, Participantes participantes, EventoModel evento) {
return Container(
color: Colors.grey[600],
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_backBottom(),
Flexible(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Text('${participantes.apellido}',
textAlign: TextAlign.center,
maxLines: 3,
softWrap: true,
style: TextStyle(
color: Colors.white,
fontFamily: "Lato",
fontStyle: FontStyle.italic,
fontSize: 30.0,
fontWeight: FontWeight.bold
),
),
),
),
Image(image: image,
fit: BoxFit.cover,
),
],
),
),
);
}
}

Related

Flutter: how integrate function in the "DropdownButton" class and pass value to the parent class

I am trying to integrate a child class (implementing DropdownButton with four values: 2, 4, 6, and 8) to a parent class which should show some content depending on the value chosen.
If user clicks on one of the drop down values ie: 2, a widget on the main class should display a container with blue colour. If user click on value 4 it should display a container with red colour and so on.
My thoughts went along these lines, implementing a simple method which is reading chosen value, calls the appropriate class (ClassTwo, ClassThree...) passing its content to the parent class but I am not sure how to do so. My renderWidget() function remains unused and fuller suggesting removing it.
Can anyone please help?
child class (DropdownMenuButton)
class VorschlageDropdownMenu extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<VorschlageDropdownMenu> {
List<ListItem> _dropdownItems = [
ListItem(1, "2"),
ListItem(2, "4"),
ListItem(3, "6"),
ListItem(4, "8"),
];
List<DropdownMenuItem<ListItem>> _dropdownMenuItems;
ListItem _selectedItem;
void initState() {
super.initState();
_dropdownMenuItems = buildDropDownMenuItems(_dropdownItems);
_selectedItem = _dropdownMenuItems[0].value;
}
List<DropdownMenuItem<ListItem>> buildDropDownMenuItems(List listItems) {
List<DropdownMenuItem<ListItem>> items = List();
for (ListItem listItem in listItems) {
items.add(
DropdownMenuItem(
child: Text(listItem.name),
value: listItem,
),
);
}
return items;
}
#override
Widget build(BuildContext context) {
return SizedBox(
child: Container(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: kWidgetBacgroundColor,
border: Border.all()),
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: _selectedItem,
items: _dropdownMenuItems,
onChanged: (value) {
setState(() {
_selectedItem = value;
renderWidget() {
if (value == "2")
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MenuForZwei(),
),
);
else if (value == "4")
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MenuForVier(),
),
);
else if (value == "6")
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MenuForSechs(),
),
);
else if (value == "8")
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => MenuForAcht(),
),
);
}
});
}),
),
),
);
}
}
class ListItem {
int value;
String name;
ListItem(this.value, this.name);
}
parental class which should display value chosen
class VorschlageZutaten extends StatelessWidget {
const VorschlageZutaten({
Key key,
this.renderWidget,
}) : super(key: key);
final Function renderWidget;
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 50, top: 20),
),
Text(
"Für ",
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (20.0),
fontWeight: FontWeight.w600,
),
),
Container(height: 40, child: VorschlageDropdownMenu()),
Text(
" Personen:",
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (20.0),
fontWeight: FontWeight.w600,
),
),
],
),
Container(
child: renderWidget(),
),
],
);
}
}
I think I've read all available documentation and reviewed all examples so I had to redesign the VorschlageDropdownMenu() class in order to achieve desired result. This is how the main class looks now:
class VorschlageDropdownMenu extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _VorschlageDropdownMenuState();
}
}
class _VorschlageDropdownMenuState extends State<VorschlageDropdownMenu> {
String ddValue;
#override
void initState() {
super.initState();
ddValue = "ZWEI";
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50.0),
child: AppBar(
elevation: 0,
backgroundColor: kWidgetBacgroundColor,
title: Column(
children: <Widget>[
Row(
children: <Widget>[
Text(
"Für ",
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (20.0),
fontWeight: FontWeight.w600,
),
),
Container(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: kWidgetBacgroundColor,
border: Border.all()),
child: DropdownButtonHideUnderline(
child: new DropdownButton(
iconSize: 0.0,
value: ddValue, //Default value
items: <DropdownMenuItem>[
new DropdownMenuItem(
value: "ZWEI",
child: new Text(
'ZWEI',
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (17.0),
fontWeight: FontWeight.w700,
),
),
),
new DropdownMenuItem(
value: "VIER",
child: new Text('VIER',
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (17.0),
fontWeight: FontWeight.w700,
),
),
),
new DropdownMenuItem(
value: "SECHS",
child: new Text('SECHS',
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (17.0),
fontWeight: FontWeight.w700,
),
),
),
new DropdownMenuItem(
value: "ACHT",
child: new Text('ACHT',
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (17.0),
fontWeight: FontWeight.w700,
),
),
),
],
onChanged: (value) {
ddValue = value;
setState(() {});
},
),
),
),
Text(
" Personen:",
style: TextStyle(
color: kPrimaryHeaderColor.withOpacity(0.6),
fontSize: (20.0),
fontWeight: FontWeight.w600,
),
),
],
),
],
),
),
),
body: ListederMenus(),
);
}
Widget ListederMenus() {
if (ddValue == "ZWEI") {
return Center(child: MenuForZwei());
} else if (ddValue == "VIER") {
return Center(child: MenuForVier());
} else if (ddValue == "SECHS") {
return Center(child: MenuForSechs());
} else if (ddValue == "ACHT") {
return Center(child: MenuForAcht());
}
}
}```
and **MenuForZwei()** and other classes with different colours:
```class MenuForZwei extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
);
}
}```

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.

Flutter i want to display the data after searching

listviewGood day do you have an idea on how to make a search bar that do not show first the list view when no one searching my data is from mysql sorry new at flutter
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Transaction'),
backgroundColor: Color(0xff083663),
),
body: RefreshIndicator(
onRefresh: fetchNotes,
key: _refresh,
child: loading
? Center(
child: CircularProgressIndicator(),
)
: ListView.builder(
itemBuilder: (context, i) {
return i == 0 ? _searchBar() : _listItem(i - 1);
},
itemCount: _notesForDisplay.length + 1,
),
));
}
This is my search bar where the user will input his/her search
_searchBar() {
return Container(
padding: const EdgeInsets.all(10.0),
child: Card(
child: ListTile(
leading: Icon(Icons.search),
title: TextField(
decoration:
InputDecoration(hintText: "Search", border: InputBorder.none),
onChanged: (text) {
text = text.toLowerCase();
setState(() {
_notesForDisplay = _notes.where((note) {
var noTitle = note.vesselname.toLowerCase();
return noTitle.contains(text);
}).toList();
});
},
),
),
),
);
}
this is the list view for my search i want this to show after the user inputted a value in the search bar
_listItem(i) {
final x = _notesForDisplay[i];
return Container(
padding: EdgeInsets.all(20.0),
child: Row(
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Vessel Name:\t' + x.vesselname,
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
),
Text('Voyage #:\t' + x.voyageno,
style: TextStyle(fontSize: 18.0)),
Text('Ship Call #:\t' + x.scn,
style: TextStyle(fontSize: 18.0)),
Divider()
],
),
),
IconButton(
icon: Icon(
Icons.add_circle_outline,
size: 30.0,
),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Transaction(x)));
}),
],
),
);
}
}
Define a bool variable that indicate the visibility state of the list view:
bool _isListViewVisible = false;
Add it to the setState code block:
setState(() {
_isListViewVisible = true; //Or you can check the text length
_notesForDisplay = _notes.where((note) {
var noTitle = note.vesselname.toLowerCase();
return noTitle.contains(text);
}).toList();
});
Then put the list in a visibility widget:
return Visibility(
visible: _isListViewVisible,
child: Container(
padding: EdgeInsets.all(20.0),
child: Row(
children: <Widget>[
....
],
),
));

How do I switch to another employee by clicking on the "NEXT" button? And how do I add a page after PageView.builder?

I have employees with their images, names, and emails displayed in pageView form "the number of employees depends on the Http query of the JSON API."
I want to switch from one employee to another by clicking on the "NEXT" button.
In addition, I would like to add a page after viewing all PageViews employees.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Employees(),
);
}
}
class Employees extends StatefulWidget {
#override
_EmployeesState createState() => _EmployeesState();
}
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(initialPage: 0,);
getEmployees()async{
String theUrl = 'http://demo8161595.mockable.io/employee';
var res = await http.get(Uri.encodeFull(theUrl),headers:{"Accept":"application/json"});
var responsBody = json.decode(res.body);
print(responsBody);
return responsBody;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title:Text("Employees") ,
),
body:FutureBuilder(
future: getEmployees(),
builder: (BuildContext context , AsyncSnapshot snapshot){
List snap = snapshot.data;
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
if(snapshot.hasError){
return Center(
child: Text("Error .... "),
);
}
return PageView.builder(
itemCount: snap.length,
itemBuilder: (context,index){
return PageView(
controller:_controller,
children: <Widget>[
Container(
padding: EdgeInsets.all(5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage("${snap[index]['avatar']}"),
backgroundColor: Colors.transparent,
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Name',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${snap[index]['firstName']}" + " " + "${snap[index]['lastName']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Email',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${snap[index]['email']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height:5.0),
Padding(
padding: EdgeInsets.all(5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
child: Center(
child:Container(
child: RaisedButton.icon(
onPressed: () {
int page = _controller.page.toInt();
_controller.animateToPage(page + 1 , duration: Duration(milliseconds: 500),curve: Curves.ease,);
_controller.jumpToPage(page+1);
if(_controller.page.toInt() == snap.length)
{
Container(
child: Center(
child: Text("Last Page"),
),
);
}
},
color: Colors.teal,
icon: Icon(Icons.navigate_next,color:Colors.white ,),
label: Text("NEXT",style: TextStyle(color: Colors.white),),
),
),
),
),
),
],
),
),
],
),
),
],
);
},
);
},
),
);
}
}
EDIT 2: Changed the code.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Employees(),
);
}
}
class Employees extends StatefulWidget {
#override
_EmployeesState createState() => _EmployeesState();
}
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(initialPage: 0,);
getEmployees()async{
String theUrl = 'http://demo8161595.mockable.io/employee';
var res = await http.get(Uri.encodeFull(theUrl),headers:{"Accept":"application/json"});
var responsBody = json.decode(res.body);
print(responsBody);
return responsBody;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title:Text("Employees") ,
),
body:FutureBuilder(
future: getEmployees(),
builder: (BuildContext context , AsyncSnapshot snapshot){
List snap = snapshot.data;
if(snapshot.connectionState == ConnectionState.waiting){
return Center(
child: CircularProgressIndicator(),
);
}
if(snapshot.hasError){
return Center(
child: Text("Error .... "),
);
}
return PageView.builder(
itemCount: snap.length,
itemBuilder: (context,index){
return PageView(
controller:_controller,
children: snap.map((e) => employeePage(e,snap.length)).toList(),
);
},
);
},
),
);
}
Widget employeePage(node , length)
{
return Container(
padding: EdgeInsets.all(5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage("${node['avatar']}"),
backgroundColor: Colors.transparent,
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Name',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${node['firstName']}" + " " + "${node['lastName']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height: 10.0),
Padding(
padding: EdgeInsets.all(5.0),
child:Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Email',
style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold,),
),
SizedBox(height: 5.0),
Text("${node['email']}",style: TextStyle(fontSize: 20)),
],
),
),
SizedBox(height:5.0),
Padding(
padding: EdgeInsets.all(5.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20.0),
Center(
child: Container(
padding: const EdgeInsets.all(8.0),
child: Center(
child:Container(
child: RaisedButton.icon(
onPressed: () {
int page = _controller.page.toInt();
_controller.animateToPage(page + 1 , duration: Duration(milliseconds: 500),curve: Curves.ease,);
_controller.jumpToPage(page+1);
if(_controller.page.toInt() == length)
{
Container(
child: Center(
child: Text("Last Page"),
),
);
}
},
color: Colors.teal,
icon: Icon(Icons.navigate_next,color:Colors.white ,),
label: Text("NEXT",style: TextStyle(color: Colors.white),),
),
),
),
),
),
],
),
),
],
),
);
}
}
EDIT 1: After you have changed the code i have realized your mistake.
This is how the PageView widget works
PageView(
controller: _controller,
children: [
MyPage1Widget(),
MyPage2Widget(),
MyPage3Widget(),
],
)
Here you are providing 3 screens in the children of the PageView and asking page view to go to the next one when _controller.jumpToPage() or _controller.next() is called.
But in your code, in the PageView widget children you have provided a single container, so there is only one screen to show. Which is why you are not able to see any changes.
Previous Answer :
What you need is the PageViewController through which you can jump/animate to any page.
STEP 1 : instantiate the Page View Controller
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(
initialPage: 0,
);
STEP 2 : Add the Page View Controller in the PageView
return PageView(
controller:_controller
children: <Widget>[
Container(
padding: EdgeInsets.all(5.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Center(
child: CircleAvatar(
radius: 50.0,
backgroundImage:
NetworkImage("${snap[index]['avatar']}"),
backgroundColor: Colors.transparent,
),
),
.....
STEP 3 : Change the page view when button tapped
onTap: () {
//Current page
int page = _controller.page.toInt();
//Animate to page
_controller.animateToPage(page + 1);
//Jump to page
controller.animateToPage(page + 1);
//if page view reaches last page
if(controller.page.toInt() == snap.length)
{
//Navigate to some page
}
}
Given above is the OnTapped function, you can wrap the Text widget in a Button and insert the code in the ontapped parameter.
Let me know if you face errors.