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
),
),
);
},
);
}
);
}
});
}
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,
),
),
);
},
);
},
),
),
],
);
}
},
);
}