Android

3 mar, 2017

Crie layouts flexíveis com FlexboxLayout

Publicidade

Artigo de Takeshi Hagikura, publicado originalmente pelo Android Developers Blog. A tradução foi feita pela Redação iMasters com autorização.

***

No Google I/O, no ano passado, anunciamos o ConstraintLayout, que permite criar layouts complexos, mantendo uma hierarquia de exibição plana. Ele também é totalmente suportado no Visual Layout Editor
do Android Studio.

Ao mesmo tempo, abrimos o código do FlexboxLayout para trazer as mesmas funcionalidades do módulo CSS Flexible Layout para Android. Aqui estão alguns casos em que o FlexboxLayout é particularmente eficaz.

FlexboxLayout pode ser interpretado como um LinearLayout avançado porque ambos os layouts alinham suas visualizações filhas sequencialmente. A diferença significativa entre LinearLayout e FlexboxLayout é que FlexboxLayout tem um recurso para wrapping.

Isso significa que se você adicionar o atributo flexWrap=”wrap”, o FlexboxLayout coloca uma visualização para uma nova linha se não houver espaço suficiente na linha atual, como mostrado na figura abaixo.

Um layout para vários tamanhos de tela

Com essa característica em mente, vamos considerar um caso em que você deseja colocar visualizações de forma sequencial, mas que tenha que fazer com que elas se movam para novas linhas se o espaço disponível mudar (devido a um fator de dispositivo, a orientação muda ou janela redimensiona no modo multijanela).

Retrato do Nexus5X

Paisagem do Nexus5X

Pixel C com o modo multijanela ativado, linha divisória à esquerda.

Pixel C com o modo multijanela ativado, linha divisória no meio.

Pixel C com o modo multijanela ativado, linha divisória à direita.

Você precisará definir vários layouts DP-bucket (como layout-600dp, layout-720dp, layout-1020dp) para lidar com vários tamanhos de tela com layouts tradicionais como LinearLayout ou RelativeLayout. Mas o diálogo acima é construído com um único FlexboxLayout.

A técnica utilizada no exemplo é definir o flexWrap=”wrap” como explicado acima,

<com .google.android.flexbox.flexboxlayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     app:flexwrap="wrap">

Então, você pode obter o seguinte layout onde as visualizações filhas estão alinhadas a uma nova linha em vez de transbordar seu pai.

Outra técnica que eu gostaria de destacar é definir o atributo layout_flexGrow para um filho individual. Isso ajuda a melhorar a aparência do layout final quando o espaço livre está sobrando. O atributo layout_flexGrow funciona de forma semelhante ao atributo layout_weight no LinearLayout. Isso significa que o FlexboxLayout distribuirá o espaço restante de acordo com o valor layout_flexGrow definido para cada filho na mesma linha.

No exemplo abaixo, ele assume que cada filho tem o atributo layout_flexGrow definido como 1, de modo que o espaço livre será distribuído uniformemente para cada um deles.

<android .support.design.widget.TextInputLayout
     android:layout_width="100dp"
     android:layout_height="wrap_content" 
     app:layout_flexgrow="1">

Você pode verificar o arquivo layout xml completo no repositório GitHub.

Integração RecyclerView

Outra vantagem do FlexboxLayout é que ele pode ser integrado com o RecyclerView. Com a versão mais recente da versão alfa, o novo FlexboxLayoutManager estende o RecyclerView.LayoutManager, e agora você pode fazer uso das funcionalidades do Flexbox em um container rolável de maneira muito mais eficiente em termos de memória.

Observe que você ainda pode conseguir um container Flexbox com FlexboxLayout embrulhado com ScrollView. Mas você provavelmente experimentará jankiness ou até mesmo um OutOfMemoryError se o número de itens contidos no layout for grande, como FlexboxLayout não leva em consideração a reciclagem de visualizações que vão fora da tela enquanto o usuário percorre.

(Se você quiser saber mais sobre o RecyclerView em detalhes, pode conferir os vídeos da equipe de ferramentas do Android UI, como 1, 2)

Um exemplo do mundo real em que a integração do RecyclerView é útil é para aplicativos como o app Google Fotos ou apps do Google Notícias, ambos esperam um grande número de itens ao mesmo tempo em que precisam lidar com vários tamanhos de itens.

Um exemplo é encontrado no aplicativo de demonstração no repositório FlexboxLayout. Como você pode ver no repositório, cada imagem mostrada no RecyclerView tem uma largura diferente. Mas, definindo a configuração flexWrap para embrulhar,

FlexboxLayoutManager layoutManager = new FlexboxLayoutManager();
layoutManager.setFlexWrap(FlexWrap.WRAP);

e definir o atributo flexGrow (como você pode ver, você pode configurar os atributos através FlexboxLayoutManager e FlexboxLayoutManager.LayoutParams para atributos filhos em vez de configurá-los a partir de xml) para um valor positivo para cada filho,

void bindTo(Drawable drawable) {
  mImageView.setImageDrawable(drawable);
  ViewGroup.LayoutParams lp = mImageView.getLayoutParams();
  if (lp instanceof FlexboxLayoutManager.LayoutParams) {
    FlexboxLayoutManager.LayoutParams flexboxLp = 
        (FlexboxLayoutManager.LayoutParams) mImageView.getLayoutParams();
    flexboxLp.setFlexGrow(1.0f);
  }
}

Você pode ver que cada imagem se encaixa dentro do layout muito bem, independentemente da orientação da tela.

Se você gostaria de ver o exemplo completo do FlexboxLayout, você pode verificar:

O que vem a seguir?

Confira a documentação completa de outros atributos para criar layouts flexíveis adaptados às suas necessidades. Estamos muito abertos para ouvir seus comentários, se você encontrar quaisquer problemas ou solicitações de recursos, por favor, registre uma issue no repositório GitHub.

***

Este artigo é do Android Developers Blog. Ele foi escrito por Takeshi Hagikura. A tradução foi feita pela Redação iMasters com autorização. Você pode acessar o original em: https://android-developers.googleblog.com/2017/02/build-flexible-layouts-with.html.