skip to Main Content

I have a set of tabs, within one of the tabs i have a futurebuilder that has a listviewBuilder and ListTile. How do I add a header container/Sizedbox above the listtiles.
I have tried adding columns, SingleChildScrollView, CustomScrollView with slivers but keeps getting errors

Widget localAttractionsTab() {
    return FutureBuilder(
        future: localAttractions(widget.locationId),
        builder: (BuildContext context, AsyncSnapshot<Amenities> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.error != null) {
            return const Center(child: Text('an error occured!'));
          } else {
            return
             ListView.builder(
                itemCount: snapshot.data!.attraction.length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(snapshot.data!.attraction[index].attractionname),
                    //subtitle: Text(el.),
                    onTap: () {
                      //Got To Amenity Details Page
                      Navigator.of(context).push(
                        MaterialPageRoute(
                          builder: (context) => AttractionDetailsScreen(
                              attractionID: snapshot.data!.attraction[index].id
                             ),
                        ),
                      );
                    },
                  );
                }
            );
          }
        });
  }


2

Answers


  1. Widget localAttractionsTab() {
        return FutureBuilder(
            future: localAttractions(widget.locationId),
            builder: (BuildContext context, AsyncSnapshot<Amenities> snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return const Center(child: CircularProgressIndicator());
              } else if (snapshot.error != null) {
                return const Center(child: Text('an error occured!'));
              } else {
                return
                 ListView.builder(
                    itemCount: snapshot.data!.attraction.length + 1,
                    itemBuilder: (context, index) {
                      if(index == 0){
                        return Container(); // add whatever you want here
                      }
                      else{
                        return ListTile(
                        title: Text(snapshot.data!.attraction[index].attractionname),
                        //subtitle: Text(el.),
                        onTap: () {
                          //Got To Amenity Details Page
                          Navigator.of(context).push(
                            MaterialPageRoute(
                              builder: (context) => AttractionDetailsScreen(
                                  attractionID: snapshot.data!.attraction[index].id
                                 ),
                            ),
                          );
                        },
                      );
                      }
                      
                    }
                );
              }
            });
      }
    
    Login or Signup to reply.
  2. There are two ways to fix it.

    The first one which I think is not too clean is alter the itemCount by adding the first widget position. You should validate first index to render the Header you want:

    Widget localAttractionsTab() {
      return FutureBuilder(
          future: localAttractions(widget.locationId),
          builder: (BuildContext context, AsyncSnapshot<Amenities> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(child: CircularProgressIndicator());
            } else if (snapshot.error != null) {
              return const Center(child: Text('an error occured!'));
            } else {
              return ListView.builder(
                  itemCount: snapshot.data!.attraction.length + 1,
                  itemBuilder: (context, index) {
                    if (index == 0) {
                      return Container(child: Text('The header!!'));
                    }
                    int attractionIndex = index + 1;
                    return ListTile(
                      title: Text(snapshot
                          .data!.attraction[attractionIndex].attractionname),
                      //subtitle: Text(el.),
                      onTap: () {
                        //Got To Amenity Details Page
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => AttractionDetailsScreen(
                                attractionID: snapshot.data!.attraction[index].id),
                          ),
                        );
                      },
                    );
                  });
            }
          });
    }
    

    The second one consists in adding a Columnn with it’s children. Take into account that you have to define the height of the Widget that containts this Column or its going throw an error:

    Widget localAttractionsTab() {
      return FutureBuilder(
        future: localAttractions(widget.locationId),
        builder: (BuildContext context, AsyncSnapshot<Amenities> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.error != null) {
            return const Center(child: Text('an error occurred!'));
          } else {
            return Column(
              children: <Widget>[
                Container(
                  height: 100, // set the height of the header container as needed
                  child: Center(
                    child: Text(
                      'Header Container', 
                      style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
                Expanded(
                  child: ListView.builder(
                    itemCount: snapshot.data!.attraction.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text(snapshot.data!.attraction[index].attractionname),
                        onTap: () {
                          Navigator.of(context).push(
                            MaterialPageRoute(
                              builder: (context) => AttractionDetailsScreen(
                                attractionID: snapshot.data!.attraction[index].id,
                              ),
                            ),
                          );
                        },
                      );
                    },
                  ),
                ),
              ],
            );
          }
        },
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search