如何通过单击 "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参数中插入代码。

如果您遇到错误,请告诉我。