如何通过单击 "NEXT" 按钮切换到另一名员工?以及如何在 PageView.builder 之后添加页面?
How do I switch to another employee by clicking on the "NEXT" button? And how do I add a page after PageView.builder?
我有员工,他们的图像、姓名和电子邮件以 pageView 形式显示“员工人数取决于 JSON API 的 Http 查询。”
我想通过单击“下一步”按钮从一名员工切换到另一名员工。
另外,我想在查看所有PageViews员工后添加一个页面。
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),),
),
),
),
),
),
],
),
),
],
),
),
],
);
},
);
},
),
);
}
}
编辑 2: 更改了代码。
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),),
),
),
),
),
),
],
),
),
],
),
);
}
}
编辑 1: 在您更改代码后我意识到您的错误。
这就是 PageView 小部件的工作原理
PageView(
controller: _controller,
children: [
MyPage1Widget(),
MyPage2Widget(),
MyPage3Widget(),
],
)
在这里,您在 PageView 的子级中提供 3 个屏幕,并要求页面视图在 _controller.jumpToPage()
或 _controller.next()
时转到下一个屏幕打电话。
但是在您的代码中,您在 PageView 小部件子项中提供了一个容器,因此只有一个屏幕可以显示。这就是为什么您看不到任何更改的原因。
上一个答案:
你需要的是PageViewController,通过它你可以jump/animate到任何页面。
第 1 步: 实例化页面视图控制器
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(
initialPage: 0,
);
第 2 步:在 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,
),
),
.....
第 3 步:点击按钮时更改页面视图
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
}
}
上面给出的是OnTapped函数,您可以将Text widget包裹在一个Button中,然后在ontapped参数中插入代码。
如果您遇到错误,请告诉我。
我有员工,他们的图像、姓名和电子邮件以 pageView 形式显示“员工人数取决于 JSON API 的 Http 查询。” 我想通过单击“下一步”按钮从一名员工切换到另一名员工。 另外,我想在查看所有PageViews员工后添加一个页面。
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),),
),
),
),
),
),
],
),
),
],
),
),
],
);
},
);
},
),
);
}
}
编辑 2: 更改了代码。
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),),
),
),
),
),
),
],
),
),
],
),
);
}
}
编辑 1: 在您更改代码后我意识到您的错误。
这就是 PageView 小部件的工作原理
PageView(
controller: _controller,
children: [
MyPage1Widget(),
MyPage2Widget(),
MyPage3Widget(),
],
)
在这里,您在 PageView 的子级中提供 3 个屏幕,并要求页面视图在 _controller.jumpToPage()
或 _controller.next()
时转到下一个屏幕打电话。
但是在您的代码中,您在 PageView 小部件子项中提供了一个容器,因此只有一个屏幕可以显示。这就是为什么您看不到任何更改的原因。
上一个答案:
你需要的是PageViewController,通过它你可以jump/animate到任何页面。
第 1 步: 实例化页面视图控制器
class _EmployeesState extends State<Employees> {
PageController _controller = PageController(
initialPage: 0,
);
第 2 步:在 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,
),
),
.....
第 3 步:点击按钮时更改页面视图
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
}
}
上面给出的是OnTapped函数,您可以将Text widget包裹在一个Button中,然后在ontapped参数中插入代码。
如果您遇到错误,请告诉我。