Sayuru_Sandaru
Sayuru_Sandaru

Reputation: 360

How to make Horizontal Scroll ListView inside the SingleChildScroll

I want to create a layout like this, Image

I want to create a flutter app which can scroll vertically and also some content of the app should scroll horizontally as describe in the picture. I used ListView with scroll horizontal inside the SingleChildScrollView but it not work. It hide the content Horizontal listView content and the content below the ListView.

So How to make this layout

Code I used,

body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 10),
              child: CustomizedAppBar(),
            ),
            SizedBox(
              height: 30.0,
            ),
            Padding(
              padding: const EdgeInsets.only(left: 10,bottom: 5),
              child: Text(
                'Hello Jessica.',
                style: kArtistNamePlayScreen,
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 10,bottom: 40),
              child: Text(
                'Recommendeddd',
                style: kSongNamePlayScreen,
              ),
            ),
            //TODO Insert Carousel Here
            ListView(
              children: <Widget>[
                Container(
                  height: 150,
                  width: 230,
                  decoration: BoxDecoration(
                    color: Colors.grey[100],
                    borderRadius: BorderRadius.circular(20.0),
                    image: DecorationImage(
                      image: AssetImage('images/Panini_l.jpg'),
                      fit: BoxFit.cover,
                    ),
                    boxShadow: [
                      new BoxShadow(
                        color: Colors.grey,
                        offset: Offset(1.5,1.5),
                        blurRadius: 3,
                      ),
                    ],
                  ),
                ),
              ],
            ),
            Text(
              'Popular artists',
              style: kSongNamePlayScreen,
            ),
            Container(
              child: Row(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(20.0),
                    child: Container(
                      width: 60,
                      height: 75,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.all(Radius.circular(8)),
                        image: DecorationImage(
                          image: AssetImage('images/Panini_l.jpg'),
                          fit: BoxFit.cover,
                        )
                      ),
                    ),
                  )
                ],
              ),
            ),
            SongList(
              songListSongName: 'Beautiful People',
              songListArtistName: 'Ed Sheeran',
              songListAvatarImage: AssetImage('images/beautiful_people_l.jpg'),
              heartClick: (){},
            ),
            SongList(
              songListSongName: 'Panini',
              songListArtistName: 'Lil Nas X',
              songListAvatarImage: AssetImage('images/Panini_l.jpg'),
              heartClick: (){},
            ),
            SongList(
              songListSongName: 'Do You Sleep',
              songListArtistName: 'Sam Samith',
              songListAvatarImage: AssetImage('images/Do_you_sleep_l.jpg'),
              heartClick: (){},
            ),
            SongList(
              songListSongName: 'Bad Guys',
              songListArtistName: 'Billie Eilish',
              songListAvatarImage: AssetImage('images/Bad_guys_l.jpg'),
              heartClick: (){},
            )
          ],
        ),
      )

Upvotes: 1

Views: 3447

Answers (2)

Pablo Barrera
Pablo Barrera

Reputation: 10963

You could use a ListView with horizontal scroll, it has to be wrapped inside a Container or SizedBox with a specific height.

Using ListView.builder could be more efficient, here is a quick example:

final _items = List.generate(20, (e) => e);

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(),
    body: SingleChildScrollView(
      child: Column(
        children: <Widget>[
          Text("A"),
          SizedBox(
            height: 100.0,
            child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: _items.length,
                itemBuilder: (context, index) {
                  print('$index');
                  return SizedBox(
                    width: 150.0,
                    child: Center(child: Text('${_items[index]}')),
                  );
                }),
          ),
          Text("B"),
        ],
      ),
    ),
  );
}

You could see the prints in the console, indicating the items are created only when they're scrolled onto the screen.

Upvotes: 0

Arash Mohammadi
Arash Mohammadi

Reputation: 1419

Instead of ListView, you can use SingleChildScrollView with Row as child. Then give the SingleChildScrollView the scrollDirection: Axis.horizontal Code:

//TODO Insert Carousel Here
      SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: <Widget>[
            Container(
              height: 150,
              width: 230,
              decoration: BoxDecoration(
                color: Colors.grey[100],
                borderRadius: BorderRadius.circular(20.0),
                image: DecorationImage(
                  image: AssetImage('images/Panini_l.jpg'),
                  fit: BoxFit.cover,
                ),
                boxShadow: [
                  new BoxShadow(
                    color: Colors.grey,
                    offset: Offset(1.5, 1.5),
                    blurRadius: 3,
                  ),
                ],
              ),
            ),
          ],
        ),
      ),

Upvotes: 3

Related Questions