Mubarak B
Mubarak B

Reputation: 60

Better way to pass selected index in flutter

I have data from firestore enter image description here

I need to display the name in a single page and the name of content in another page and so episodes

Is there a better way than this

tvshow page

FutureBuilder(
            future: Provider.of<Data>(context).fetchShows(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data.length,
                  scrollDirection: Axis.horizontal,
                  itemBuilder: (BuildContext context, int index) {
                    return InkWell(
                      onTap: () {
                        tvSelected = index;
                        Navigator.push(context, MaterialPageRoute(
                            builder: (BuildContext context) {
                          return SeasonsPage(selectedTv: tvSelected);
                        }));
                      },
                      child: Container(
                        margin: EdgeInsets.all(10.0),
                        width: 100.0,
                        color: Colors.orangeAccent,
                        child: Text(snapshot.data[index].name),
                      ),
                    );
                  },
                );
              } else {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            }),

seasons page:

FutureBuilder(
        future: Provider.of<Data>(context).fetchShows(),
        builder: (context, snapshot) => snapshot.hasData
            ? ListView.builder(
                itemCount: snapshot.data[selectedTv].content.length,
                scrollDirection: Axis.horizontal,
                itemBuilder: (BuildContext context, int index) {
                  return InkWell(
                    onTap: () {
                      selectedSeason = index;
                      Navigator.push(context, MaterialPageRoute(
                          builder: (BuildContext context) {
                        return EpisodesPage(
                          selectedTv: selectedTv,
                          selectedSeason: selectedSeason,
                        );
                      }));
                    },
                    child: Container(
                      margin: EdgeInsets.all(10.0),
                      width: 100.0,
                      color: Colors.orangeAccent,
                      child: Text(
                          snapshot.data[selectedTv].content[index].name),
                    ),
                  );
                },
              )
            : Center(child: CircularProgressIndicator()),
      ),

episodes page:

FutureBuilder(
        future: Provider.of<Data>(context).fetchShows(),
        builder: (context, snapshot) => snapshot.hasData
            ? ListView.builder(
                itemCount: snapshot.data[selectedTv].content[selectedSeason]
                    .episodes.length,
                scrollDirection: Axis.horizontal,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    margin: EdgeInsets.all(10.0),
                    width: 100.0,
                    color: Colors.orangeAccent,
                    child: Text(snapshot.data[selectedTv]
                        .content[selectedSeason].episodes[index]),
                  );
                },
              )
            : Center(child: CircularProgressIndicator()),
      ),

look at when I pass a route page ............................. ............................. ...........................

Upvotes: 0

Views: 997

Answers (1)

Mich25educ
Mich25educ

Reputation: 333

Firstly you you create a new provider class that will hold the indices of the currently selected tv,episode and season as shown bellow:

class CurrentIndexProvider with ChangeNotifier {
  int _selectedTv;
  int _selectedSeason;
  int _selectedEpisode;

  set selectedTv(int newIndex) {
    this._selectedTv = newIndex;
    notifyListeners();
  }

  set selectedSeason(int newIndex) {
    this._selectedSeason = newIndex;
    notifyListeners();
  }

  set selectedEpisode(int newIndex) {
    this._selectedEpisode = newIndex;
    notifyListeners();
  }

  int get selectedTv => this._selectedTv;
  int get selectedSeason => this._selectedSeason;
  int get selectedEpisode => this._selectedEpisode;
}

Then your tv shows page becomes:

final selectedItems = Provider.of<CurrentIndexProvider>(context);
FutureBuilder(
            future: Provider.of<Data>(context).fetchShows(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data.length,
                  scrollDirection: Axis.horizontal,
                  itemBuilder: (BuildContext context, int index) {
                    return InkWell(
                      onTap: () {
                        // tvSelected = index; -->we dont need this anylonger
                        //we set the current show number to the index of the current 
                        //listview item when tapped
                        selectedItems.selectedSeason=index; 
                        Navigator.push(context, MaterialPageRoute(
                            builder: (BuildContext context) {
                          return SeasonsPage(
                            //we don't need to pass anything in the constructor again
                            // selectedTv: tvSelected
                            );
                        }));
                      },
                      child: Container(
                        margin: EdgeInsets.all(10.0),
                        width: 100.0,
                        color: Colors.orangeAccent,
                        child: Text(snapshot.data[index].name),
                      ),
                    );
                  },
                );
              } else {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            }),

your seasons page becomes

final selectedItems = Provider.of<CurrentIndexProvider>(context);
FutureBuilder(
    future: Provider.of<Data>(context).fetchShows(),
    builder: (context, snapshot) => snapshot.hasData
        ? ListView.builder(
            itemCount: snapshot.data[ selectedItems.selectedTv].content.length,
            scrollDirection: Axis.horizontal,
            itemBuilder: (BuildContext context, int index) {
              return InkWell(
                onTap: () {
                  //selectedSeason = index; --> we dont need this any longer
                  selectedItems.selectedSeason=index;
                  Navigator.push(context, MaterialPageRoute(
                      builder: (BuildContext context) {
                    return EpisodesPage(
                      //we don't need any parameter in the constructor now
                      // selectedTv: selectedTv,
                      // selectedSeason: selectedSeason,
                    );
                  }));
                },
                child: Container(
                  margin: EdgeInsets.all(10.0),
                  width: 100.0,
                  color: Colors.orangeAccent,
                  child: Text(
                      snapshot.data[selectedItems.selectedTv].content[index].name),
                ),
              );
            },
          )
        : Center(child: CircularProgressIndicator()),
  ),

And finally the episodes page becomes

   final selectedItems = Provider.of<CurrentIndexProvider>(context);
FutureBuilder(
        future: Provider.of<Data>(context).fetchShows(),
        builder: (context, snapshot) => snapshot.hasData
            ? ListView.builder(
                itemCount: snapshot.data[selectedItems.selectedTv ].content[selectedItems.selectedSeason]
                    .episodes.length,
                scrollDirection: Axis.horizontal,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    margin: EdgeInsets.all(10.0),
                    width: 100.0,
                    color: Colors.orangeAccent,
                    child: Text(snapshot.data[selectedItems.selectedTv]
                        .content[selectedItems.selectedSeason].episodes[index]),
                  );
                },
              )
            : Center(child: CircularProgressIndicator()),
      ),

With this you can have access to the currently selected tv show or seasons or even episodes anywhere within you code by using provider. hope this helped

Upvotes: 1

Related Questions