skip to Main Content

Say I have a homemade in my app and at the top is a ListView.Builder and below the listview I want to have an about section, a footer, etc. (more content), how do I make this content under a ListView.builder while having normal scrolling (not visible until we have reached the bottom of the listview).

My code:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          'Home',
          style: TextStyle(color: Colors.white),
        ),
        backgroundColor: Colors.deepPurple,
      ),
      body: _isLoading
          ? const Center(
              child: CircularProgressIndicator(),
            )
          : ListView.builder(
              itemCount: services.length + 1, // +1 for the title

              itemBuilder: (context, index) {
                if (index == 0) {
                  // The first item is the title
                  return const Padding(
                    padding: EdgeInsets.only(top: 30.0, bottom: 12),
                    child: Center(
                      child: Text(
                        'Services',
                        style: TextStyle(fontSize: 29),
                      ),
                    ),
                  );
                } else {
                  // The rest of the items are service cards
                  Service service = services[index - 1];
                  var smallestDuration = findLowestDurationPrice(service);

                  return Padding(
                    padding: const EdgeInsets.all(20),
                    child: Card(
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(15),
                      ),
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(20),
                        child: SingleChildScrollView(
                          child: Column(
                            children: [
                              FutureBuilder(
                                future: getImageUrl(service.imageFileName),
                                builder: (context, snapshot) {
                                  if (snapshot.connectionState ==
                                      ConnectionState.waiting) {
                                    return CircularProgressIndicator();
                                  } else if (snapshot.hasError) {
                                    return Text('Error: ${snapshot.error}');
                                  } else {
                                    String imageUrl = snapshot.data.toString();
                                    print('printing:   $imageUrl');
                                    return Container(
                                      height: 270,
                                      child: Image.network(
                                        imageUrl,
                                        fit: BoxFit.cover,
                                      ),
                                    );
                                  }
                                },
                              ),
                              ExpansionTile(
                                title: Text(
                                  service.title,
                                  style: TextStyle(fontSize: 20),
                                ),
                                children: [
                                  Padding(
                                    padding: const EdgeInsets.all(17.0),
                                    child: Text(
                                      service.description,
                                      style: const TextStyle(fontSize: 16),
                                    ),
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.all(17.0),
                                    child: Center(
                                      child: Row(
                                        children: [
                                          const Text('Starting from:'),
                                          const SizedBox(
                                            width: 8,
                                          ),
                                          Text(
                                            '€ $smallestDuration',
                                            style:
                                                const TextStyle(fontSize: 16),
                                          ),
                                        ],
                                      ),
                                    ),
                                  ),
                                  // You can add more content here if needed
                                ],
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  );
                }
              },
            ),
    );
  }

I have managed to add the Services title at the top by knowing the list starts at zero but with no indication of how long the list will be how do we put content under the ListView to achieve a natural scroll?

2

Answers


  1. Arrange ListView widget like this:

    Column(
      children: [
        Expanded(
         child: ListView.builder(...),
        ),
        Padding(
          padding: const EdgeInsets.all(16),
          child: Text(
            'About Section',
             style: TextStyle(fontSize: 24),
          ),
        ),
      ],
    )
    
    Login or Signup to reply.
  2. you need to give list view height you use an Expanded() but some times it fills all the space, i have a better way to do it, you need to get the media screen height (screen hieght) and subtract the height for the widget you want to put under the list view. you can get screen size from the MediaQuery object using BuidContext

         @override
          Widget build(BuildContext context) {
            Size size = MediaQuery.of(context).size;
            return Column(
               children: [
                SizedBox(
                 hieght:size.height * 0.7, // you can adjust the percentage of screen you the list view to take by adjust value of 0.7
                  child:ListView.builder(...) 
    ,),
           
            Padding(
              padding: const EdgeInsets.all(16),
              child:MaterialButton(
                  child: Text("More"),
                  onPressed: (() {
                  
                }
            
                ),)
            ),
          ],
        )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search