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.