Programação para a Plataforma Android – Aula 5 Sudoku • Refinando layouts • Lidando com telas em modo paisagem • Invocando a@vidades dentro de a@vidades • Usando temas para melhorar layouts • Depurando via o console de saída • Carregando uma a@vidade Sudoku • Sudoku é um jogo de raciocínio, cujo obje@vo é preencher uma matriz de 9x9 casas com números inteiros entre 1 e 9 inclusive, de tal forma que nenhuma linha, coluna ou diagonal possua números iguais. Este exemplo foi retirado do Capítulo 3 do livro Hello, Android (The Pragmatic Programmers) Por Ed Burnette Visão Geral do Jogo Prefs Sudoku Game About PuzzleView Keypad rve Para que se essas cada uma d classes? Visão Geral do Jogo Prefs Sudoku Game About PuzzleView Keypad Criando o projeto Sudoku.java A Primeira A@vidade package com.aula5; import android.app.Ac@vity; import android.os.Bundle; public class Sudoku extends Ac@vity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } } main.xml O Layout Principal e s o m o c r e prev o n a main.xml O Layout Principal main.xml O Layout Principal r Como muda fundo? values/colors.xml Cores também são recursos #3500ffff main.xml Margens …. nar Como adicio tre n e m e g r a uma m o os botões e tela? a d o r t e m í r pe main.xml Alinhamento …. O que são dip’s? r Isto vai da mais trabalho… Como centralizar os botões verticalmente? main.xml Formatação de Fonte Não dá para aumentar o tamanho do título não? main.xml Inferface Final O que é “sp”? Unidades de Medida px (pixels): pontos na tela. in (polegadas): tamanho real (medido por régua). mm (milímetros): tamanho real. pt (pontos): 1/72 de uma polegada. dp (density‐independent pixels): em uma tela com 160 pontos por polegada, 1dp = 1px. Se forem 320 pontos, então 1dp = 2px, etc. • sp (scale‐independent pixels): mesmo que dp, porém ajustável ao tamanho da fonte. • • • • • android:textSize="22sp" > android:background="#FF22FF22" > android:textSize="22sp" > android:background="#FF22FF22" > android:textSize="22sp" > android:background="#FF22FF22" > Exemplo de Escalas Layout de Paisagem • Muitos smartphones possuem um layout para o modo de paisagem, chamado quando viramos o aparelhos. • Nosso layout de paisagem ficou assim: • Qual o problema desse layout? • E como resolvê‐lo? Layout de Paisagem • É possível definir um layout de paisagem editando o arquivo res/layout-land/ main.xml. • Como criar o layout abaixo? layout‐land/main.xml Tabelas E se eu removesse esse pedacinho de texto aqui? Não fica tão legal… layout‐land/main.xml Espaçamento ria a a c fi o Com eu e s o ã ç aplica os e s s e v remo s de o d n a com to? n e m a ç espa Também não ficaria muito legal… layout‐land/main.xml Botão About • O que poderíamos fazer com o botão about? – Outras aplicações possuem uma funcionalidade assim? – Como implementá‐la? About.java Ac@vity About import android.app.Activity; import android.os.Bundle; Como é o código do layout de nossa atividade? public class About extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.about); } } about.xml Um Layout para About erve s e u q Para de o p i t e ess layout? about.xml Um Layout para About ao c fi e d n Mas o e texto qu s na mo e r a x i e d janela? strings.xml strings.xml Certo… mas ainda falta integrar essa nova atividade com o botão About. Sudoku Android Sudoku Con?nue New Game About Exit About Android Sudoku \ Sudoku is a logic‐based number placement puzzle. Star;ng with a par;ally completed 9x9 grid, the ade d i v objec;ve is to fill the grid so that each i t a a o Com row, each column, and each of the 3x3 boxes e ser v e d t u o b A (also called blocks) contains the digits invocada? 1 to 9 exactly once. manifest.xml O Manifesto • Para adicionar‐se uma nova a@vidade, é preciso modificar o arquivo manifest.xml. eé u q o , a Agor ara p o s i c pre ar a t n e m e impl t? u o b A e d ativida Sudoku.java Relacionamento entre A@vidades • Uma a@vidade pode invocar outra, via objetos chamados Intenções (Intents). public void onCreate(Bundle savedInstanceState) { Pergunta repetida: super.onCreate(savedInstanceState); como se dá a setContentView(R.layout.main); View aboutBulon = findViewById(R.id.about_bu5on); amarração entre botão e evento? aboutBulon.setOnClickListener(this); } public void onClick(View v) { switch (v.getId()) { case R.id.about_bu5on: Intent i = new Intent(this, About.class); startAc@vity(i); break; Lembre‐se: } } public class Sudoku extends Ac@vity implements OnClickListener De volta ao Manifesto • Se a a@vidade não exis@r por si mesma, e não quisermos exportá‐la para outras aplicações, então podemos simplificar o manifesto: Caixa de Diálogo • Seria mais interessante que a a@vidade About fosse mostrada como uma caixa de diálogo. • Como podemos modificar nossa aplicação para obtermos essa caixa de diálogo? Temas • Android permite que desenvolvedores criem Temas. ? • Temas são como arquivos de formato CSS. • Já existem alguns temas prontos. ? Adicionando Configurações Menu de preferências: Adicione um menu à sua aplicação, de tal forma que o usuário possa configurar o ambiente de jogo. • O usuário deveria ser capaz de escutar música enquanto brinca. • E ele poderia pedir dicas para a aplicação. • Essas opções podem ser configuradas via um menu que dispara a atividade de configuração string.xml string.xml • Vamos criar algumas strings que nos auxiliarão na construção do menu: Configurações... Preferências do Sudoku s Música Tocar música de fundo Dicas Mostrar dicas durante o jogo Novamente: por que criar strings em strings.xml? Quais strings devem ficar lá? Tudo bem, mas vocês lembram como inserir o menu em nossa aplicação? O Layout do Menu • O ambiente de desenvolvimento Android define uma pasta menu, em que é definido o layout do menu da aplicação. menu/menu.xml O Layout do Menu certo? Sudoku.java A@vando o Menu @Override public boolean onCreateOp@onsMenu(Menu menu) { super.onCreateOp@onsMenu(menu); MenuInflater inflater = getMenuInflater(); Com inflater.inflate(R.menu.menu, menu); o ser o deveria return true; l } Pref ayout de s? @Override public boolean onOp@onsItemSelected(MenuItem item) { switch (item.getItemId()) { E como deveria ser case R.id.se_ngs: essa atividade Prefs, startAc;vity(new Intent(this, Prefs.class)); que modifica as return true; preferêncais do } return false; usuário? } A Caixa de Preferências • Podemos usar botões de verificação! mo o c s Ma tar n e m imple out? y a l e s es se~ngs.xml Caixa de Preferências E a implementação da atividade em si? Prefs.java A A@vidade Prefs import android.os.Bundle; import android.preference.PreferenceAc@vity; public class Prefs extends PreferenceAc@vity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.layout.se_ngs); } } O que é esse método aqui? E o que está faltando para usarmos a atividade? Adicionar a A@vidade ao Manifesto Níveis de Dificuldade: Quando o usuário clicar em “new game”, ele deverá receber um menu de contexto, com três opções de dificuldade: fácil, médio e difícil. Seria legal um pouco de música não? Bom, isso fica para um próximo capítulo. Por hor a, nos pre vamos ocupar com o b ot “new ga ão me” Por onde ? os m a ç e m co Registrando um Evento main.xml • Precisamos de um iden@ficador para o botão que começará o jogo: Sudoku.java • E precisamos de um escutador de eventos para o novo botão: @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); … View newBu1on = findViewById(R.id.new_bu1on); newBu1on.setOnClickListener(this); } Níveis de Dificuldade Sudoku.java public void onClick(View v) { switch (v.getId()) { … case R.id.new_bulon: openNewGameDialog(); break; } } private void openNewGameDialog() { new AlertDialog.Builder(this) .setTitle(R.string.new_game_;tle).setItems( R.array.difficulty, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); Existem alguns } }).show(); recursos que } precisamos private void startGame(int i) { definir. Log.d(TAG, "clicked on " + i); } E há também de o ã ç r o p a m u coisas . misteriosas Mais Strings… strings.xml Dificuldade Fácil Médio Di‚cil E um arranjo: values/array.xml @string/easy_label @string/medium_label @string/hard_label Sudoku.java Console de Saída public void onClick(View v) { switch (v.getId()) { … O que acontece case R.id.new_bulon: quando alguém openNewGameDialog(); clica no botão break; “new game”? } } private void openNewGameDialog() { new AlertDialog.Builder(this) .setTitle(R.string.new_game_@tle).setItems( R.array.difficulty, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); } }).show(); } private void startGame(int i) { Log.d("Sudoku", "clicked on " + i); } Console de Saída public void onClick(View v) { switch (v.getId()) { … case R.id.new_bulon: openNewGameDialog(); break; } } private void openNewGameDialog() { new AlertDialog.Builder(this) .setTitle(R.string.new_game_@tle).setItems( R.array.difficulty, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); } }).show(); } private void startGame(int i) { Log.d(”Sudoku", "clicked on " + i); } Ainda o Manifesto O que aconte ceria se apagás semos a decla ração da ativi dade no mani festo? Usando o Console • Observaríamos a seguinte mensagem no console: android.content.ActivityNotFoundE xception: Unable to find explicit activity class {com.aula5/ com.aula5.About}; have you declared this activity in your AndroidManifest.xml? Padrão de Projetos Builder public void onClick(View v) { switch (v.getId()) { … case R.id.new_bulon: openNewGameDialog(); break; } } private void openNewGameDialog() { new AlertDialog.Builder(this) .setTitle(R.string.new_game_@tle).setItems( R.array.difficulty, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); } O que é o }).show(); padrão de } private void startGame(int i) { projetos Log.d(TAG, "clicked on " + i); Builder? } Padrão de Projetos Builder • Builder é uma forma de separar o código de construção do objeto da lógica do programa. – Alguns objetos são formados por vários componentes, e a única diferença entre eles é a forma como esses componentes são arranjados. new AlertDialog.Builder(this) .setTitle(R.string.new_game_@tle).setItems( R.array.difficulty, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { startGame(i); } }) Padrão de Projetos Builder Como sair do jogo? Re@rado de hlp://en.wikipedia.org/wiki/Builder_palern Terminando o Jogo • Implemente o tratador de eventos que seria a@vado caso clicássemos sobre o botão Exit. Na verdade, esse botão não é muito necessário. Porque? Terminando o Jogo E tendo terminado a public void onClick(View v) { atividade, como switch (v.getId()) { podemos começacase R.id.about_bulon: Intent i = new Intent(this, About.class); la novamente? } } startAc@vity(i); break; case R.id.new_bulon: openNewGameDialog(); break; case R.id.exit_bu1on: finish(); break; Carregando A@vidades • Todas as a@vidades testadas estão disponíveis em modo de emulação: