'How can I navigate to next list item on a new page?
I have a list that I fetch from a provider file and display using ListView builder. The LIST page displays only the title of the item on the list and clicking on this title opens a new DETAIL with other related data.
I have created a button on the detail page that is supposed to navigate to the next item on the list to show its details too, but I have had a challenge implementing this.
I need help with this, please. Thanks in advance.
Here is the listview widget
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '/providers/lessons/lessons_provider.dart';
import '../lessons/lesson_item.dart';
class LessonGrid extends StatelessWidget {
const LessonGrid({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final subjectId = ModalRoute.of(context)!.settings.arguments as String;
final lessonData = Provider.of<LessonsProvider>(context);
final lessons = lessonData.lessons;
return ListView.builder(
padding: const EdgeInsets.all(10.0),
itemCount: lessons.length,
itemBuilder: (ctx, i) => ChangeNotifierProvider.value(
value: lessons[i],
child: LessonItem(),
),
);
}
}
This is the LessonItem widget
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '/providers/lessons/lesson.dart';
import '/providers/subjects/subject.dart';
import '/screens/lesson_detail_screen.dart';
class LessonItem extends StatelessWidget {
const LessonItem({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final subjectData = Provider.of<Subject>(context);
final lesson = Provider.of<Lesson>(context);
return GridTile(
child: GestureDetector(
onTap: () {
Navigator.of(context).pushNamed(
LessonDetailScreen.routeName,
arguments: lesson.id,
);
},
child: Card(
color: lesson.isCompleted! ? Color.fromARGB(255, 186, 247, 217) : null,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(lesson.title!, style: TextStyle(fontSize: 17, )),
),
),
),
);
}
}
This is the LessonDetailScreen
import 'package:classhall_app/providers/lessons/lesson.dart';
import 'package:flutter/material.dart';
import 'package:chewie/chewie.dart';
import 'package:provider/provider.dart';
import 'package:video_player/video_player.dart';
import '../providers/lessons/lessons_provider.dart';
class LessonDetailScreen extends StatefulWidget {
static const routeName = '/lesson-detail';
@override
State<LessonDetailScreen> createState() => _LessonDetailScreenState();
}
class _LessonDetailScreenState extends State<LessonDetailScreen> {
late VideoPlayerController _videoPlayerController;
late ChewieController _chewieController;
@override
initState() {
super.initState();
_videoPlayerController = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4');
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
aspectRatio: 1,
autoInitialize: true,
allowFullScreen: true,
placeholder: Container(
color: Colors.grey,
),
// The Full Screen has an issue. Will implement it once it's resolved
// fullScreenByDefault: true,
looping: false,
);
}
@override
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
}
@override
Widget build(BuildContext context) {
final lessonId = ModalRoute.of(context)!.settings.arguments as String;
var loadedLesson =
Provider.of<LessonsProvider>(context).findById(lessonId);
final lessons = Provider.of<LessonsProvider>(context);
var lesson = Provider.of<Lesson>(context);
bool _showMore = true;
void goToNextLesson() {
int currentIndex = lessons.lessons.indexOf(lesson);
var nextLesson = lessons.lessons[currentIndex + 1];
lesson = nextLesson;
}
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
title: Text('${loadedLesson.title}'),
expandedHeight: 220,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: SafeArea(
child: Chewie(
controller: ChewieController(
videoPlayerController: _videoPlayerController,
),
),
),
),
),
SliverList(
delegate: SliverChildListDelegate([
SizedBox(
height: 5,
),
Column(
children: [
Container(
padding: const EdgeInsets.only(top: 2.0, bottom: 8.0),
child: const Text(
'Lesson Summary',
style: TextStyle(fontSize: 20),
),
),
Container(
width: double.infinity,
color: Color.fromARGB(255, 157, 197, 245),
padding: const EdgeInsets.all(8.0),
child: Text(
'${loadedLesson.summary}',
style: TextStyle(
fontSize: 20,
color: Colors.black54,
),
textAlign: TextAlign.left,
),
),
],
),
Column(
children: [
Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
child: ExpansionTile(
tilePadding: EdgeInsets.all(-10),
title: Text(
'Full Lesson',
style: TextStyle(fontSize: 20),
),
children: [
Text(
'${loadedLesson.content}',
style: TextStyle(
fontSize: 18,
color: Color.fromARGB(136, 17, 17, 17)),
textAlign: TextAlign.left,
softWrap: true,
),
]),
),
Row(
children: [
TextButton.icon(
label: Text('Attempt Quiz', style: TextStyle(fontSize: 20),),
style: ButtonStyle(),
onPressed: null,
icon: Icon(Icons.quiz, size: 50, color: Colors.red,),
),
TextButton.icon(
label: Text('Next Lesson', style: TextStyle(fontSize: 20),),
style: ButtonStyle(),
onPressed: goToNextLesson,
icon: Icon(Icons.arrow_forward, size: 50, color: Colors.green,),
),
],
)
],
),
SizedBox(
height: 800,
),
]),
),
],
),
);
}
}
I tried to use the following function to move to the next list item, but it is not working
void goToNextLesson() {
int currentIndex = lessons.lessons.indexOf(lesson);
var nextLesson = lessons.lessons[currentIndex + 1];
lesson = nextLesson;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
