
Olá Habr!
Neste artigo, consideraremos o processo de criação de telas com base nos layouts da
primeira parte .
Layout da tela
Tela inicial
A tela principal conterá fragmentos e menus de navegação. Vamos escrever o menu, depois de criar os ícones. Para fazer isso, abra a pasta
extraível , clique em
Novo e selecione
Ativos de vetor . Na janela que aparece, clique em
Clip Art e selecione os
ícones de colagem Settings ,
Search and
Content . O tamanho deixará 24 por 24.
Crie um arquivo de
strings na pasta
values e adicione as seguintes linhas:
<resources> <string name="title_home">Home</string> <string name="title_search">Search</string> <string name="title_settings">Settings</string> </resources>
Colocar todas as linhas em um arquivo simplificará a localização adicional do aplicativo.
Se você deseja adicionar outro idioma, por exemplo, russo, crie um arquivo com o atributo
Localidade , selecione o idioma desejado na lista
Idioma e adicione as mesmas linhas após traduzi-las.
Agora vamos diretamente para a criação do menu. Na pasta do
menu , crie o
arquivo de recurso de menu , nomeie-o "
bottom_nav_menu " e adicione o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/navigation_home" android:icon="@drawable/ic_content_paste_black_24dp" android:title="@string/title_home"/> <item android:id="@+id/navigation_search" android:icon="@drawable/ic_search_black_24dp" android:title="@string/title_search"/> <item android:id="@+id/navigation_settings" android:icon="@drawable/ic_settings_black_24dp" android:title="@string/title_settings"/> </menu>
Crie um arquivo de
estilos na pasta
valores e adicione o seguinte código:
<resources> <style name="MyLinearLayout"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:orientation">vertical</item> </style> </resources>
Os estilos criados são usados para visualizações para separar arquivos de marcação e arquivos de estilo. Eles contêm atributos de formatação responsáveis pela aparência e comportamento dos elementos. Primeiro, você pode gravar todos os atributos no arquivo de marcação e exportá-los para o arquivo de estilos clicando na seguinte combinação: RMB ->
Refatorar ->
Extrair ->
Estilo . O estilo estará disponível apenas nas vistas internas. Leia mais sobre isso
aqui .
Depois disso, você pode prosseguir diretamente para a criação de um layout para a Atividade. Na pasta de
layout , crie um
arquivo de recurso de layout , nomeie-o como "
nome_da_atividade " e adicione o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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" tools:context=".MainActivity" style="@style/MyLinearLayout"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/fragment_container" android:layout_marginBottom="?attr/actionBarSize" /> <android.support.design.widget.BottomNavigationView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/nav_view" app:menu="@menu/bottom_nav_menu" android:background="#6986c2" android:layout_gravity="bottom"/> </FrameLayout>
Vamos ver o que aconteceu.

Tela da guia Início
Abra o arquivo de
estilos e adicione estilos para a Barra de Ferramentas com um TextView e RecyclerView filho:
<style name="MyToolbar"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:background">#6986c2</item> </style> <style name="Toolbar_TextView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:gravity">center</item> </style> <style name="MyRecyclerView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="android:background">#fff</item> </style>
Adicione as seguintes linhas ao arquivo de
strings :
<string name="desc_home">Notification list</string> <string name="movie_title">Movie title</string> <string name="default_imdb_rating">IMDb rating: 7,4</string>
Agora crie um
layout chamado "
fragment_home " e adicione o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/MyLinearLayout"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_home" style="@style/MyToolbar"> <TextView android:text="@string/desc_home" style="@style/Toolbar_TextView"/> </android.support.v7.widget.Toolbar> <android.support.v7.widget.RecyclerView android:id="@+id/recView_home" style="@style/MyRecyclerView"/> </LinearLayout>
Adicione os ícones
Notificação e
Notificação nenhum à pasta de
desenho .
Vamos para a criação de um item da lista. Adicione o arquivo "
item_movie " à pasta de
layout e escreva o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView 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="120dp" app:cardCornerRadius="16dp" android:layout_marginLeft="16dp" android:layout_marginTop="8dp" android:layout_marginRight="16dp" android:layout_marginBottom="8dp" app:cardBackgroundColor="#00FFFFFF"> <ImageView android:layout_width="98dp" android:layout_height="98dp" app:srcCompat="@mipmap/ic_launcher" android:id="@+id/item_image" android:layout_gravity="center|start" android:layout_marginLeft="10dp"/> <TextView android:text="@string/movie_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/item_title" android:layout_marginTop="18dp" android:layout_marginLeft="120dp" android:textStyle="bold" android:textColor="@android:color/black" android:ellipsize="end" android:maxLines="1" android:layout_marginRight="16dp"/> <TextView android:text="@string/default_imdb_rating" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/item_rating" android:layout_marginLeft="120dp" android:layout_marginTop="50dp"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_notifications_black_24dp" android:id="@+id/item_notification" android:layout_gravity="bottom|right" android:layout_marginRight="16dp" android:layout_marginBottom="16dp" tools:ignore="VectorDrawableCompat"/> </android.support.v7.widget.CardView>
Vejamos o resultado:

