flutter集团/州管理的问题 - 如何通过页面之间的对象?

发布于 2025-01-18 03:26:32 字数 6989 浏览 2 评论 0原文

我的实习老板要求我解决一个我目前无法解决的问题。 我已经收到一份现成的申请。这基本上是受宠若惊的考勤应用程序。

现在让我清楚地告诉你我面临的问题在哪里。当用户单击学生按钮时,它会将学生带到班级页面,并且在班级承诺中用户或学生必须通过 onTap 事件选择班级 -一个人点击并选择了班级。您,用户,转到另一个页面,用户需要再次点击才能最终进入签入页面 - 意味着另一个 OnTap 事件。/

现在我的老板想摆脱这两个OnTap 事件发生在其间。He想让我直接从学生按钮成长到学生项目页面,而不丢失所传递的对象的内容。请注意,我在这里只展示了重要的代码,废弃了 UI 代码,因为它会变得很长。请看看您是否能理解这些代码。

该应用程序使用块/状态管理系统。

学生按钮-从这里开始流程(这里仅重要代码)

final User user;
SelectUser({this.user});


Expanded(
 child: GestureDetector(
   onTap: () {
     final ClassroomRepository classroomRepository =
         ClassroomRepository(
       classroomApiClient: ClassroomApiClient(
         httpClient: http.Client(),
       ),
     );
     Navigator.push(
         context,
         MaterialPageRoute(
             builder: (context) => BlocProvider(
                   create: (context) => ClassroomBloc(
                       classroomRepository: classroomRepository),
                   child: ClassList(user: this.user),//user object is passed to the ClassList

                 )));

   },
   child: Image.asset('assets/logos/studentbutton.png'),
 )

上面是将用户对象传递给ClassList。下面是ClassList的完整代码:

class ClassList extends StatelessWidget {
 final User user ;
 ClassList({this.user});
 @override
 Widget build(BuildContext context) {
   return Scaffold(

       body: Center(
         child: BlocBuilder<ClassroomBloc, ClassroomState>(
           builder: (context, state) {
             if (state is ClassroomEmpty) {
               print('load');
               BlocProvider.of<ClassroomBloc>(context)
                   .add(FetchClassroom(schoolId: this.user.id));
               return Center(child: Text('Please Wait'));
             } else if (state is ClassroomLoading) {
               return Center(child: CircularProgressIndicator());
             } else if (state is ClassroomLoaded) {
               final classrooms = state.classrooms;
               return ListView.builder(
                 itemCount: classrooms.length,
                 itemBuilder: (context, position) {
                   return ClassItem(classroom: classrooms[position]);//GENERATES UI WITH ONTAP EVENT IN THE NEXT PAGE.
                 },
               );
             } else {
               return Text(
                 'Something went wrong!',
                 style: TextStyle(color: Colors.red),
               );
             }
           },
         ),
       ));
 }
}

现在,它会去Class ItemPage执行第一次onTap。您可以在上面的代码中看到(return ClassItem(classroom:classrooms [position])从repo传递教室对象)

下面是Class Item Page的完整代码。在这里,我试图摆脱这个点击按钮,而不丢失已通过但反复失败的对象的内容。

import 'package:attendanceapp/blocs/student/blocs.dart';
import 'package:attendanceapp/repositories/student/repositories.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:attendanceapp/models/classroom.dart';
import 'package:attendanceapp/widgets/student/student.dart';
class ClassItem extends StatelessWidget {
 final Classroom classroom ;
 ClassItem({this.classroom});

 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: (){
       final VisitorRepository studentRepository = VisitorRepository(
         visitorApiClient: StudentApiClient(
           httpClient: http.Client(),
         ),
       );
       Navigator.push(context,
           MaterialPageRoute(builder: (context) =>
               BlocProvider(
                 create: (context) => StudentBloc(studentRepository:studentRepository),
                 child: Student(classroom: classroom),

               )
           )
       );
     },//tapping on the card
     child: Card(
         margin: EdgeInsets.all(20),
     child: Padding(
     padding: const EdgeInsets.all(20.0),
     child: Text(classroom.classroomName,style: TextStyle(fontSize: 30))
     )
     ),
   );
 }
}









From ClassItem Page , we go to the StudentPage passing ClassRooms as object.//Shows the Appbar and generates UI by returning the next page. Now this is the Page I don’t want to show but only pass the objects.



