Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter : How to add a Header Row to a ListView

Very new to Flutter. I've been able to utilize HTTP requests for data, build a ListView, edit a Row in that List and other basics. Excellent environment.

I've managed to cobble together a badly constructed Header for a ListView... but I know this isn't right. I can't get the Header text to line up properly.

I see that the Drawer Class has a DrawerHeader Class, but can't see that ListView has a ListViewHeader.

  @override   Widget build(BuildContext context) {     return Scaffold(         appBar: AppBar(           title: Text('Contacts'),           actions: [             IconButton(icon: Icon(Icons.add_circle),                 onPressed: getCustData             ),           ],         ),         //body:         body: Column(             children: [               Row(                   children: [                     Expanded(child: Text('', style: TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),                     Expanded(child: Text('First Name', style:  TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),                     Expanded(child: Text('Last Name', style:  TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),                     Expanded(child: Text('City', style: TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),                     Expanded(child: Text('Customer Id', style: TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),                     Expanded(child: Text('', style: TextStyle(height: 3.0, fontSize: 15.2, fontWeight: FontWeight.bold,))),                   ]               ),            Expanded(child:Container(             child: ListView.builder(                itemCount: data == null ? 0 : data.length,               itemBuilder: (BuildContext context, int index) {                  return InkWell(                   onTap: () {                     Navigator.push(                       context,                       MaterialPageRoute(                           builder: (context) => APIDetailView(data[index])),                     );                   },                    child: ListTile(                //return new ListTile(                       onTap: null,                       leading: CircleAvatar(                         backgroundColor: Colors.blue,                         child: Text(data[index]["FirstName"][0]),                       ),                       title: Row(                           children: <Widget>[                             Expanded(child: Text(data[index]["FirstName"])),                             Expanded(child: Text(data[index]["LastName"])),                             Expanded(child: Text(data[index]["Bill_City"])),                             Expanded(child: Text(data[index]["Customer_Id"])),                           ]                       )                   ),                  );               }, //itemBuilder              ),           ),         ),       ]     ) ); 

} }

Thanks.

enter image description here

like image 796
davidk Avatar asked Apr 23 '18 16:04

davidk


2 Answers

Return the header as first row by itemBuilder:

ListView.builder(     itemCount: data == null ? 1 : data.length + 1,     itemBuilder: (BuildContext context, int index) {         if (index == 0) {             // return the header             return new Column(...);         }         index -= 1;          // return row         var row = data[index];         return new InkWell(... with row ...);     }, ); 
like image 161
najeira Avatar answered Sep 19 '22 21:09

najeira


Here's how I solved this. Thanks @najeira for getting me thinking about other solutions.

In the first body Column I used the same layout for my Header that I used for the ListTile.

Because my data ListTile, in this case, includes a CircleAvatar, all the horizontal spacing is off a bit... 5 columns where the CircleAvatar is rendered... then 4 evenly spaced columns.

So... I added a ListTile to the first body Column, a CircleAvatar with a backgroundColor of transparent, and then a Row of my 4 Headings.

        ListTile(         onTap: null,         leading: CircleAvatar(           backgroundColor: Colors.transparent,         ),         title: Row(             children: <Widget>[               Expanded(child: Text("First Name")),               Expanded(child: Text("Last Name")),               Expanded(child: Text("City")),               Expanded(child: Text("Id")),             ]         ),       ), 

enter image description here

like image 37
davidk Avatar answered Sep 20 '22 21:09

davidk