Flutter : How to add a Header Row to a ListView

davidk picture davidk · Apr 23, 2018 · Viewed 44k times · Source

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

Answer

najeira picture najeira · Apr 24, 2018

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