Desenvolvendo um widget de upload com Flutter 🩵
Tags: flutter, frontend, dart, tutorial
Published: 2024-04-10 05:09:49


Desenvolvendo um widget de upload com flutter

Oi, muito obrigada por estar aqui, gostaria de informar que esse é o meu primeiro artigo publicado oficialmente aqui no Dev To e que estão tods convidads a se chegarem e lerem um pouquinho das experiências e vivências minhas, eu que sou atualmente estagiária flutter, também sigo atuando como freelancer front end nas horas vagas e uxui por hobby.

Pois bem, apresentada, agora vamos ao que interessa.

Esse foi um dos meus muitos desafios que tive no cotidiano do estágio. Em algum momento precisei desenvolver um widget que fizesse o upload de pdfs e que além disso também tivesse a funcionalidade de drag e drop na área ao redor.

Para a criação desse projeto, utilizei o seguinte comando:
`flutter create --project-name testedropdrag --org br.com.suamirocha --platforms web ./testedropdrag`

Dessa forma, fica claro que o projeto será feito para web.

Para implementar o widget e deixar ele funcional como eu gostaria, vou utilizar os seguintes pacotes:

ps: encontre os pacotes no site oficial dos pacotes: https://pub.dev


![Package 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwxvirgn47t0tv2z1nar.png)

![Package 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pnh8lom6xw6slqioae9f.png)


![Package 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vu516v1g8yziaw8jfnzv.png)

agora que baixei as minhas dependencias, elas ficam assim no arquivo pubscpec.yaml

![Image Pubspec.yaml](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vyoq7531cwsh4kk6vnts.png)


Agora vamos organizar o projeto.

No meu arquivo Main, vai apenas o principal para rodar a nossa página:

![Image Main.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovtordaq009k4wed757w.png)

Agora podemos trabalhar na nossa página principal que é onde o nosso widget ficará.

A princípio o código vai estar assim: 

![Image Home.dart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g68jmxufl4q3nkr4v4i1.png)

Agora vamos fazer os imports dos pacotes de instalamos no nosso projeto:

Eles ficarão assim mas não se assuste rs

![imports](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3i3i72ps8tp4iq1dkl0.png)

Em relação ao pacote cross _file, ele irá identificar os nossos arquivos, então além de importá-lo eu preciso também instanciar o XFile junto a uma matriz de bytes para ter acesso aos seus métodos e propriedades de metadados.

Vou fazer a importação do Uint8List e aqui vai uma explicação legal sobre isso:

![final xfile e Uint8List](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w8u30giraoicbpwylwvx.png)

A Uint8List é uma lista de comprimento fixo de inteiros não assinados de 8 bytes.
Mas de uma forma simples e divertida, imagine que você tenha um monte de brinquedos diferentes, certo? E às vezes você quer organizar em grupos diferentes e especiais. A UintList8 é como uma caixa onde você pode guardar coisas, mas é especial porque só guarda números pequenos entre 0 e 255.


Então nessa linha de código:

```
final List<(XFile file, Uint8List bytes)> _list = [];
```
Está criando uma lista chamada _list que é uma lista de pares, onde cada par consiste em dois objetos, sendo um o XFile e o outro o Uint8List, dessa forma o XFile representa o arquivo em si e o Uint8List os bytes desse arquivo.

E isso tudo é útil porque em alguns casos você quer acessar tanto o arquivo, quando os seus bytes então faz sentido agrupá-los dessa forma, como é o nosso caso. 

Dando continuidade…

Adicionei essas propriedades para centralizar o nosso widget:

![Center](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q2c10cyzo26hnoz3bv5l.png)

Adicionei o DropTarget(desktop_drop) que cuidará dos eventos de drop e drag do nosso arquivo em pdf.

![droptarget](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wv44w7ykuoofdvqfc5e2.png)

Estilizei o widget como queria e agora vamos deixar ele funcional

Crio um booleano iniciando como falso, para criar um estado no futuro: 

```
bool isHovering = false;

```

Basicamente essa função basicamente faz a leitura do bytes e os adiciona na _list com o xFiles de forma assíncrona.

![setfile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0spk0z6t8a68w7xjq52g.png)

 Essa função seleciona um ou mais arquivos essa condição no final quer dizer que se o resultado for diferente de null ele irá selecionar o arquivo e colocar no 'result'

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rsujg4k9k3048jihnao7.png)

Quando o usuário soltar os arquivos na área que escolhi, essa função vai processar os arquivos que foram soltos.

![dragfile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wuc2k8kzahypma7fjcmw.png)

Já nessa nossa última função assíncrona, vamos apenas deletar o par de Xfile e Uint8List que representa o nosso arquivo que fizemos o upload.

![deletefile](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d28iasl3smwvwzl29bf5.png)

Por fim, fiz as alterações necessárias no nosso widget DropTarget para ligar os estados e deixar a nossa área funcional.


![funcional](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/byoptxwq094l9pq2lhs4.png)

Mas ainda faltam alguns detalhes.. 

Agora preciso criar um widget onde mostrará meu arquivo quando ele subir ou for carregado, assim saberei que deu tudo certo e posso excluí-lo futuramente caso precise.

E essa aqui foi a minha solução para isso, envolvi todo o conteúdo do DropTarget em uma coluna e no final adicionei uma fila com icone e texto para representar o meu arquivo.

![arquivo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jz81qcqsicm0b56j69qe.png)

Enfim, temos o nosso Widget completo do inicio ao fim esse aqui é o resultado final:

![resultado 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ze3mijwrgkso5zep1q7.png)

![resultado 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/demh94cy90z6qijq09de.png)

![resultado 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3p5gfnenzla6sgke4al.png)

Muito obrigada pela atenção 🩵🩵✌️

Agradecimento especial aos meus chefinhos, ao arthur e lizandra que me inspiraram a fazer o widget, ao pessoal da devs norte que me motivaram a escrever por aqui e muito obrigada a todos os demais que de alguma forma única contribuíram para que eu chegasse aqui.


Caso você queira ver o meu código desse tutorial, ele se encontra nesse link: https://github.com/suamirochadev/upload-widget-flutter

Referências: 
- [Drag and Drop Flutter Buil Show](https://youtu.be/c6BPtrU0M7I?si=69U577eSw-T5XV6k)
- [Flutter Tutorial Drag and Drop File Upload Drop Files](https://youtu.be/pZdJX3PAydQ?si=JqTHbrtd_AaPNxrN)
- [Flutter Desktop Drag and Drop](https://youtu.be/o9LuC4eqWPg?si=22GTBpLbQim-lPNl)
- [Package Cross File](https://pub.dev/packages/cross_file)
- [Package Desktop Drop](https://pub.dev/packages/desktop_drop)
- [Package Picker](https://pub.dev/packages/file_picker)