Home > Software engineering >  How to get the index number outside of a listview.builder
How to get the index number outside of a listview.builder

Time:07-12

I have an application that will open a pdf file based on the selection from a listview. I want the title of the app bar on journal_view.dart to display the corresponding journalTitle of the selection from journal_data.dart.

import 'package:aplikasi_jurnal_mobile/models/journals.dart';

List<JournalModel> journal_list = [
  JournalModel(
    id: 'j1',
    journalTitle: 'Pembangunan Sistem Informasi Penjualan Obat Pada Apotek Punung', 
    journalReleaseYear: 2014, 
    author: "Tri Utami, Bambang Eka Purnama, Sukadi", 
    topic: "Kesehatan", 
    fileLocation: '44-83-2-PB.pdf',
  ),

  JournalModel(
    id: 'j2',
    journalTitle: 'Pembuatan Aplikasi Pembelajaran Bahasa Inggris Pada Handphone dengan J2ME', 
    journalReleaseYear: 2010, 
    author: "Yusni Nyura", 
    topic: "Pendidikan", 
    fileLocation: '66-204-1-PB.pdf',
  ),

I have a listview.builder that functions correctly on a seperate dart file. This is the sample of said code.

List<JournalModel> displayJournal = List.from(journal_list);

ListView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: displayJournal.length,
              itemBuilder: (context, int index) {

child: ListTile(
              onTap: ()async {
                final path = 'assets/${journal_list[index].fileLocation}';
                final file = await JournalAPI.loadAsset(path);
                openPDF(context, file);
              },

              title: Text(displayJournal[index].journalTitle!

})

However, i have no idea on how to access the index from said listview to journal_view.dart.

class _JournalViewerPageState extends State<JournalViewerPage>{
    int pages = 0;
    int indexPage = 0;

Widget build(BuildContext context) {
      final name = journal_list[index].journalTitle;
      final text = '${indexPage   1} of $pages';
    
    return Scaffold(
      appBar: AppBar(
        title: Text(name!),
        actions: pages >= 2
            ? [
                Center(child: Text(text)),
                IconButton(
                  icon: const Icon(Icons.chevron_left, size: 32),
                  onPressed: () {
                    final page = indexPage == 0 ? pages : indexPage - 1;
                    controller.setPage(page);
                  },
                ),
                IconButton(
                  icon: const Icon(Icons.chevron_right, size: 32),
                  onPressed: () {
                    final page = indexPage == pages - 1 ? 0 : indexPage   1;
                    controller.setPage(page);
                  },
                ),
              ]
            : null,
      ),
   );
 }
}

I've tried to define the index on class _JournalViewerPageState as

class _JournalViewerPageState extends State<JournalViewerPage>{
    int pages = 0;
    int indexPage = 0;
    int index = 0;

but that obviously would only grab the first item on the array. I also tried adding int index on widget build as Widget build(BuildContext context, int index), but it threw an error stating ('Widget Function(BuildContext, int)') isn't a valid override of 'State.build'.

Any help would be much appreciated, Thanks in advance.

CodePudding user response:

itemBuilder need a widget to return not a child property. you can assign that index value above return statement to another variable and use it for your own purposes.

ListView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: displayJournal.length,
              itemBuilder: (context, int index) {

return ListTile(
              onTap: ()async {
                final path = 'assets/${journal_list[index].fileLocation}';
                final file = await JournalAPI.loadAsset(path);
                openPDF(context, file);
              },

              title: Text(displayJournal[index].journalTitle!

})

CodePudding user response:

It seems that i have solved the problem, and it was probably a rookie mistake.

So basically, all i had to do was define journals in the listview as such (I changed the variable name journal_list to journals and JournalModel to Journal in the journal_model.dart file).

: ListView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: displayJournal.length,
              itemBuilder: (context, int index) {
                final journal = journals[index];

              child: ListTile(
              onTap: ()async {
                final path = 'assets/${journal.fileLocation}';
                final file = await JournalAPI.loadAsset(path);
                
                openPDF(context, file, journal);
              },

And in the navigator, i defined the selected journals as well

void openPDF(BuildContext context, File file, Journal journal) => Navigator.of(context).push( //Membuka viewer jurnal
    MaterialPageRoute(builder: (context) => JournalViewerPage(file: file, journal: journal))
    );

It was all a matter of calling it in the Journal_view.dart file

class JournalViewerPage extends StatefulWidget {
  final File file;
  final Journal journal;

  const JournalViewerPage({
    Key? key,
    required this.file, required this.journal
  }) : super(key: key);

  @override
  _JournalViewerPageState createState() => _JournalViewerPageState();
  }

  class _JournalViewerPageState extends State<JournalViewerPage>{
    late PDFViewController controller;

    int pages = 0;
    int indexPage = 0;

    @override
    Widget build(BuildContext context) {

      final name = widget.journal.journalTitle;
      final text = '${indexPage   1} of $pages';
    
    return Scaffold(
      appBar: AppBar(
        title: Text(name),

I'm a bit new to flutter so sorry if my explanation isn't too comprehensive or my question wasn't worded properly.

  • Related