Search code examples
flutterlistviewflutter-layoutheightscrollable

How to make list view builder scrollable and set its height space as much as it can take?


I have a problem with ListView. I need to make it scrollable and set its size to max space it can take. Below listView I have a button that should be visible, but the ListView covers it. I tried solutions from similar topics:

  • put ListView into SingleChildScrollView
  • make ListView Expanded

So the problem is:

  • how to make this listView scrollable?
  • how can I set its size to max as it can take (I mean it should be between 'List of participants' and Leave button)
  • how can I attach this button to be always on the bottom of screen, no matter what size of screen I have?

I hope pictures help you to understand what I mean. I also add the code but it is formatted weird, so sorry about that.

Screenshoot from device with above problem:

enter image description here

How it looks on another device and how it should look:

enter image description here

Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomInset: false,
        appBar: AppBar(
          title: const Text('Flutter SDK'),
          centerTitle: true),
        body: Padding(
            padding: const EdgeInsets.all(16),
            child: !isInitializedList
                ? Column(
                    children: [
                      TextField(
                        controller: usernameController,
                        readOnly: true),
                      const SizedBox(height: 12),
                      TextField(
                        decoration: const InputDecoration(hintText: 'Conference name'),
                        controller: conferenceNameController),
                      const SizedBox(height: 12),
                      ElevatedButton(
                        onPressed: () async {
                          // Step 5: Call joinConference()
                          await joinConference();
                        },
                        child: isJoining
                            ? const Text('Joining...')
                            : const Text('Join the conference')),
                      const Divider(thickness: 2),
                      const Text("Join the conference to see the list of participants.")
                    ],
                  )
                : Column(
                    children: [
                      Text(
                          'Conference name: ${conferenceNameController.text}',
                          style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 16)),
                      const SizedBox(height: 16),
                      Column(
                        children: [
                          const Align(
                              alignment: Alignment.centerLeft,
                              child: Text(
                                  'List of participants:',
                                  style: TextStyle(color: Colors.blue, fontWeight: FontWeight.w600))),
                        const SizedBox(height: 16),

                        // Step 7: Display the list of participants
                          ListView.separated(
                            separatorBuilder: (BuildContext context, int index) {
                              return const SizedBox(height: 5);
                            },
                            shrinkWrap: true,
                            itemCount: participants.length,
                            itemBuilder: (context, index) {
                              var participant = participants[index];
                              return Padding(
                                padding: const EdgeInsets.all(4),
                                child: Row(children: [
                                  Expanded(
                                    flex: 1,
                                    child: SizedBox(
                                        height: 150,
                                        width: 150,
                                        child: VideoView.withMediaStream(
                                            participant: participant,
                                            mediaStream: participant.streams?.firstWhereOrNull((s) =>
                                                    s.type == MediaStreamType.camera),
                                            key: ValueKey('video_view_tile_${participant.id}'))),
                                  ),
                                  Expanded(
                                    flex: 1,
                                    child: Padding(
                                      padding: const EdgeInsets.symmetric(horizontal: 8.0),
                                      child: Column(
                                          mainAxisAlignment:
                                              MainAxisAlignment.center,
                                          children: [
                                            Text(
                                                "${participant.info?.name.toString()}"),
                                            Text(
                                                "status: ${participant.status?.name}")
                                          ]),
                                    ),
                                  )
                                ]),
                              );
                            }),
                    ]),
                    const SizedBox(height: 16),
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(primary: Colors.red),
                    onPressed: () async {
                      // Step 6: Call leaveConference()
                      await leaveConference();
                    },
                    child: isJoining
                        ? const Text('Leaving...')
                        : const Text('Leave the conference'))
                ])
        )
    );
  }

Solution

  • When you want to make list view expand as much as available, you need to wrap it with Expanded widget, by that you tell to column give it space as much as you have, also you need to do this for inside column agin, like this:

    Column(
       children: [
           Text('Conference name: ${conferenceNameController.text}',
           style: const TextStyle(fontWeight: FontWeight.w400, fontSize: 16)),
           const SizedBox(height: 16),
           Expanded(// <--- add this
             child: Column(
                   children: [
                            const Align(
                                alignment: Alignment.centerLeft,
                                child: Text('List of participants:',
                                    style: TextStyle(
                                        color: Colors.blue,
                                        fontWeight: FontWeight.w600))),
                            const SizedBox(height: 16),
    
                            Expanded( // <--- add this
                              child: ListView.separated(
                                  separatorBuilder:
    
                   ...
    )
    

    enter image description here