Search code examples
dartflutter-layout

Add more fields after a listview.builder


I have a statefull layout with a listview.builder inside the builder I have a couple of expansionTile widgets

How do I show the entire list on the screen and add some textform widget below the list?

I have added a Expanded widget around the list to allow for more widgets below it but the list gets cut at a certain point where I want to show the entire list and then the text widgets after



class ContactUsScreen extends StatefulWidget {
  const ContactUsScreen({Key? key}) : super(key: key);

  static const String contactRouteName = "/contactScreen";

  @override
  State<ContactUsScreen> createState() => _ContactUsScreenState();
}

class _ContactUsScreenState extends State<ContactUsScreen> {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
          appBar: AppBar(
            title: Text("Contact Us"),
            centerTitle: true,
          ),
          body: CustomScrollView(
            slivers: [
              SliverFillRemaining(
                hasScrollBody: true,
                child: Column(
                  children: [
                    Expanded(
                      child: ListView.builder(
                          itemCount: salesList.length,
                          itemBuilder: (BuildContext context, int index) {
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: Card(
                                elevation: 5,
                                child: ExpansionTile(
                                  key: PageStorageKey<ContactPeople>(salesList[index]),
                                  controlAffinity: ListTileControlAffinity.leading,
                                  childrenPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
                                  expandedCrossAxisAlignment: CrossAxisAlignment.end,
                                  maintainState: true,
                                  title: Text(
                                    salesList[index].regionDescription,
                                    style: const TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 18,
                                    ),
                                  ),
                                  children: //[Text("Test")],
                                      salesList[index].people!.map(
                                    (peopleRecord) {
                                      return ExpansionTile(
                                        expandedCrossAxisAlignment: CrossAxisAlignment.start,
                                        key: PageStorageKey<ContactUsScreen>(peopleRecord),
                                        title: Align(
                                          alignment: Alignment.topLeft,
                                          child: Row(
                                            children: [
                                              ClipOval(
                                                child: Image.asset(
                                                  "assets/images/people/${peopleRecord.avatarImage}",
                                                  fit: BoxFit.cover,
                                                  width: 60,
                                                  height: 60,
                                                ),
                                              ),
                                              SizedBox(
                                                width: 10,
                                              ),
                                              Text(
                                                peopleRecord.name,
                                                style: const TextStyle(fontSize: 15),
                                              ),
                                            ],
                                          ),
                                        ),
                                        children: [
                                          Text(
                                            peopleRecord.title,
                                            style: const TextStyle(fontWeight: FontWeight.bold),
                                          ),
                                          Text(peopleRecord.cellPhoneNumber),
                                          Text(
                                            peopleRecord.emailAddress,
                                          ),
                                          const SizedBox(
                                            height: 5,
                                          ),
                                        ],
                                      );
                                    },
                                  ).toList(),
                                  
                                ),
                              ),
                            );
                          }),
                    ),
                    SizedBox(height: 15,),
                    Text("Contact us directly",
                    style: TextStyle(fontWeight: FontWeight.w700,
                    fontSize: 20,
                    color: Colors.black),),
                    Form(
                      key: formKey,
                      child: Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 15),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.center,

                          children: [
                            TextFormField(controller: fullNameController,
                              keyboardType: TextInputType.text,
                              decoration: InputDecoration(labelText: "Full Name",
                            hintText: "Full Name",
                            ),
                            validator: (inputFieldFullName)
                              {
                                if(inputFieldFullName!.isEmpty)
                                  {
                                    return "Please enter your Full Name";
                                  }
                                else
                                  {
                                    return null;
                                  }
                              },
                            ),
                            TextFormField(controller: contactNumberController,
                              keyboardType: TextInputType.number,
                              decoration: InputDecoration(labelText: "Contact Number",
                              hintText: "Contact Number",
                            ),
                              validator: (inputFieldContactNumber)
                              {
                                if(inputFieldContactNumber!.isEmpty)
                                {
                                  return "Please enter your contact number";
                                }
                                else
                                {
                                  return null;
                                }
                              },
                            ),
                            SizedBox(height: 5,),
                            ElevatedButton(
                              onPressed: () {
                                if(formKey.currentState!.validate())
                                  {
                                    //Send the email
                                  }
                                else
                                  {
                                    const SnackBar snackBar = SnackBar(duration: Duration(seconds: 2), content: Text("Please correct the errors"));
                                    ScaffoldMessenger.of(context).showSnackBar(snackBar);
                                  }
                              },
                              child: Text("Submit"),
                            ),
                            SizedBox(height: 20,),
                          ],
                        ),
                      ),
                    ),
                    //getContactForm(context, formKey),
                  ],
                ),
              )
            ],
          )
          ),
    );
  }
  }

The end result should be that we display the entire list of parent expansion tile, and then only after the textform fields enter image description here Regards


Solution

  • You have to use this structure:

    CustomScrollView(
        slivers: <Widget>[
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return ** first listview **
              },
              childCount: top.length,
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return ** second listview **
              },
              childCount: bottom.length,
            ),
          ),
        ],
      ),