class Student extends StatelessWidget {
 final Classroom classroom ;
  Student({this.classroom});
 @override
 Widget build(BuildContext context) {

   return Scaffold(
       appBar: new AppBar(
         backgroundColor: Colors.amber[600],
         title: Text(classroom.classroomName),
       ),
       body:
       Center(

         child: BlocBuilder<StudentBloc, StudentState>(
           builder: (context, state) {
             if (state is StudentEmpty) {
               print(this.classroom);
               BlocProvider.of<StudentBloc>(context).add(FetchStudent(classId: this.classroom.id));
               return Center(child: Text('Please Wait'));
             } else if (state is StudentLoading) {
               return Center(child: CircularProgressIndicator());
             } else if (state is StudentLoaded) {
               final students = state.students;
               return ListView.builder(
                 itemCount: students.length,
                 itemBuilder: (context, position) {
                   return StudentItem(student:students[position], classroom: classroom,);
                 },
               );


             } else {
               return Text(
                 'Something went wrong!',
                 style: TextStyle(color: Colors.red),
               );
             }
           },
         ),
       ));
 }
}

最后,我们从 StudentButton 页面转到 StudeDetails 页面。下面是我想删除的 StudentItem 页面中的第二个 onTap。但失败了……我想从学生按钮页面转到学生项目页面,而不需要两个 OnTap 事件并且不丢失对象的内容。我已经尝试了7天,但失败了。我告诉我的实习老板这是可能的,因为每个学生都有一个课程,但他说无论如何都可以。

下面是我们在上一页中讨论的下一页。 我只需要显示从 StudentButton 开始的 StudentDetails 页面,而不执行两个 onTaps。我已经为此苦苦挣扎了大约7天,但仍然无法从studentButton转到studentDetails页面,跳过间歇性页面。

class StudentItem extends StatelessWidget {
 final Student student;
 final Classroom classroom;
 StudentItem({this.student, this.classroom});

 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: () {
       final StudentAttendanceRepository attendanceRepository =
           StudentAttendanceRepository(
         studentAttendanceClient: StudentAttendanceClient(
           httpClient: http.Client(),
         ),
       );
       Navigator.push(
           context,
           MaterialPageRoute(
             settings: RouteSettings(name: '/studentDetail'),
             builder: (context) => BlocProvider(
               create: (context) => StudentAttendanceBloc(studentAttendanceRepository: attendanceRepository),
               child: StudentDetail(student: student,),
             ),
           ),
       ).then((value){
         if(value){
           BlocProvider.of<StudentBloc>(context).add(FetchStudent(classId: this.classroom.id));
         }
       });
     },

////UI CODES HERE…NOT PASTED HERE BECAUSE TOO LONG
    }

My internship boss asked me to solve a problem which I am not being able to do so far.
I have been given an ready application. This is basically flattered attendance app.

Now let me tell you clearly where I'm facing the issue.When the user click the student button,It takes the student to a class page,And in the class pledge the user or the student has to select the class by onTap event-One tapped and selected the class.the You, the user, goes to another page where the user will need to tap again to finally go to the check in Page-meaing another OnTap event./

Now my boss wants to get rid of the two OnTap events in the in between.He wants me to directly grow from student button to Student Item Page without losing the contents of the object that was passed. Please note I just show the important codes here scrapping the UI codes because it will become long.Please see if you can understand the codes.

The app uses bloc/statemanagement system.

Student Button-From here starts the flow(only important codes here)

final User user;
SelectUser({this.user});


Expanded(
 child: GestureDetector(
   onTap: () {
     final ClassroomRepository classroomRepository =
         ClassroomRepository(
       classroomApiClient: ClassroomApiClient(
         httpClient: http.Client(),
       ),
     );
     Navigator.push(
         context,
         MaterialPageRoute(
             builder: (context) => BlocProvider(
                   create: (context) => ClassroomBloc(
                       classroomRepository: classroomRepository),
                   child: ClassList(user: this.user),//user object is passed to the ClassList

                 )));

   },
   child: Image.asset('assets/logos/studentbutton.png'),
 )

The above is passing the user object to ClassList. Below is the full code for ClassList:

class ClassList extends StatelessWidget {
 final User user ;
 ClassList({this.user});
 @override
 Widget build(BuildContext context) {
   return Scaffold(

       body: Center(
         child: BlocBuilder<ClassroomBloc, ClassroomState>(
           builder: (context, state) {
             if (state is ClassroomEmpty) {
               print('load');
               BlocProvider.of<ClassroomBloc>(context)
                   .add(FetchClassroom(schoolId: this.user.id));
               return Center(child: Text('Please Wait'));
             } else if (state is ClassroomLoading) {
               return Center(child: CircularProgressIndicator());
             } else if (state is ClassroomLoaded) {
               final classrooms = state.classrooms;
               return ListView.builder(
                 itemCount: classrooms.length,
                 itemBuilder: (context, position) {
                   return ClassItem(classroom: classrooms[position]);//GENERATES UI WITH ONTAP EVENT IN THE NEXT PAGE.
                 },
               );
             } else {
               return Text(
                 'Something went wrong!',
                 style: TextStyle(color: Colors.red),
               );
             }
           },
         ),
       ));
 }
}

Now , it will go to Class ItemPage to perform the first onTap. You can see in the above code(return ClassItem(classroom: classrooms[position]) passing classroom object from repo)

Below is the full code for Class Item Page. HERE , I AM TRYING TO GET RID OF THIS ON TAP BUTTON WITHOUT LOSING THE CONTENT OF THE OBJECT THAT IS PASSED BUT FAILED REPEATEDLY.

import 'package:attendanceapp/blocs/student/blocs.dart';
import 'package:attendanceapp/repositories/student/repositories.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:attendanceapp/models/classroom.dart';
import 'package:attendanceapp/widgets/student/student.dart';
class ClassItem extends StatelessWidget {
 final Classroom classroom ;
 ClassItem({this.classroom});

 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: (){
       final VisitorRepository studentRepository = VisitorRepository(
         visitorApiClient: StudentApiClient(
           httpClient: http.Client(),
         ),
       );
       Navigator.push(context,
           MaterialPageRoute(builder: (context) =>
               BlocProvider(
                 create: (context) => StudentBloc(studentRepository:studentRepository),
                 child: Student(classroom: classroom),

               )
           )
       );
     },//tapping on the card
     child: Card(
         margin: EdgeInsets.all(20),
     child: Padding(
     padding: const EdgeInsets.all(20.0),
     child: Text(classroom.classroomName,style: TextStyle(fontSize: 30))
     )
     ),
   );
 }
}









