Escrevendo um aplicativo Android para fãs de filmes - Parte 2 (Design)



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.

Tudo bemRuim



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.

Para o primeiro casoPara o segundo caso



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.

Source: https://habr.com/ru/post/pt461249/


All Articles