Programação para Dispositivos Móveis: Material Design
Guilherme Antonio Borges
guilhermeborges.pf@gmail.com
Conteúdo de hoje
2
Conteúdo de hoje
3
Introdução Material Design
4
Material Design: Exemplos de Guias
5
Material Design: Exemplos de Guias
6
Material Design: Exemplos de Guias
7
Material Design
8
Material Design
9
Compatibilidade com Versões Anteriores
10
dependencies {
implementation 'com.android.support:appcompat-v7:26.1.0'
...
}
// O Android 5.0 ou superior�if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){� // Pode executar uma nova API�} else {� // Implementa determinada funcionalidade de outra maneira�}
Tema Material
11
Configurando o Tema Material
12
Configurando o Tema Material
13
Arquivo: /app/res/values/syles.xml
<resources>�� <!-- Base application theme. -->� <style
name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar">� <!-- Customize your theme here. -->� <item name="colorPrimary">@color/colorPrimary</item>� <item name="colorPrimaryDark">@color/colorPrimaryDark</item>� <item name="colorAccent">@color/colorAccent</item>� </style>�
<style name="AppTheme.NoActionBar">� <item name="windowActionBar">false</item>� <item name="windowNoTitle">true</item>� </style>��</resources>
Configurando o Tema Material
14
Arquivo: /app/res/values/syles.xml
<resources>�� <!-- Base application theme. -->� <style
name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar">� <!-- Customize your theme here. -->� <item name="colorPrimary">@color/colorPrimary</item>� <item name="colorPrimaryDark">@color/colorPrimaryDark</item>� <item name="colorAccent">@color/colorAccent</item>� </style>�
<style name="AppTheme.NoActionBar">� <item name="windowActionBar">false</item>� <item name="windowNoTitle">true</item>� </style>��</resources>
Os arquivos styles.xml e as configurações são geradas automaticamente se durante a criação do projeto a aplicação for criada usando o tema material
Configurando o Tema Material
15
Arquivo: /app/res/values/syles.xml
<resources>�� <!-- Base application theme. -->� <style
name="AppTheme"
parent="Theme.AppCompat.Light.DarkActionBar">� <!-- Customize your theme here. -->� <item name="colorPrimary">@color/colorPrimary</item>� <item name="colorPrimaryDark">@color/colorPrimaryDark</item>� <item name="colorAccent">@color/colorAccent</item>� </style>�
<style name="AppTheme.NoActionBar">� <item name="windowActionBar">false</item>� <item name="windowNoTitle">true</item>� </style>��</resources>
Cores são definidas no arquivo colors.xml
Arquivo: /app/res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>�<resources>� <color name="colorPrimary">#26a69a</color>� <color name="colorPrimaryDark">#303f9f</color>� <color name="colorAccent">#FF4081</color>�</resources>
Paleta de Cores
16
Elevação de Views
17
Exemplo o impacto da elevação views
18
Elevação de views
19
<android.support.v7.widget.CardView� android:id="@+id/card1"� android:layout_width="match_parent"� android:layout_height="40dp"� android:layout_marginLeft="32dp"� android:layout_marginRight="32dp"� android:layout_marginTop="32dp"� app:cardElevation="8dp" />��<android.support.v7.widget.CardView� android:id="@+id/card2"� android:layout_width="match_parent"� android:layout_height="40dp"� android:layout_marginLeft="32dp"� android:layout_marginRight="32dp"� android:layout_marginTop="32dp"� app:cardElevation="3dp" />
Elevação de views
20
Elevação (DP) | Componente |
16 dp | Nav drawer Modal bottom Sheet |
12 dp | Floating action button (FAB - pressed) |
8 dp | Card View (when picked up) Raised button (pressed state) |
6 dp | Floating action button (FAB) Snackbar |
2 dp | Card View |
Floating Action Button (FAB)
21
Exemplo de FAB
22
Arquivo: /app/res/layout/activity_testa_fab.xml
<?xml version="1.0" encoding="utf-8"?>�<android.support.design.widget.CoordinatorLayout� xmlns:android="http://schemas.android.com/apk/res/android"� xmlns:app="http://schemas.android.com/apk/res-auto"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <include layout="@layout/conteudo_tela_testa_fab"/>�� <android.support.design.widget.FloatingActionButton� android:id="@+id/fab"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_gravity="bottom|end"� android:layout_margin="16dp"� app:backgroundTint="@color/colorAccent"� app:elevation="8dp"� app:fabSize="normal"� app:srcCompat="@android:drawable/ic_dialog_email" />
�</android.support.design.widget.CoordinatorLayout>
Exemplo de FAB
23
Arquivo: /app/res/layout/activity_testa_fab.xml
<?xml version="1.0" encoding="utf-8"?>�<android.support.design.widget.CoordinatorLayout� xmlns:android="http://schemas.android.com/apk/res/android"� xmlns:app="http://schemas.android.com/apk/res-auto"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <include layout="@layout/conteudo_tela_testa_fab"/>�� <android.support.design.widget.FloatingActionButton� android:id="@+id/fab"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_gravity="bottom|end"� android:layout_margin="16dp"� app:backgroundTint="@color/colorAccent"� app:elevation="8dp"� app:fabSize="normal"� app:srcCompat="@android:drawable/ic_dialog_email" />
�</android.support.design.widget.CoordinatorLayout>
Exemplo de FAB
24
Arquivo: /app/res/layout/activity_testa_fab.xml
<?xml version="1.0" encoding="utf-8"?>�<android.support.design.widget.CoordinatorLayout� xmlns:android="http://schemas.android.com/apk/res/android"� xmlns:app="http://schemas.android.com/apk/res-auto"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <include layout="@layout/conteudo_tela_testa_fab"/>�� <android.support.design.widget.FloatingActionButton� android:id="@+id/fab"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_gravity="bottom|end"� android:layout_margin="16dp"� app:backgroundTint="@color/colorAccent"� app:elevation="8dp"� app:fabSize="normal"� app:srcCompat="@android:drawable/ic_dialog_email" />
�</android.support.design.widget.CoordinatorLayout>
O conteúdo da tela fica em arquivo separado:
/app/res/layout/conteudo_tela_testa_fab.xml
Facilita reuso de código!
Exemplo de ação com FAB em Java
25
public class FloatActivity extends AppCompatActivity {�� @Override� protected void onCreate(Bundle savedInstanceState) {� super.onCreate(savedInstanceState);� setContentView(R.layout.activity_testa_fab);�� FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);� fab.setOnClickListener(new View.OnClickListener() {� @Override� public void onClick(View view) {� // código da ação aqui!� }� });� }��}
Exemplo de ação com FAB em Java
26
public class FloatActivity extends AppCompatActivity {�� @Override� protected void onCreate(Bundle savedInstanceState) {� super.onCreate(savedInstanceState);� setContentView(R.layout.activity_testa_fab);�� FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);� fab.setOnClickListener(new View.OnClickListener() {� @Override� public void onClick(View view) {� // código da ação aqui!� }� });� }��}
Card View
27
Exemplos de Card View
28
Card View
29
dependencies {� ...� implementation 'com.android.support:cardview-v7:26.1.0'�}
<?xml version="1.0" encoding="utf-8"?>�<LinearLayout� xmlns:android="http://schemas.android.com/apk/res/android"� xmlns:card_view="http://schemas.android.com/apk/res-auto"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <android.support.v7.widget.CardView� android:layout_width="match_parent"� android:layout_height="100dp"� android:layout_marginEnd="8dp"� android:layout_marginStart="8dp"� android:layout_marginTop="8dp"� card_view:cardBackgroundColor="@color/cardview_light_background"� card_view:cardElevation="3dp"� card_view:contentPadding="6dp">�� <TextView� android:id="@+id/textView2"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_gravity="center"� android:text="Hello World" />� </android.support.v7.widget.CardView>��</LinearLayout>
Card View
30
dependencies {� ...� implementation 'com.android.support:cardview-v7:26.1.0'�}
<?xml version="1.0" encoding="utf-8"?>�<LinearLayout� xmlns:android="http://schemas.android.com/apk/res/android"� xmlns:card_view="http://schemas.android.com/apk/res-auto"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <android.support.v7.widget.CardView� android:layout_width="match_parent"� android:layout_height="100dp"� android:layout_marginEnd="8dp"� android:layout_marginStart="8dp"� android:layout_marginTop="8dp"� card_view:cardBackgroundColor="@color/cardview_light_background"� card_view:cardElevation="3dp"� card_view:contentPadding="6dp">�� <TextView� android:id="@+id/textView2"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_gravity="center"� android:text="Hello World" />� </android.support.v7.widget.CardView>��</LinearLayout>
Card View
31
dependencies {� ...� implementation 'com.android.support:cardview-v7:26.1.0'�}
<?xml version="1.0" encoding="utf-8"?>�<LinearLayout� xmlns:android="http://schemas.android.com/apk/res/android"� xmlns:card_view="http://schemas.android.com/apk/res-auto"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <android.support.v7.widget.CardView� android:layout_width="match_parent"� android:layout_height="100dp"� android:layout_marginEnd="8dp"� android:layout_marginStart="8dp"� android:layout_marginTop="8dp"� card_view:cardBackgroundColor="@color/cardview_light_background"� card_view:cardElevation="3dp"� card_view:contentPadding="6dp">�� <TextView� android:id="@+id/textView2"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_gravity="center"� android:text="Hello World" />� </android.support.v7.widget.CardView>��</LinearLayout>
Exercícios Parte 1
Exercícios Baseados nos exemplos.
32
Exercício 1: Menu
33
Id: btnNavegador
Id: btnIMC
Id: btnSair
Sem ID
Id: txtUltimoResultadoDeIMC
Exercício 2: Tela do Formulário de IMC
34
Id: edtPeso
Id: edtAltura
Id: btnCalcular
RecyclerView
35
RecyclerView
36
Padrão ViewHolder
37
RecyclerView
38
Usando RecyclerView
39
dependencies {� ...
implementation 'com.android.support:recyclerview-v7:26.1.0'�}
Arquivo: /app/res/layout/activity_recycler_view.xml
<?xml version="1.0" encoding="utf-8"?>�<LinearLayout� xmlns:android="http://schemas.android.com/apk/res/android"� android:layout_width="match_parent"� android:layout_height="match_parent">�� <android.support.v7.widget.RecyclerView� android:id="@+id/recyclerView"� android:layout_width="match_parent"� android:layout_height="wrap_content" />�</LinearLayout>
RecyclerView: LinearLayoutManager
40
public class RecyclerViewActivity extends AppCompatActivity {� private RecyclerView recyclerView;� private String[] valores = {"Um","Dois","Três","Quatro",...,"Dezesseis"};� @Override� public void onCreate( Bundle savedInstanceState) {� super.onCreate(savedInstanceState);� setContentView(R.layout.activity_recycler_view);�� // RecyclerView� recyclerView = (RecyclerView) findViewById(R.id.recyclerView);� recyclerView.setLayoutManager(new LinearLayoutManager(this));� recyclerView.setItemAnimator(new DefaultItemAnimator());� recyclerView.setHasFixedSize(true);� // Valores e Adapter� recyclerView.setAdapter(new LineAdapter<String>(this,valores));� }�}
RecyclerView: LinearLayoutManager
41
public class RecyclerViewActivity extends AppCompatActivity {� private RecyclerView recyclerView;� private String[] valores = {"Um","Dois","Três","Quatro",...,"Dezesseis"};� @Override� public void onCreate( Bundle savedInstanceState) {� super.onCreate(savedInstanceState);� setContentView(R.layout.activity_recycler_view);�� // RecyclerView� recyclerView = (RecyclerView) findViewById(R.id.recyclerView);� recyclerView.setLayoutManager(new LinearLayoutManager(this));� recyclerView.setItemAnimator(new DefaultItemAnimator());� recyclerView.setHasFixedSize(true);� // Valores e Adapter� recyclerView.setAdapter(new LineAdapter<String>(this,valores));� }�}
RecyclerView: LinearLayoutManager
42
public class RecyclerViewActivity extends AppCompatActivity {� private RecyclerView recyclerView;� private String[] valores = {"Um","Dois","Três","Quatro",...,"Dezesseis"};� @Override� public void onCreate( Bundle savedInstanceState) {� super.onCreate(savedInstanceState);� setContentView(R.layout.activity_recycler_view);�� // RecyclerView� recyclerView = (RecyclerView) findViewById(R.id.recyclerView);� recyclerView.setLayoutManager(new LinearLayoutManager(this));� recyclerView.setItemAnimator(new DefaultItemAnimator());� recyclerView.setHasFixedSize(true);� // Valores e Adapter� recyclerView.setAdapter(new LineAdapter<String>(this,valores));� }�}
Permite Adicionar Animações
RecyclerView: LinearLayoutManager
43
public class RecyclerViewActivity extends AppCompatActivity {� private RecyclerView recyclerView;� private String[] valores = {"Um","Dois","Três","Quatro",...,"Dezesseis"};� @Override� public void onCreate( Bundle savedInstanceState) {� super.onCreate(savedInstanceState);� setContentView(R.layout.activity_recycler_view);�� // RecyclerView� recyclerView = (RecyclerView) findViewById(R.id.recyclerView);� recyclerView.setLayoutManager(new LinearLayoutManager(this));� recyclerView.setItemAnimator(new DefaultItemAnimator());� recyclerView.setHasFixedSize(true);� // Valores e Adapter� recyclerView.setAdapter(new LineAdapter<String>(this,valores));� }�}
Diferente do ListView o RecyclerView não possui adaptadores padrão.
Necessário criar adaptador!
Template de Linha
44
<?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="wrap_content">�� <TextView� android:id="@+id/txtConteudo"� android:layout_width="wrap_content"� android:layout_height="28dp"� android:layout_marginStart="8dp"� android:layout_marginTop="8dp"� android:text="TextView"� app:layout_constraintStart_toStartOf="parent"� app:layout_constraintTop_toTopOf="parent" />�� <ImageButton� android:id="@+id/btnAdicionar"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_marginEnd="24dp"� android:layout_marginTop="8dp"� android:background="@color/cardview_shadow_end_color"� app:layout_constraintEnd_toStartOf="@+id/btnExcluir"� app:layout_constraintTop_toTopOf="parent"� app:srcCompat="@drawable/ic_add_gray_24dp" />�� <ImageButton� android:id="@+id/btnExcluir"� android:layout_width="wrap_content"� android:layout_height="wrap_content"� android:layout_marginEnd="16dp"� android:layout_marginTop="8dp"� android:background="@color/cardview_shadow_end_color"� app:layout_constraintEnd_toEndOf="parent"� app:layout_constraintTop_toTopOf="parent"� app:srcCompat="@drawable/ic_delete_gray_24dp" />��</android.support.constraint.ConstraintLayout>
Adaptador: Container de dados da linha
45
public class LineHolder extends RecyclerView.ViewHolder {�� public TextView title;� public ImageButton moreButton;� public ImageButton deleteButton;�� public LineHolder(View itemView) {� super(itemView);� title = (TextView) itemView.findViewById(R.id.txtConteudo);� moreButton = (ImageButton) itemView.findViewById(R.id.btnAdicionar);� deleteButton = (ImageButton) itemView.findViewById(R.id.btnExcluir);� }�}
Adaptador
46
public class LineAdapter<UserModel> extends RecyclerView.Adapter<LineHolder> {� private final List<UserModel> list;� private final Context context;� public LineAdapter(Context context, UserModel[] valores) {� this.context = context;� list = new ArrayList<>();� for (UserModel a : valores) {� list.add(a);� }� }�� @Override� public LineHolder onCreateViewHolder(ViewGroup parent, int viewType) {� return new LineHolder(LayoutInflater.from(context)� .inflate(R.layout.linha_recycler_view, parent, false));� }� @Override� public void onBindViewHolder(LineHolder holder, int position) {� holder.title.setText(list.get(position).toString());� holder.moreButton.setOnClickListener(new View.OnClickListener() {� @Override� public void onClick(View v) {� // faz algo� }� });� holder.deleteButton.setOnClickListener(new View.OnClickListener() {� @Override� public void onClick(View v) {� // faz algo� }� });� }� @Override� public int getItemCount() {� return list != null ? list.size() : 0;� }�}
Resultado Final
47
Referências
48
Referências
49
Fontes adicionais
50
Programação para �dispositivos móveis
Guilherme Antonio Borges
guilhermeborges.pf@gmail.com