From ClassItem Page , we go to the StudentPage passing ClassRooms as object.//Shows the Appbar and generates UI by returning the next page. Now this is the Page I don’t want to show but only pass the objects.



class Student extends StatelessWidget {
 final Classroom classroom ;
  Student({this.classroom});
 @override
 Widget build(BuildContext context) {

   return Scaffold(
       appBar: new AppBar(
         backgroundColor: Colors.amber[600],
         title: Text(classroom.classroomName),
       ),
       body:
       Center(

         child: BlocBuilder<StudentBloc, StudentState>(
           builder: (context, state) {
             if (state is StudentEmpty) {
               print(this.classroom);
               BlocProvider.of<StudentBloc>(context).add(FetchStudent(classId: this.classroom.id));
               return Center(child: Text('Please Wait'));
             } else if (state is StudentLoading) {
               return Center(child: CircularProgressIndicator());
             } else if (state is StudentLoaded) {
               final students = state.students;
               return ListView.builder(
                 itemCount: students.length,
                 itemBuilder: (context, position) {
                   return StudentItem(student:students[position], classroom: classroom,);
                 },
               );


             } else {
               return Text(
                 'Something went wrong!',
                 style: TextStyle(color: Colors.red),
               );
             }
           },
         ),
       ));
 }
}

Finally, we go from StudentButton Page to StudeDetails Page. Below IS THE SECOND onTap in the studentItem page which I want to get rid. But failed …I want to go From Student Button Page to STUDENT ITEM PAGE without two OnTap evens and Not losing the content of the object. I have been trying for 7 days,but failed. I told my internship boss it is possible because each student has a class but he said do it any how.

Below is the next page we were talking about in the previous page.
I just need to show StudentDetails page starting from studentButton without performing the two onTaps. I have struggling with this for about 7 days, but still couldn’t go from studentButton to studentDetails page skipping the intermittent pages.

class StudentItem extends StatelessWidget {
 final Student student;
 final Classroom classroom;
 StudentItem({this.student, this.classroom});

 @override
 Widget build(BuildContext context) {
   return GestureDetector(
     onTap: () {
       final StudentAttendanceRepository attendanceRepository =
           StudentAttendanceRepository(
         studentAttendanceClient: StudentAttendanceClient(
           httpClient: http.Client(),
         ),
       );
       Navigator.push(
           context,
           MaterialPageRoute(
             settings: RouteSettings(name: '/studentDetail'),
             builder: (context) => BlocProvider(
               create: (context) => StudentAttendanceBloc(studentAttendanceRepository: attendanceRepository),
               child: StudentDetail(student: student,),
             ),
           ),
       ).then((value){
         if(value){
           BlocProvider.of<StudentBloc>(context).add(FetchStudent(classId: this.classroom.id));
         }
       });
     },

////UI CODES HERE…NOT PASTED HERE BECAUSE TOO LONG
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山人契 2025-01-25 03:26:32

因此,要访问不同页面上的数据,您可以将数据传递到第1页,然后在集团中将数据传递给您的事件,您可以将此数据分配给州类之一。现在,在第2页或第3页,无论您要访问数据的地方,都可以使用bloclistener或blocbuilder,并使用状态对象访问数据。

So to access the data on different pages, you can pass the data to your event from page 1 and then in the bloc, you can assign this data to one of the state class. Now on page 2 or page 3, wherever you want to access the data, you can use BlocListener or BlocBuilder and access the data using the state object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文