Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

A ListView of two ListView builders

I’m cloning a social media app design where there are two ListView: an horizontal one for the user stories, and a vertical one for user posts. I’ve already built them and they work, but I would like to wrap them in a unique ListView with stories at the top, and posts under the stories. If I scroll, the stories should disappear after a while and I should see only posts. How can I do?

UserStory widget:


class UserStory extends StatelessWidget {
  const UserStory({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        SizedBox(
          height: 100,
          child: ListView.builder(
            physics: const BouncingScrollPhysics(),
            padding: const EdgeInsets.symmetric(horizontal: 10.0),
            scrollDirection: Axis.horizontal,
            itemCount: 10,
            itemBuilder: (context, i) {
              return Container(
                width: 60,
                height: 60,
                margin: const EdgeInsets.symmetric(horizontal: 5.0),
                decoration: BoxDecoration(
                  shape: BoxShape.circle,
                  color: Colors.grey.shade200,
                ),
              );
            },
          ),
        )
      ],
    );
  }
}

UserPost widget:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


class UserPost extends StatelessWidget {
  const UserPost({super.key});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: ListView.builder(
        physics: const BouncingScrollPhysics(),
        itemCount: 10,
        itemBuilder: (context, index) {
          return Padding(
            padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0),
            child: Column(
              children: [
                ListTile(
                  leading: Container(
                    width: 40,
                    height: 40,
                    decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        color: Colors.grey.shade200
                    ),
                  ),
                  title: const Text("Ava Sadie"),
                  subtitle: Text("Sylhet, Bangladesh", style: Theme.of(context).textTheme.labelSmall,),
                  trailing: IconButton(splashRadius: 20.0, onPressed: () {}, icon: const Icon(Icons.more_horiz_outlined),),
                ),
                Container(
                  width: double.infinity,
                  height: 250,
                  margin: const EdgeInsets.only(top: 5.0),
                  decoration: BoxDecoration(
                    color: Colors.grey.shade200,
                    borderRadius: BorderRadius.circular(25.0),
                  ),
                ),
                const SizedBox(height: 5),
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        IconButton(splashRadius: 20.0, onPressed: () {}, icon: const Icon(Icons.favorite_outline,),),
                        Text("6.2k", style: Theme.of(context).textTheme.displaySmall,),
                      ],
                    ),

                    const SizedBox(width: 20,),

                    Row(
                      children: [
                        IconButton(splashRadius: 20.0, onPressed: () {}, icon: const Icon(Icons.messenger_outline,),),
                        Text("2.1k", style: Theme.of(context).textTheme.displaySmall,),
                      ],
                    ),

                    const SizedBox(width: 20,),

                    Row(
                      children: [
                        IconButton(splashRadius: 20.0, onPressed: () {}, icon: const Icon(Icons.bookmark_border_outlined),),
                        Text("3.5k", style: Theme.of(context).textTheme.displaySmall,),
                      ],
                    ),
                  ],
                )
              ],
            ),
          );
        }
      ),
    );
  }
}

HomePage:

import 'package:atlas/pages/widgets/user_post.dart';
import 'package:atlas/pages/widgets/user_story.dart';
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        forceMaterialTransparency: true,
        leading: IconButton(
          padding: const EdgeInsets.symmetric(horizontal: 30.0),
          onPressed: () {},
          icon: const Icon(Icons.camera_alt_outlined),
        ),
        actions: [
          IconButton(
            padding: const EdgeInsets.symmetric(horizontal: 30.0),
            onPressed: () {},
            icon: const Icon(Icons.email_outlined),
          ),
        ],
      ),
      body: const Column(
        children: <Widget>[
          UserStory(),
          UserPost(),
        ],
      ),
    );
  }
}

I tried to wrap the body in a ListView, but it spams some errors and I see neither Stories nor posts

You find two photos of the actual screen: When opening homepage

here it’s all ok, but when I want to scroll stories should disappear and I should see only posts. Instead, as you can see in the second photo, stories stay at the top.

Second photo while scrolling

>Solution :

You could replace Column to ListView at HomePage.

body: ListView(
  children: <Widget>[
    UserStory(),
    UserPost(),
  ],
),

And add shrinkWrap: true to ListView at UserPost widget.

return ListView.builder(
  shrinkWrap: true,
  ...,
);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading