How to add a TextField at the end of an expandable ListView in Flet Python?

173 Views Asked by At

I am trying to create a chat app using firebase and python, when the user authenticates then it goes to chatScreen() class, there i want expandable Listview because previous messages are to be loaded, and i too want to add a text field at the bottom of it so that we can send the text.

Basically I wrote the code in different files at first, i created an individual file for authentication and for chat, now i want to merge both of them, I used user controls for that, I merged the authentication part but while trying to add chat too the textfield doesn't goes at the bottom of screen

What've tried is

class ChatScreen(UserControl):
    def __init__(self,email,password):
        print(email,password)
        self.listView = ListView(
            expand=True,
            auto_scroll=True,
        )

        self.textField = TextField(
            hint_text="write a message",
            text_size=14,
            autofocus=True,
            border_radius=15,
            max_lines=3,
            color="white",
            cursor_color="white",
            border_color=text_input_border,
            focused_color=text_input_border,
            bgcolor=text_input_bg,
        )

        self.colm = Column(
            controls=[self.listView,self.textField]
        )
        super().__init__()
        
        def build(self):
            
            return self.colm

But it doesn't works

The expected output of this is enter image description here

but i am getting : enter image description here

1

There are 1 best solutions below

0
On

Here is a solution:

import flet as ft


class ChatScreen(ft.UserControl):
    def __init__(self, email, password):
        super().__init__(expand=True)  # Let the UserControl expand as much as it can
        print(email, password)
        self.listView = ft.ListView(expand=True, auto_scroll=True)

        self.textField = ft.TextField(
            hint_text="write a message",
            text_size=14,
            autofocus=True,
            border_radius=15,
            max_lines=3,
        )

        self.colm = ft.Column(controls=[self.listView, self.textField])

    def build(self):
        return self.colm


if __name__ == "__main__":
    def main(page: ft.Page):
        page.add(ChatScreen("email", "pwd"))

    ft.app(target=main)

Here is the explanation of why it was not working, and why it works not. You indeed tried to put expand=True in the ListView object, which is a good thing. This makes the ListView object take as much space as it can in its parent. And here lies the problem: the parent of the ListView is the ChatScreen, and the size of the ChatScreen is just the size of all its components. When the ListView tries to expand, nothing happen as its parent has a fixed size, so the ListView already take all the available space.

To fix this, you only need to allow the ChatScreen to be expandable too. You can do that simply by passing the parameter expand=True in the UserControl constructor (super().__init__). Like that, the ChatScreen will take as much space as it can in it parent (i.e. the whole page), and then the ListView will take as much space as it can in its parent (i.e. the ChatScreen, that will now be big enough for the ListView to expand as it now takes the whole page).