ConstraintLayout, Melhor Performance no Android
(13931) (13)
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
CategoriaDesenvolvimento Web
Autor(es)Robert C. Martin
EditoraAlta Books
Edição1ª
Ano2023
Páginas416
Tudo bem?
Neste artigo vamos estar apresentando o ConstraintLayout do Android, um layout muito similar ao RelativeLayout, porém ainda mais flexível fazendo com que nós, developers Android, possamos evitar ainda mais os layouts aninhados.
Ai você pergunta: qual o problema em aninhar layouts?
O custo da renderização é maior, na maioria dos casos. Além de ser fonte de problemas de layout sendo utilizado sem necessidade, por exemplo.
Para melhor estudo sobre layouts e aninhamento entre esses, acesse essa página da documentação Android: Optimizing Layout Hierarchies.
Antes de prosseguir, não esqueça de se inscrever 📫na lista de e-mails do Blog para receber, em primeira mão, todos os conteúdos Android exclusivos do Blog.
No decorrer do conteúdo vamos abordar:
- Configuração Android Studio;
- Codificação necessária para utilizar o ConstraintLayout;
- Alterando layout já existente;
- Configuração de ConstraintLayout via Java API;
- Vídeo com a implementação passo a passo;
- Conclusão.
Configuração Android Studio
Essa é primeira vez, dentre os artigos do Blog, que houve a necessidade de instalar um novo Android Studio. Com a versão 2.1 ou menor você não conseguirá utilizar o ConstraintLayout, ao menos não com o novo UI Builder do Android Studio.
Pode parecer estranho, mas o ConstraintLayout e o Android Studio estão relacionados a ponto de que se um evolui o outro tende a evoluir também, digo, ambos, provavelmente, terão atualização de versão.
Antes de rodar os exemplos corretamente tive alguns problemas em utilizar o Android Studio 2.2 Preview 2 (clique no link para download) com a versão Alpha 4 do ConstraintLayout.
Qual tipo de problema?
Mais precisamente: a margem para widgets e layout (o ConstraintLayout) não funcionava, ao menos para o lado direito do ConstraintLayout. Outro bug era com as linhas dos widgets, essas atualizavam de posição, porém o conteúdo não.
Logo a solução foi utilizar a última versão disponível da library do ConstraintLayout, porém não foi trivial descobrir sobre a última versão. Nos principais tutoriais encontrados (primeiros resultados do Google) não há nada sobre ela.
Depois de já descarregada e instalada ao menos a versão 2.2 Preview 2 do Android Studio (isso mesmo, somente a atualização desse IDE via update option não funciona, você terá de baixar tudo novamente), clique no ícone do SDK Manager:
Então clique na aba SDK Tools e em seguida dê um check em ConstraintLayout for Android e clique em Apply:
Com isso você já poderá seguir com a versão mais estável (até a data desse post) do Android Studio e ConstraintLayout, e acredite, funciona sem problema algum (ao menos não evidente quanto na versão Alpha 4 do ConstraintLayout).
Antes de prosseguir com o código de exemplo você deve estar se perguntando: versão Alpha? É isso mesmo? Podemos já utilizar em produção?
Na documentação do ConstraintLayout não há nada informando para não utilizarmos mesmo que em Alpha. Até a versão Alpha 4 eu poderia seguramente lhe informar para nem mesmo testar devido a quantidade de bugs, incluindo os do UI Builder.
Porém com a versão Alpha 7, a princípio, está tudo ok. Sério! Inclusive no vídeo, logo no final do artigo, realizo vários testes mostrando o perfeito funcionamento do layout.
Obviamente que sabemos o risco que é utilizar uma versão Alpha, logo, depois de implementar em seu aplicativo, realize ao menos os testes mais óbvios para seu domínio do problema para depois decidir se vale ou não a pena colocar em produção com o novo layout.
Com isso podemos seguir para o código de exemplo.
Codificação necessária para utilizar o ConstraintLayout
A partir desse ponto, além dos códigos do projeto de exemplo vamos também estudar alguns pontos chaves do ConstraintLayout e do novo UI Builder do Android Studio.
Note que o Constraint do nome do layout é referente as restrições (ou limitações ou especificações) que podemos adicionar aos widgets (Views) dentro desse layout.
É possível utilizar o ConstraintLayout a partir da API 9, Android 2.3 (Gingerbread).
Vamos começar configurando o Gradle top level, build.gradle (Project: constraint-layout-start). Verifique se o seu está com configurações similares:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0-rc1'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Pode ser que o seu classpath esteja com uma versão diferente. Tente rodar o projeto mesmo assim, pois tentei somente com a versão acima. Caso surjam problemas, altere como para utilizar a versão indicada aqui.
Agora vamos ao Gradle App level, build.gradle (Module: app). Aqui somente as dependências são atualizadas:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "com.google.googleio"
minSdkVersion 22
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7' /* ADICIONE ESSA LINHA */
testCompile 'junit:junit:4.12'
}
Agora os códigos, na verdade, os passos no UI Builder do Android Studio. Devido a melhora no UI Builder é muito mais tranquilo utiliza-lo para a construção do layout do que diretamente codificar no XML.
Nesse início ainda vamos no código XML. Clique na aba Text e crie um layout chamado activity_main_update.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main_update"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.constraint.ConstraintLayout>
No UI Builder, depois de clicar na aba Design, você terá algo similar a isso:
Antes de prosseguir certifique-se de que o Autoconnect esteja bloqueado, logo nas ferramentas do UI Builder verifique se há o seguinte ícone:
Caso sim, clique nele para ficar da seguinte forma:
No decorrer do artigo vamos falar dessa opção, Autoconnect.
Agora no menu de Views lateral vá até Images & Medias, então clique e arraste para o device com o ConstraintLayout o item ImageView.
Caso tenha baixado o projeto deste artigo, selecione a imagem singapore assim que o dialog de imagens aparecer, caso contrário selecione qualquer uma. Depois deste passo terá algo como:
O primeiro (são três) constraint que iremos utilizar é o Resize Handle, representado pelos retângulos nos limites dos widgets no layout:
Com esse constraint é possível redimensiona-los, logo vamos colocar o ImageView em um tamanho melhor para trabalhar o layout e então posiciona-lo mais acima. Agora temos:
Note ao lado, na aba Properties, há as medições, largura e altura, exatas do ImageView. Com essa aba é possível acessar e alterar todos os atributos do widget.
Clicando em View all properties acessamos o restante dos atributos:
Nosso próximo passo é definir o atributo scaleType do ImageView com o valor centerCrop, como abaixo:
Agora podemos começar as vinculações do ImageView ao ConstraintLayout para que seja possível centralizar o widget no topo da tela.
Para isso vamos utilizar um outro constraint, Side Constraint Handle:
Clique no Side Handle de topo do ImageView e arraste até o topo do ConstraintLayout, assim que ficar com a bolinha verde, solte o clique:
Agora vamos repetir o processo para o Left Side Handle e para o Right Side Handle do ImageView, respectivamente ligando esses aos handles Left e Right (esquerdo e direito) do ConstraintLayout.
Logo teremos:
Ao lado, em Properties, logo no topo temos algumas definições importantes do widget que está sendo trabalhado, o ImageView:
O quadrado mais escuro ao centro representa o widget. As linhas dentro dele representam como serão trabalhadas as largura e altura, podendo essas terem as seguintes configurações:
- Fixed: O tamanho fixo e definido em DPs;
- Any Size: O widget terá o tamanho atualizado para ocupar os espaços em branco existentes entre as constraints (Side Handle) do eixo escolhido (esse é mais tranquilo de entender na prática). Não confunda o Any Size com o MATCH_PARENT, pois não são a mesma coisa;
- Wrap Content: mais comum com widget de texto. O tamanho será o suficiente para comportar o conteúdo.
Note que os tamanhos na vertical e horizontal podem ter tipos distintos de trabalho no widget, um pode ser Fixed e o outro Any Size, por exemplo.
As linhas externas ao quadrado mais escuro e com números ao lado representam as margens que o widget está utilizando para com widgets vizinhos ou até mesmo com o ConstraintLayout, caso do ImageView.
A Horizontal Bias somente está presente, pois o ImageView está com as constraints Side Handle da esquerda e direita sendo utilizadas, ou seja, permitindo que o widget seja movimentado na horizontal (eixo x), caso contrário o Horizontal Bias não apareceria.
Como teste, ligue também o Bottom Side Handle do ImageView ao Bottom Side Handle do ConstraintLayout e teste os movimentos no Vertical e Horizontal Bias.
Depois dos testes com os Bias como indicado acima, vamos as novas configurações do widget ImageView. Coloque a largura dele como WRAP_CONTENT. A altura como 203dp (essa escolha foi aleatória).
No quadrado interno clique nas linhas horizontais que estão como Fixed para colocá-las como Any Size. E para todas as margens coloque o valor 0. Assim temos:
Note que se você realizou os testes com os Bias Vertical e Horizontal, já pode remover o Bottom Side Handle do ImageView com o ConstraintLayout apenas clicando nesse Side Handle do ImageView.
Aproveitando o assunto "remove constraint", outras duas formas são via Remove Icon no widget:
Clicando nele todas as constraints definidas para o widget, digo, as Side Handle, serão removidas.
Logo no topo do UI Builder, tem um Remove Icon, clicando nele (se fizer isso, depois volte com as constraints colocadas até aqui) você irá remover todos os constraints do layout atual.
Note que estou trabalhando no Blue Print, mas é possível realizar as mesmas alterações de layout na tela real simulada ao lado da Blue Print.
Com isso podemos ver como se encontra o XML do layout. Logo abaixo no UI Builder clique na aba Text:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/singapore"
android:layout_width="wrap_content"
android:layout_height="203dp"
android:id="@+id/imageView8"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
Os atributos de ligação em ImageView são bem intuitivos, layout_constraintTop_toTopOf="parent", por exemplo, indica a ligação do topo do ImageView com o topo do ConstraintLayout, que nesse caso é o parent.
Caso fosse uma ligação com outro widget seria o id do widget o conteúdo do atributo.
Agora no topo do UI Builder clique no ícone do Autoconnect (voltamos!) para ativá-lo:
Logo depois, na aba de Views, clique e arraste um TextView logo para baixo do ImageView. Note as constraints sendo ligadas automaticamente:
O Autoconnect é uma funcionalidade que tem como objetivo realizar as conexões mais eficientes para o widget selecionado, isso de forma automática.
Porém (provavelmente devido a versão Alpha) não obtive bons resultados com ele ativado. Logo clique novamente no ícone do Autoconnect para desativá-lo e remova todas as constraints criadas para o TextView.
Deixe o TextView ainda no layout, somente remova as constraints dele clicando no icon de remoção de constraints desse widget.
Agora realize as seguintes alterações no TextView:
- Side Handle: Ligue o topo dele com o bottom do ImageView;
- Side Handle: Ligue o lado esquerdo dele com o lado esquerdo do ConstraintLayout (parent);
- Na aba Properties, mais precisamente no quadrado central, clique nas linhas verticais que estão como Fixed. Clique duas vezes até ficarem como Wrap Content;
- Logo abaixo, em layout_width, coloque 156dp;
- Então em text, coloque um texto grande, como: "It is a common misconception that using the basic layout structures leads to the most efficient layouts. However, each widget and layout you add to your application requires initialization, layout, and drawing".
Logo depois você deverá ter algo como:
E a seguinte nova configuração no XML do layout:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<TextView
android:text="..."
android:layout_width="156dp"
android:layout_height="wrap_content"
android:id="@+id/textView19"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/imageView8"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent" />
</android.support.constraint.ConstraintLayout>
Note que o TextView já tem configurado uma margem top e left, provavelmente em seu caso também estará, respectivamente, 8dp e 16dp.
Esses valores estão seguindo as especificações do Material Design Android. Caso estejam diferentes, logo em Properties os altere para terem os valores 8 para margem de topo e 16 para margem esquerda.
Agora na aba de Views, vá até Text Fields, clique e arraste o item Plain Text para ficar ao lado do TextView.
Ainda sem nenhuma constraint criada para o novo widget, vá até os ícones de topo do UI Builder e clique em Infer Constraints:
Logo depois coloque o cursor do mouse em cima do widget adicionado e veja que alguns constraints foram criados automaticamente.
Essa funcionalidade de inferência tenta fazer o que o Autoconnect faz com o widget, porém o Infer Constraint realiza a tarefa com todos os widgets ainda sem conexão.
Como no Autoconnect percebi que as ligações realizadas não foram mais eficientes que as que fiz na mão. Logo, remova as conexões criadas para o Plain Text e então realize as seguintes alterações nele:
- Side Handle: Ligue o topo dele com o bottom do ImageView;
- Side Handle: Ligue o lado esquerdo dele com o lado esquerdo do TextView;
- Side Handle: Ligue o lado direito dele com o lado direito do ConstraintLayout;
- Na aba Properties, mais precisamente no quadrado central, clique nas linhas horizontais que estão como Fixed. Clique uma vez para ficar como Any Size;
- Agora, nas linhas de margens esquerda, topo e direita do widget coloque respectivamente os valores: 16, 8 e 16.
Depois dessas atualizações no Plain Text, seu layout estará como:
E no XML terá um novo widget:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:text="Name"
android:ems="10"
android:id="@+id/editText7"
android:layout_marginStart="16dp"
tools:layout_constraintLeft_creator="1"
app:layout_constraintLeft_toRightOf="@+id/textView19"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.46"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/imageView8" />
</android.support.constraint.ConstraintLayout>
Agora para completar o layout vamos adicionar outros widgets.
Na aba de Views, clique em TextView. Agora arraste para logo abaixo do Plain Text. Em seguida coloque as seguintes configurações:
- Side Handle: Ligue o topo dele com o bottom do Plain Text;
- Side Handle: Ligue o lado esquerdo dele com o lado esquerdo do TextView adicionado inicialmente;
- Side Handle: Ligue o lado direito dele com o lado direito do ConstraintLayout;
- Na aba Properties, mais precisamente no quadrado central, clique nas linhas horizontais que estão como Fixed. Clique uma vez para ficar como Any Size;
- Agora nas linhas verticais do mesmo quadrado do passo acima, clique até ficar com o tipo Wrap Content;
- Nas linhas de margens esquerda, topo e direita do widget coloque respectivamente os valores: 16, 8 e 16;
- Logo abaixo na aba Properties, em text, coloque: "The Android SDK tools include a tool called Hierarchy Viewer that allows you to analyze your layout while your application is running.".
Com isso agora temos o seguinte layout:
Assim temos o novo widget no XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<TextView
android:text="The Android SDK tools include a tool called Hierarchy Viewer that allows you to analyze your layout while your application is running."
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/textView20"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/editText7"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toRightOf="@+id/textView19"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
Agora, novamente na aba de Views, na seção Widgets, clique e arraste um Button para o canto inferior direito do layout. Logo depois coloque as seguintes configurações:
- Side Handle: Ligue o topo dele com o bottom do último TextView adicionado;
- Side Handle: Ligue o bottom dele com o bottom do ConstraintLayout;
- Side Handle: Ligue o lado direito dele com o lado direito do ConstraintLayout;
- Na aba Properties, mais precisamente no quadrado central, clique nas linhas horizontais e verticais até ambas ficarem com o tipo Wrap Content, isso se já não estiverem assim;
- Ainda na aba Properties, vá no Vertical Bias e arraste para baixo o ícone até atingir o valor 0;
- Agora, nas linhas de margens topo, direita e fundo do widget coloque respectivamente os valores: 8, 16 e 16.
Aproveitando o embalo, adicione outro Button, agora ao lado do Button adicionado anteriormente. Dessa vez as configurações serão:
- Side Handle: Ligue o bottom dele com o bottom do ConstraintLayout;
- Side Handle: Ligue o lado direito dele com o lado direito do Button adicionado anteriormente;
- Na aba Properties, mais precisamente no quadrado central, clique nas linhas horizontais e verticais até ambas ficarem com o tipo Wrap Content;
- Agora, nas linhas de margens direita e fundo do widget coloque respectivamente os valores: 16 e 8.
Fique atento nas configurações do último Button adicionado, pois elas não são as mesmas que a do primeiro Button, aliás algumas configurações não são nem mesmo necessárias.
Notei isso. Por que as configurações de margem de topo e constraint de topo não são necessárias nesse widget?
Porque essas configurações já estão no primeiro Button adicionado. Essas servem somente para manter os Buttons do layout abaixo do TextView que o primeiro Button está conectado.
Caso contrário, assim que o device for colocado em modo Landscape os Buttons teriam grandes chances de ficarem sobre o TextView.
Com os novos widgets adicionados agora temos o seguinte layout:
E a seguinte nova configuração no arquivo XML de layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button11"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/textView20"
app:layout_constraintVertical_bias="1.0" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button12"
app:layout_constraintRight_toLeftOf="@+id/button11"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp" />
</android.support.constraint.ConstraintLayout>
Agora para abordar o último constraint Side Handle vamos adicionar um novo widget, um TextView. Coloque-o logo no canto inferior esquerdo do layout.
Expanda o Textview utilizando o constraint Resize Handle deixando ele com o tamanho aproximado a 83x41 dp. Logo depois note o ícone de nosso terceiro constraint, Baseline Handle:
Deixe o cursor do mouse alguns segundos parado em cima desse ícone e assim que ele começar a piscar clique e arraste a seta para o baseline do último Button adicionado, assim que fixar solte ele, como abaixo:
Agora podemos seguir com as demais configurações:
- Side Handle: Ligue o lado esquerdo dele com o lado esquerdo do ConstraintLayout;
- Em Properties clique nas linhas verticais e horizontais dentro do quadrado mais escuro até que elas fiquem com o tipo Wrap Content;
- Ainda em Properties, na margem referente ao lado esquerdo do ConstraintLayout coloque o valor 16.
Com essa nova atualização temos o novo layout:
E então o novo widget no XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
<TextView
android:text="TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView21"
app:layout_constraintBaseline_toBaselineOf="@+id/button12"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent" />
</android.support.constraint.ConstraintLayout>
Para que seja possível rodar sem problemas também em Landscape, mais precisamente para que tenha o scroll de tela, devemos adicionar o ScrollView no layout, logo faça a seguinte alteração no XML:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
</android.support.constraint.ConstraintLayout>
</ScrollView>
Agora executando o projeto temos na orientação Portrait:
E na orientação Landscape:
Note que em Landscape há um problema. O último TextView adicionado fica sobre o primeiro TextView incluído no layout.
Isso acontece, pois não há ligação entre esses TextView, digo, a ligação do topo do último TextView adicionado com o bottom do primeiro.
Logo realize as seguintes alterações no último TextView adicionado:
- Side Handle: Ligue o lado esquerdo dele com o lado esquerdo do ConstraintLayout;
- Side Handle: Ligue o bottom dele com o bottom do ConstraintLayout
- Side Handle: Ligue o topo dele com o topo do TextView acima dele;
- Em Properties clique nas linhas verticais e horizontais dentro do quadrado mais escuro até que elas fiquem com o tipo Wrap Content;
- Ainda em Properties, para as margens bottom, left e top coloque respectivamente os valores: 16, 16 e 8.
Executando o projeto novamente e testando diretamente em Landscape temos:
Note que assim que foi adicionado um novo Side Handle do eixo x o Baseline Handle do último TextView foi automaticamente removido, isso acontece, pois, a princípio, não é possível ter um Side Handle do eixo x e o constraint Baseline Handle definidos pelo mesmo widget.
Note que também não é possível criar vínculos entre um Side Handle de um eixo de um widget com um Side Handle de outro eixo de um outro widget.
Alterando layout já existente
Caso queira atualizar um layout existente para se tornar um ConstraintLayout siga as instruções aqui.
Abaixo da aba de Views tem uma aba Component Tree. No layout root (caso seja esse que você queira alterar) clique com o botão direito do mouse e logo em seguida clique em Convert ScrollView to ConstraintLayout:
A seguinte tela aparecerá:
Onde a primeira opção indica que o layout será refatorado com o intuito de acabar com os layouts aninhados e constraints serão utilizadas no lugar dos aninhamentos.
A segunda opção informa que os layouts referenciados dentro do layout atual não serão refatorados.
Configuração de ConstraintLayout via Java API
Apesar de eu não recomendar, você pode aplicar as configurações de ConstraintLayout via Java API, veja o código abaixo da MainActivity:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ConstraintLayout constraintLayout = new ConstraintLayout(this);
constraintLayout.setId( R.id.constraintLayout );
ConstraintLayout.LayoutParams lpCl = new ConstraintLayout.LayoutParams( ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.MATCH_PARENT );
constraintLayout.setLayoutParams( lpCl );
ImageView imageView = new ImageView(this);
imageView.setId( R.id.imageView );
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setImageResource(R.drawable.singapore);
lpCl = new ConstraintLayout.LayoutParams( ConstraintLayout.LayoutParams.WRAP_CONTENT, dpToPx(186) );
lpCl.topToTop = constraintLayout.getId();
lpCl.leftToLeft = constraintLayout.getId();
lpCl.rightToRight = constraintLayout.getId();
imageView.setLayoutParams(lpCl);
constraintLayout.addView(imageView);
TextView textView = new TextView(this);
textView.setText("...");
textView.setPadding( dpToPx(16), 0, 0, 0 );
lpCl = new ConstraintLayout.LayoutParams( dpToPx(126), ConstraintLayout.LayoutParams.WRAP_CONTENT );
lpCl.topToBottom = imageView.getId();
lpCl.leftToLeft = constraintLayout.getId();
lpCl.setMargins(0, dpToPx(8), 0, 0);
textView.setLayoutParams(lpCl);
constraintLayout.addView(textView);
setContentView(constraintLayout);
}
private int dpToPx(int dp){
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
}
Note que o código acima é apenas um trecho do código montado via UI Builder nesse artigo e no vídeo. Devido a qualidade do UI Builder recomendo a utilização dele para conseguir maior produção no desenvolvimento.
Note que foi necessário utilizar textView.setPadding(), pois o setMargins() do LayoutParams não funciona quando é em relação ao ConstraintLayout.
Abaixo um print do aplicativo rodando apenas com o código acima:
Com isso terminamos o projeto de teste com o ConstraintLayout.
Antes de prosseguir, não esqueça de se inscrever na 📫 lista de e-mails do Blog para receber semanalmente os conteúdos Android liberados aqui.
Se inscreva também no canal do Blog em YouTube Thiengo.
Vídeo com implementação passo a passo
Abaixo o vídeo com a implementação passo a passo do projeto desse artigo. Para acessar o código completo do projeto entre no GitHub dele: https://github.com/viniciusthiengo/constraint-layout.
Conclusão
Como já informado no início do artigo, o ConstraintLayout é uma excelente opção para aumento de performance na renderização dos layouts de seu aplicativo, provavelmente a melhor opção.
Isso porque esse layout é ainda mais flexível que o RelativeLayout permitindo que todas as Views fiquem bem alocadas em diferentes tipos de tela e também em diferentes orientações de tela.
Somente acompanhe o desenvolvimento desse layout caso for utilizá-lo em produção, pois ele, apesar de ter funcionado sem problemas nos testes aqui, ainda está em Alpha teste e sabemos que é possível ter vários problemas.
Curtiu o conteúdo? Não esqueça de compartilha-lo. E, por fim, de se inscrever na 📩 lista de e-mails, respondo às suas dúvidas também por lá.
Abraço.
Fontes
New Layout Editor with Constraint Layout
Using ConstraintLayout to design your views
Exploring the new Android ConstraintLayout
Android Studio 2.2 Preview - New UI Designer & Constraint Layout
Comentários Facebook