ReorderableListView
Um controle ReorderableListView é um widget container que admite controles filhos reposicionáveis. Ele cria uma lista similar à ListView com filhos que podem ser arrastados para novas posições, mostrando uma animação durante o movimento. Ele pode ser usado para abrigar listas com elementos de prioridade ajustável, como uma lista de tarefas ou de músicas.
Exemplo Básico
O controle ReorderableListView permite a construção de linhas ou colunas que podem ser arrastadas e reposicionadas, mudando de lugar com uma animação suave. No exemplo abaixo, dois desses controles são inseridos em uma página. No primeiro, declarado como uma lista horizontal (horizontal=True
) são inseridos 2 elementos do tipo ft.Container
. No segundo, uma lista vertical (horizontal=False
, que é o default), são inseridos 2 elementos ft.ListTile
.
import flet as ft def main(page: ft.Page): page.add( # 2 colunas dispostas horizontalmente ft.ReorderableListView( expand=True, horizontal=True, controls=[ ft.Container(width=250, content=ft.Text("Festa"), alignment=ft.alignment.center, bgcolor="#228A82"), ft.Container(width=250, content=ft.Text("Trabalho"), alignment=ft.alignment.center, bgcolor="#8A4F22"), ], ), # 2 linhas dispostas verticalmente ft.ReorderableListView( controls=[ ft.ListTile(title=ft.Text("Comprar cerveja"), bgcolor="#6C8785"), ft.ListTile(title=ft.Text("Tomar a cerveja"), bgcolor="#BA733C"), ], ) ) ft.app(main)

O resultado desse código está mostrado na figura 1.
Os containers Festa e Trabalho podem ser movidos e realocados horizontalmente. Na parte inferior as linhas Comprar cerveja e Tomar cerveja podem ser arrastados verticalmentes e alterados em sua posição. Em um caso mais completo, os eventos de arrastar podem ser capturados (veja abaixo) para alterar propriedades do aplicativo, alterar um banco de dados ou executar qualquer outra ação desejada.
O arrasto é feito com o mouse nas marcas de abas (traços em azul). Se existirem mais controles que que o espaço disponĩvel para exibí-los, uma barra de rolagem é disponibilizada.
Observação: No atual estado do Flet (em Abril de 2025) a atualização de qualquer controle no aplicativo, como por exemplo, uma linha de texto informando sobre o estado da página, atualiza toda a página, retornando os controles ReorderableListView ao seu estado original.
Propriedades
O controle ReorderableListView possui as seguintes propriedades. Como ele pode conter diversos outros controles filhos a formatação e coleta de eventos dos filhos pode ser feita de forma independante.
Propriedade | Descrição |
---|---|
anchor | A posição relativa do deslocamento de rolagem zero. O default é 0,0. |
auto_scroller_velocity_scalar | A velocidade escalar por pixel sobre rolagem. Representa como a velocidade é dimensionada com a distância de rolagem. A velocidade de rolagem automática = (distância da overscroll) * velocidade escalar. |
build_controls_on_demand | Booleano. Se True controles são criados de forma preguiçosa/sob demanda, ou seja, somente quando se tornarem visíveis. Isso é útil quando de lida com um número grande de controles. O default é True. |
cache_extent | A janela de visualização (viewport) possui uma área antes e depois da área visível onde armazena em cache itens que serão tornados visíveis quando o usuário rola a página.
Itens nessa área de cache são dispostos antes de se tornarem visíveis na tela. O cache_extent define quantos pixels a área de cache inclui antes da borda inicial e depois da borda final da janela de visualização. |
controls | Lista de controles que serão inseridos e reordenados. |
clipe_behavior | O conteúdo será recortado (ou não) de acordo com esta opção. O valor é do tipo ClipBehavior e default é ClipBehavior.HARD_EDGE. |
first_item_prototype | Booleano. Se True as dimensões (largura e altura) definidas para o primeiro item são usadas como “protótipo” para os demais itens. O default é False. |
footer | Um controle a ser usado no rodapé. Esse item é não reordenável e será exibido ao final dos controles ordenáveis. O valor é do tipo Control. |
header | Um controle a ser usado como cabeçalho. Esse item é não reordenável e será exibido antes dos controles ordenáveis. O valor é do tipo Control. |
horizontal | Booleano, se os controles devem ser dispostos horizontalmente. O default é False. |
item_extent | Se não nulo, força os filhos a terem a extensão fornecida na direção de rolagem.
É mais eficiente especificar um item_extent do que deixar que os filhos determinem sua própria extensão pois o mecanismo de rolagem tem informação prévia da extensão dos filhos. Isso economiza trabalho, por exemplo, quando a posição de rolagem muda drasticamente. |
padding | Espaço de afastamento interno dos controles. O valor é do tipo Padding. |
Eventos
O controle ReorderableListView responde aos seguintes eventos:
Evento | Descrição |
---|---|
on_reorder | Dispara quando um controle filho é arrastado para uma nova posicão. O aplicativo tem que ser atualizado para reordenar esses itens. |
on_reorder_start | Dispara quando o arrasto do controle filho é iniciado. |
on_reorder_end | Dispara quando termina o arrasto do controle filho. |
O argumento de evento é do tipo OnReorderEvent, chamado e
nos exemplos dados.
Exemplo de Uso do ReorderableListView
Um exemplo mais completo de uso do ReorderableListView está apresentado abaixo:
import flet as ft def main(page: ft.Page): page.title = "Demonstração de ReorderableListView" page.bgcolor=ft.Colors.WHITE page.window.width=330 page.window.height=620 def move_coluna(e: ft.OnReorderEvent): print(f"Coluna movida da posição {e.old_index+1} para {e.new_index+1}.") def move_linha(e: ft.OnReorderEvent): print(f"Linha movida da posição {e.old_index+1} para {e.new_index+1}.") cor=[ft.Colors.GREEN_200, ft.Colors.GREEN_50, ft.Colors.GREEN_500, ft.Colors.GREEN] coluna=["A","B","C","D","E"] linha=["Comparar café","Tomar café","Comprar cerveja","Tomar cerveja","Dormir"] # Colunas dispostas horizontalmente lista_horizontal = ft.ReorderableListView( expand=True, horizontal=True, on_reorder=move_coluna, controls=[ ft.Container( border=ft.border.all(1, ft.Colors.BLACK), content=ft.Text(f"{coluna[i]}", color=ft.Colors.BLACK), margin=ft.margin.symmetric(horizontal=1, vertical=5), width=60, alignment=ft.alignment.center, bgcolor= cor[i%2], ) for i in range(5) ], ) # linha_header linha_header=ft.Container( content=ft.Text("Coisas a Fazer", color=ft.Colors.WHITE), margin=ft.margin.symmetric(horizontal=0, vertical=5), padding=5, height=30, bgcolor= cor[2], ) # linha_footer linha_footer=ft.Container( content=ft.Text("Fim da Página", color=ft.Colors.WHITE), margin=ft.margin.symmetric(horizontal=0, vertical=5), padding=5, height=30, bgcolor=cor[2], ) # Linhas dispostas verticalmente lista_vertical=ft.ReorderableListView( expand=True, on_reorder=move_linha, header=linha_header, footer=linha_footer, controls=[ ft.Container( border=ft.border.all(1, ft.Colors.BLACK), content=ft.Text(f"{linha[i]}", color=ft.Colors.BLACK), margin=ft.margin.symmetric(horizontal=1, vertical=1), width=330, height=40, padding=10, alignment=ft.alignment.center_left, bgcolor= cor[i%2], ) for i in range(5) ], ) page.add(lista_horizontal, lista_vertical) ft.app(main)
Após algumas operações de arrasto das linhas e colunas, as seguintes linhas são exibidas no console:
Linha movida da posição 1 para 4. Linha movida da posição 2 para 3. Coluna movida da posição 1 para 4. Coluna movida da posição 2 para 3.
O resultado desse código está mostrado na figura 2 em seu estado inicial e depois dos arrastos descritos acima.
Observe que as propriedades controls de ambos os ReorderableListView, que são listas (lists ordinárias do Python), foram preenchidos com compressão de listas. Esse mecanismo está descrito em Compreensão de listas no Python e resumido abaixo:
$ lista1=[i** for i in range(10)] $ print(lista1) ↳ [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] $ lista2=[i** for i in range(10) if i%2==0] $ print(lista2) ↳ [0, 4, 16, 36, 64]
Portanto o código preenche a lista ft.ReorderableListView.controls
com 5 instâncias de ft.Container
, com i=0,...,4
. As propriedades internas variam com i
em linha[i]
, definida como uma lista no início do código, e cor[i%2]
, que pode ser apenas cor[0]
ou cor[1]
, de outra lista já definida.
A propriedade horizontal=True
define que os controles são dispostos na horizontal.