Tela da guia Pesquisar
No arquivo de
strings , adicione o cabeçalho da barra de ferramentas:
<string name="desc_settings">Preferences</string>
E crie um
layout chamado "
fragment_search ", adicionando simultaneamente o seguinte bloco de código:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/MyLinearLayout"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar_search" style="@style/MyToolbar"> <android.support.v7.widget.SearchView android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/border_search_view" android:layout_marginRight="15dp" android:id="@+id/search_view"/> </android.support.v7.widget.Toolbar> <android.support.v7.widget.RecyclerView android:id="@+id/recView_search" style="@style/MyRecyclerView"/> </LinearLayout>
Vamos ver o resultado:

Tela para a guia Configurações
Essa tela acabou sendo a mais volumosa, porque possui poucos estilos de repetição.
Adicione o código para TextView e CardView ao arquivo de
estilos :
<style name="MyTextView"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:textStyle">bold</item> <item name="android:textColor">@android:color/black</item> <item name="android:layout_marginLeft">16dp</item> <item name="android:layout_marginTop">8dp</item> <item name="android:layout_marginBottom">8dp</item> <item name="android:typeface">normal</item> </style> <style name="MyCardView"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_margin">16dp</item> </style>
Adicione também mais algumas linhas ao arquivo de
strings :
<string name="imdb_rating">IMDb rating</string> <string name="default_rating">6</string> <string name="movie_genres">Movie genres</string>
Você também precisa adicionar o ícone de
borda Estrela à pasta de
desenho .
Crie um
layout chamado "
fragment_settings " e adicione o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" style="@style/MyLinearLayout" android:background="#fff"> <android.support.v7.widget.Toolbar style="@style/MyToolbar" android:id="@+id/toolbar_home" app:title="@string/desc_home"> <TextView android:text="@string/desc_settings" style="@style/Toolbar_TextView"/> </android.support.v7.widget.Toolbar> <android.support.v7.widget.CardView app:cardCornerRadius="16dp" app:cardBackgroundColor="#00FFFFFF" style="@style/MyCardView"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_star_border_black_24dp" android:layout_gravity="right" android:layout_marginRight="50dp" android:layout_marginTop="8dp" tools:ignore="VectorDrawableCompat"/> <TextView android:text="@string/default_rating" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rating_value" android:layout_gravity="right" android:layout_marginRight="40dp" android:layout_marginTop="8dp" android:textColor="#666666"/> <TextView android:text="@string/imdb_rating" android:id="@+id/textView" style="@style/MyTextView"/> <SeekBar style="@style/Widget.AppCompat.SeekBar.Discrete" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="10" android:progress="6" android:id="@+id/seek_bar" android:layout_marginLeft="16dp" android:layout_marginTop="50dp" android:layout_marginBottom="20dp" android:layout_marginRight="16dp"/> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView app:cardCornerRadius="16dp" app:cardBackgroundColor="#00FFFFFF" style="@style/MyCardView"> <TextView android:text="@string/movie_genres" style="@style/MyTextView"/> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00FFFFFF" android:layout_marginLeft="16dp" android:layout_marginTop="36dp" android:layout_marginBottom="16dp" android:layout_marginRight="16dp" android:id="@+id/recView_settings"/> </android.support.v7.widget.CardView> </LinearLayout>
Crie um item para a lista. Adicione o arquivo "
item_genre " à pasta de
layout e escreva o seguinte código:
<?xml version="1.0" encoding="utf-8"?> <CheckBox xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:text="@string/movie_genres" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/item_check_box" />
Vejamos o resultado:

Teste de projeto
Vamos ver com que frequência a mesma seção da tela é redesenhada, ou seja, trabalho extra está sendo feito.
Cor azul - redesenha uma vez. Bom
Cor verde - redesenha duas vezes. Otimização necessária.
Cor vermelha clara - redesenha
três vezes. Que pena.
Cor vermelha - redesenha mais de
4 vezes. Algo deu errado.
E se nada for pintado, o enredo não será redesenhado. Bom trabalho.
Por que tudo está vermelho na segunda captura de tela? Um plano de fundo branco foi adicionado a cada Layout, RecyclerView e CardView, o que causou a sobreposição de camadas. Este não é o caso no design descrito acima, o exemplo demonstra apenas a aplicação malsucedida da estilização.
Na primeira captura de tela, apenas um plano de fundo foi usado no LinearLayout para o fragmento Home, cujo redesenho foi cancelado programaticamente usando o seguinte método:
window.setBackgroundDrawable(null)
Vamos ver quanto tempo leva para renderizar quadros.
Cyan é responsável pelo tempo usado para criar e atualizar a Visualização.
A parte roxa representa o tempo necessário para transferir os recursos de renderização do fluxo.
Vermelho é a hora de desenhar.
Uma cor laranja indica quanto tempo o processador levou para aguardar a GPU concluir seu trabalho. É uma fonte de problemas com grandes quantidades. - Alexander Klimov
No nosso caso, quase todas as guias são desenhadas em menos de 16ms, ou seja, abaixo da barra verde. Se a barra for maior que esta linha, o programa poderá ficar mais lento.
Conclusão
No próximo artigo, consideraremos trabalhar com o servidor e, enquanto o autor o escreve, você pode avaliar o design atual na pesquisa abaixo.
Se algum ponto permanecer incerto, faça perguntas nos comentários.
Se você acha que o design (XML) pode ser simplificado ou aprimorado, escreva sobre ele.