user2148956
user2148956

Reputation: 179

Flutter ListView with different widgets and list items

I'm not sure if I'm missing something. I'm playing around with Flutter and I want to build a (simple) view with some text widgets, buttons and other widgets (see picture below). These widgets should be followed by a list of items. The whole view (except the app bar, of course) should be scrollable - not only the items.

That's why I put everything inside a ListView. But I'm not able to do something like this (while items is a map with String values):

...    
home: Scaffold(
  appBar: AppBar(
    title: Text('App bar'),
  ),
  body: new ListView(
    children: <Widget>[
      new Text('Some Text'),
      new FlatButton(...),
      new Image.asset(...),
      items.map((item)=>new Padding(
        child: new Text(item.title),
      )).toList()
    ],
  ),
),
...

What is the right way to get the desired view?

Thanks in advance!

ListView with different widget types and some list items

Upvotes: 7

Views: 12914

Answers (7)

Farooq Khan
Farooq Khan

Reputation: 76

Try this

body: SingleChildScrollView( //add to Scroll whole screen
    child: Column(
        children: <Widget>[
            new Text('Some Text'), //Element-1
            new FlatButton(...),   //Element-2
            new Image.asset(...),  //Element-3
            items.map((item)=>new Padding(child: new Text(item.title),)).toList(), //Element-4
           Expanded(child:ListView.separated(    //Element-5
                shrinkWrap: true,  //this property is must when you put List/Grid View inside SingleChildScrollView
                physics: NeverScrollableScrollPhysics(), //this property is must when you put List/Grid View inside SingleChildScrollView
                itemCount: listItems.length,
                itemBuilder: (context, i) {
                    return ListTile(
                        title: Text(listItems[i].Title),
                        subtitle: Text(listItems[i].Description),
                    );
                },
                separatorBuilder: (context, i) {
                    return Divider();
                },
            ),
),
        ],
    ),
),

Upvotes: 0

olowola oreoluwa
olowola oreoluwa

Reputation: 1

Use a for loop

...    
home: Scaffold(
  appBar: AppBar(
    title: Text('App bar'),
  ),
  body: new ListView(
    children: <Widget>[
      new Text('Some Text'),
      new FlatButton(...),
      new Image.asset(...),
      for (var i in items)
      Padding(
        child: new Text(i.title),
      ))
    ],
  ),
),
...

Upvotes: 0

Hekmat
Hekmat

Reputation: 531

You can do this by slivers, for fixed part use SliverToBoxAdapter and for scrolling list use SliverList. both fixed and list parts in page can easily scroll!!!

return CustomScrollView(
  slivers: [
    SliverToBoxAdapter(child: FixedHeader()),
    SliverList(
        delegate: SliverChildBuilderDelegate((context, index) {
            YourListitems()
         })
    )]
)

Upvotes: 0

BIS Tech
BIS Tech

Reputation: 19514

You can use like this

 ListView(
     shrinkWrap: true,
     children: <Widget>[
          Text('hi'),//first widget
          Text('hi2'),//second widget
          Flex(
              direction: Axis.horizontal,children: <Widget>[
                      Expanded(
                        child: ListView.builder(
                            shrinkWrap: true,
                            itemCount: 3,
                            itemBuilder: (BuildContext context, int index){
                              return ...

Or Just tweak the count and the index.

 ListView.builder(
      itemCount: get.length + 2, // add room for the two extra
      itemBuilder: (BuildContext context, int index) {
        if(index == 0){
         return Text('Custom any widget');
        }
        if(index == 1){
         return Text('Custom any widget');
        }
        index -= 2; // decrement index so that it's now in the range [0..length]
        return Bubble(
            style: styleSomebody,
            child: Container(
              ... 
            ));
      }),

Upvotes: 6

Pablo Barrera
Pablo Barrera

Reputation: 10963

You could use ListView.builder since is more efficient, because the items are only created when they're scrolled onto the screen. And in the first position you could put the widgets that aren't from the list, like this:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text('App bar')),
    body: ListView.builder(
      itemCount: items.length + 1,
      itemBuilder: (context, index) {
        if (index == 0) {
          return Column(
            children: <Widget>[
              Text('Some Text'),
              FlatButton(child: Text('A flat button'), onPressed: () {}),
              Image.asset("An image"),
            ],
          );
        }
        return Text('Item ${items[index].title}');
      },
    ),
  );
}

Upvotes: 7

Jay Dhamsaniya
Jay Dhamsaniya

Reputation: 1891

You may use the following code in the body.

body: SingleChildScrollView( //add to Scroll whole screen
    child: Column(
        children: <Widget>[
            new Text('Some Text'), //Element-1
            new FlatButton(...),   //Element-2
            new Image.asset(...),  //Element-3
            items.map((item)=>new Padding(child: new Text(item.title),)).toList(), //Element-4
            ListView.separated(    //Element-5
                shrinkWrap: true,  //this property is must when you put List/Grid View inside SingleChildScrollView
                physics: NeverScrollableScrollPhysics(), //this property is must when you put List/Grid View inside SingleChildScrollView
                itemCount: listItems.length,
                itemBuilder: (context, i) {
                    return ListTile(
                        title: Text(listItems[i].Title),
                        subtitle: Text(listItems[i].Description),
                    );
                },
                separatorBuilder: (context, i) {
                    return Divider();
                },
            ),
        ],
    ),
),

Upvotes: 3

Rubens Melo
Rubens Melo

Reputation: 3315

Children in ListView are list of itens, so, if you want to display a button or text, your widget tree is:

Scaffold
 appBar: AppBar
 body:  Container
   child: ListView       
            ListItem
            ListItem
            ListItem

Then, in your case, you can use a Column to display "fixed widget" (text, button) + listview scrollable:

Scaffold
 appBar: AppBar
 body:  Column 
     [
        Text,
        Buttom,
        ListView
          ListItem
          ListItem
          ListItem
     ]

Upvotes: -2

Related Questions