Cadastro de Alunos - facom.ufu.brbacala/ANDROID/AppAlunos.pdf · Começando pelo Cadastro ......
Transcript of Cadastro de Alunos - facom.ufu.brbacala/ANDROID/AppAlunos.pdf · Começando pelo Cadastro ......
•Implementação de uma app para Manipulação de Dados de Alunos
Em linhas gerais, a app consiste em:
Manter dados de alunos;
Entrar em contato com alunos;
Trocar dados com um servidor WEB; e
Compartilhar conteúdo em mídias ;
Definições de Projeto
• Neste requisito da nossa App, precisamos de:
• Uma tela para listar Alunos
• Outra para cadastrar ou alterar dados de Alunos
• A exclusão deve ocorrer com a seleção de um aluno na tela de listagem
Começando pelo Cadastro
• Componentes:
Nome do aluno que se deseja incluir na listagem
EditText
Botão para adicionar o nome do aluno à lista.
Button
Lista com nomes dos alunos.
ListView, que recebe uma coleção de Objetos e
lista seus dados
Tela Inicial: Listagem dos alunos
• Observe:
Componentes EditText e Button estão visíveis
No entanto, a ListView não aparece
Isso ocorre porque nossa lista ainda está vazia
Tela Inicial: Listagem dos alunos
Texto nome do
aluno e o botão
estão visíveis
Lista alunos ainda
vazia
• Os layouts xml (telas) estão associadas a classes Java (controladores), responsáveis pela implementação de suas regras de negócio
• listaalunoslayou.xml é controlada pela classe ListaAlunosActivity.java
• A classe de controle deve capturar os eventos e componentes da tela e implementar as regras de negócio necessárias às funcionalidades da App
Controladores a as regras de negócio
Atributos
Componentes da
tela acessados pela
classe de controle
Coleção de alunos
Método para inicializar
os atributos
Inicialização dos Atributos
Associa a tela (layout)
ao controlador (java)
Associa componentes
da View a atributos da
Activity
Captura o click no
botão
• É preciso inicializar a coleção de alunos e exibir os nomes na ListView
• Porém, ListView pode assumir diversos formatos de visualização
• ListView precisa da ajuda de alguém que saiba como organizar os dados na tela
ListView precisa do apoio de um Adaptador, que saiba converter objetos Java para componentes de Tela: Adapter.
Observações com relação ao ListView
Novos atributos
Declaração dos novos
atributos
Converte listas e
vetores em View
Define o layout que o
Adapter usará
• Associar objetos java a componentes de tela
• Criar o adaptador que exibe List<Strings>
• Inicializar:
A coleção de nomes de Alunos(List<Strings>);
O adaptador (ArrayAdapter<String>); e
A ListView que vai exibir os nomes na tela;
• Por fim, associar o adaptador à ListView
Passo a Passo
• Atualizar o evento de clique do botão Adicionar Aluno;
Adicionar o nome digitado no campo edNome à coleção listaAlunos;
Limpar o conteúdo do campo edNome; e
Atualizar o conteúdo da ListView
Passo a passo
Evento de click no botão
Implementação do
Evento de clique
Adiciona o nome
informado em edNome
na coleção
Limpa
conteúdo
de edNome
Atualiza o conteúdo
do ListView
• Inclua alguns nomes
• É possível agregar mais alguma funcionalidade?
• Que tal exibir um alerta com o nome do aluno, quando do clique em um nome da lista?
Conferindo o Resultado
• Assim como Button, a ListView possui o evento de click. Porém, são dois tipos de click:
Click curto, quando o usuário clica em um item da ListView; e
Click Longo, quando o usuário clica e segura um item da ListView ;
• Vamos implementar os eventos de clique Longo e Simples no final do método onCreate()
Evento de click no ListView
Cliques da ListView Implementação do
Evento de clique
simples
Implementação do
Evento de clique
longo
true: não executa o
click simples
false: executa o click
simples
E quando giramos o dispositivo?
Depois do giro:
Lista Vazia!
Quando giramos o
dispositivo, o Android
invoca novamente o
método onCreate() da
Activity
Todos os componentes
retornam ao estado
inicial
• Podemos armazenar o estado da app antes dela ser pausada, parada ou destruída
• Utilizamos Métodos de Callback, que são métodos usados quando o cliente requer um retorno do servidor, mas não quer ficar bloqueado, esperando.
• onSaveInstanceState(): chamado quando o Android vai destruir a Activity, mas sabe que vai restaurá-la depois;
Não é chamado quando usuário clica em Back
• onRestoreInstanceState(): Chamado antes da Activity destruída ser chamada pelo usuário
Persistindo o estado da Activity
• Para salvar o estado da Activity, usamos o objeto Bundle, gerenciado pelo Android
• O Bundle empacota um java.util.Map
• O Objeto Bundle é passado pelo Android aos métodos
onCreate(),
onSaveInstanceState() e
onRestoreInstanceState()
• Podemos utilizar o Map empacotado no Bundle para armazenar o estado da nossa App
Persistindo o estado da Activity
• Na classe ListaAlunosActivity, defina rduas constantes:
String TAG = "CADASTRO_ALUNO" – Usada para registro de mensagens de LOG no Logcat
String ALUNOS_KEY = "LISTA" – Usada como Chave para o Map do Objeto Bundle;
• Implementar os métodos onSaveInstanceState() e onRestoreInstanceState()
• Atualizar o método onCreate(), para tentar recuperar a chave ALUNOS_KEY do Bundle
Passo a Passo
• Pelas mensagens de log, verificamos a lista de alunos sendo salva e recuperada do objeto Bundle
Resultado exibido no LogCat
• Precisamos Cadastrar e Alterar os dados do aluno
Dados: Foto, Nome, Fone, Endereço, Site, E-mail e Nota
• Como o dispositivo possui uma tela limitada, criaremos uma nova Activity (tela) para edição dos dados dos alunos.
Incrementando o cadastro
• Formulário para cadastro de alunos
• Novos componentes:
ImageView: para exibir a foto o usuário, armazenada no próprio device;
SeekBar: para que o usuário escolha uma nota, dentro de um intervalo
Tela de Cadastro de Alunos
• Torne novamente a ListaAlunosActivity a tela inicial da nossa aplicação:
Antes de prosseguir...
Tela de listagem
• Com duas telas na App, é necessário algum mecanismo para navegar entre elas
• Para isso, é comum o uso menus. Toda Activity sabe tratar menus, basta sobrescrever o método:
onCreateOptionsMenu(Menu menu), que recebe do Android um menu vazio
• O próprio Android se encarrega de encaixar o menu na tela
• Para exibir o menu da App:
Basta clicar no Botão Menu do device
Navegação entre telas
• Apesar da possibilidade de definição de Menus no código Java, é mais comum o uso de arquivos XML:
• O método Activity.onCreateOptionsMenu retorna true para indicar que o menu deve ser exibido na tela
Estratégia para definição de Menus
<item
android:id="@+id/menu_novo"
android:icon="@drawable/ic_novo"
android:showAsAction="always"
android:title="Novo"/>
<item
android:id="@+id/menu_mapa"
android:icon="@drawable/ic_mapa"
android:showAsAction="always"
android:title="Mapa"/>
• O Android precisa ler o XML com itens do menu e criar objetos do tipo View, a partir das tags
• Essa é a especialidades dos Inflaters
• O MenuInflater é especialista em carregar XML de menu
• O método Activity.onCreateOptionsMenu(Menu menu) nos oferece um objeto Menu vazio, que pode ser utilizado pelo MenuInflater para carregar um XML com itens do menu
• O método Activity.getMenuInflater() nos devolve um MenuInflater
• Inflater.inflate(): lê um XML e carrega um Menu
Estratégia para definição de Menus
•Crie o arquivo XML: res/menu/menu_principal:
Menu principal
É comum que apenas
dois Itens do Menu
fiquem visíveis e os
demais, ocultos
• Para monitorar o click, precisaremos implementar o método onOptionsItemSelected da ListaAlunosActivity
• Por enquanto, exibiremos apenas uma mensagem num Toast, quando o usuário clicar no item NOVO:
Eventos de click
•Configurada a ActionBar, podemos incrementar ainda mais nossa App.
•Vamos fazer com que o clique no menu NOVO faça surgir a tela de Formulário
Usamos objetos do tipo Intent, que recebem um contexto e uma Activity que deve ser exibida
•Depois de configurada nossa Intenção, podemos iniciar a nova tela (startActivity)
Navegação entre telas da nossa App
MVC em Android
Exibir tela
Entrada
de dados
modelo.getEstado()
modelo.atualizaEstado()
Notificação de
mudanças
Tela.atualizarVisao()
• A tela de Listagem da App permite o cadastro do nome dos alunos e os exibe em uma ListView
• Porém, surgem alguns problemas nessa abordagem:
Os dados são perdidos quando a App é destruída
Precisamos de outros dados para o Aluno
• Como resposta, poderíamos:
Persistir os dados em um Bando de Dados
Usar a tela de Formulário para cadastro e alteração de dados do Aluno
Persistência com SQLite
•no método onCreate() da Activity, temos de povoar um bean Aluno com dados da tela:
Pensando na arquitetura...
• A complexidade da Activity aumenta, à medida que novas funcionalidades vão sendo implementadas
• É uma boa prática de programação isolar pequenas responsabilidades em outras classes.
• Assim, a Activity passa a realizar o seu trabalho interagindo com pequenos especialistas
• Neste cenário, é possível implementar o padrão de projeto View Helper, que define a criação de classes especialistas em ext rair e tratar dados das telas
Ainda, pensando na arquitetura
• Método construtor que recebe um FormularioActivity
O Helper (cont.) O construtor recebe um FormularioActivity
Associa atributos do Helper a componentes da tela
Criação do objeto Aluno
O Helper (final) Retorna Aluno com dados vindos da tela
Seta os atributos do aluno nos campos da tela
Retorna referência para um objeto Aluno
•Agora que aclasse FormularioHelper está pronta, podemos utilizá-la na classe de controle FormularioActivity
•Para isso, é preciso:
criar um atributo FormularioHelper
criar um objeto Helper no método onCreate()
utilizar os dados do Aluno em qualquer método que necessite desse objeto (reuso)
•Nessa App, vamos usar o click do botão para exibir o nome do aluno
Usando o Helper
Usando o Helper na View Definição do novo atributo FormularioHelper
Inicialização do helper,
passando uma
referência para o
objeto atual(this)
Pedindo do Helper
uma referência a
Aluno Usando o novo objeto
Aluno
• O ViewHelper extrai os dados de Aluno da tela
• Vamos armazenar esses dados em um Banco de Dados relacional SQLite
• Para converter Objetos Java em Relações do banco de dados, vamos utilizar o padrão de projeto DAO
• DAO (Data Access Object) define que, para cada tabela do banco, criamos uma classe de persitência
Ex: para a tabela Aluno, teremos uma classe AlunoDAO, responsável pelo CRUD do aluno
Hora de persistir os dados
• Crie a classe para persistir dados do Aluno:
AlunoDAO
Classe DAO para persistir dados de Aluno
Filha da classe de
persistência
SQLiteOpenHelper
• Agora que a camada de modelo está preparada para o cadastro do aluno, podemos atualizar nossa tela de formulário;
• No click do botão de Salvar, vamos:
Pedir um objeto Aluno do Helper;
Abrir uma conexão com BD, criando AlunoDAO;
Cadastrar o novo Aluno no BD; e
Fechar a conexão com o banco de dados
Atualização da FormularioActivity
• Para visualizar os dados do BD, precisamos atualizar as camadas de visão, controle e modelo
• Na camada de modelo,
criar o método listar()
• Nas camadas de visão e controle:
Remover o EditText e Button
• Na camada de controle,
alterar o método onCreate() da ListaAlunosActivity para chamar o método listar() da camada de modelo e apagar os métodos:
onSaveInstanceState() e onRestoreInstanceState()
Para ver o que foi salvo...
• Alterar o arquivo: /res/layout/listaalunoslayout.xml
• Deixar apenas a ListView
Atualização da Tela inicial
•No método onCreate() da ListaAlunosActivity, deixar apenas a associação da ListView
Atualizar camada de controle
•Nossa coleção de Alunos deve deixar de ser List<String> e se tornar List<Aluno>
•Alterar, também, o tipo do ArrayAdapter
Mudança de tipos
• Na ListaAlunosActivity, criar o método carregarLista() para acesso ao DAO e carregar a coleção de Alunos
Carga dos dados
• Na classe ListaAlunosActivity, criar o método onResume()
• Nesse método, fazer a chamada a carregarLista()
Carga no OnResume()
•Para completar o cadastro de alunos, falta implementar as rotinas de:
Alterar; e
Excluir Alunos
•Para alterar um registro, é comum o uso de um click curto, indicando sua seleção
•Na exclusão, é comum um click longo, que abre um pequeno menu, para selecionar uma ação
Completando o sistema
• No Android, há o ContextMenu, que abre um menu exclusivo para um item da lista
• Para avisar ao Android que a ListView possui um menu de contexto, é preciso marcá-la: registerForContextMenu()
• Criar um arquivo .xml para descrever os itens que devem ser exibidos no ContextMenu
• No método onCreateContextMenu() da Activity, usar um Inflater para inflar as opções do menu:
Opções: Ligar, Enviar SMS, Achar no Mapa, Navegar no
site, Enviar E-mail e Deletar, etc...
Menu de Contexto
• Na pasta /res/menu, criar um Android XML File
• Informe o nome do novo arquivo: menu_contexto
Criando o Menu de Contexto
•Na classe ListaAlunosActivity, incluir um atributo para marcar o aluno selecionado no Click Longo da ListView
Novo Atributo
• Atualize o método ListaAlunosActivity.onCreate():
Atualização do onCreate
Não consome o Click Curto,
para
que o ContextMenu seja
exibido
• Criar a funcionalidade para alterar os dados de um aluno
• Ao acionar o click longo da ListView, a App exibe um menu de contexto, com possíveis ações para o Aluno
• No click curto, chamar a tela de formulário, carregada com os dados do aluno selecionado
• Como enviar o aluno selecionado na ListaAlunosActivity para FormularioActivity?
Vamos usar Intents para enviar objetos Serializáveis de uma Activity para outra
Edição dos dados do aluno
•Para realizar a edição de dados do Aluno, precisamos:
Tornar o bean Aluno “Serializável”
Implementar o método AlunoDAO.alterar(Aluno);
Enviar um objeto Aluno da ListaAlunosActivity para FormularioActivity;
Carregar o formulário com os dados do Aluno; e
Verificar se é necessário cadastrar ou alterar os dados do Aluno;
Passo a passo
AlunoDAO.alterar() Valores que serão
enviados para o BD
Valores dos
parâmetros
da cláusula
WHERE
Atualização dos
dados do Aluno
• Na ListaAlunosActivity, atualize o click da ListView:
Transição de telas
Intenção de navegar
de ListaAlunosActivity
para FormularioActivity
Recupera o
aluno
selecionado
Compartilha o objeto
Aluno com a nova tela Inicia a tela de
Formulário
• Atualize o método FormularioActivity.onCreate():
Dados na tela
Recupera o objeto
Aluno enviado pela
ListaAlunosActivity
• Vez por outra, pode ser necessário que nossa App acesse recursos do próprio device, como:
Câmera, Arquivos, Internet etc
• Para que o acesso seja autorizado, precisamos registrar esses interesses no AndroidManifest.xml
• Incluir a tag uses-permission e informar o valor para sua propriedade android:name
• Exemplo para solicitação de acesso à câmera:
<uses-permission
android:name="android.permission.CAMERA"/>
Permissões de Acesso
• Em nossa aplicação, precisamos realizar uma chamada telefônica para um aluno;
• O Android nos oferece duas estratégias para isso:
acessar o telefone em baixo nível e controlar todo o ciclo de vida da chamada (pode não ser uma boa ideia)
usar uma Intent que já sabe fazer ligações telefônicas: Intent.ACTION_CALL
• O Android oferece várias Activities prontas para acesso a funcionalidades do device
Intents implícitas
• Altere o método onContextItemSelected da ListaAlunos:
• Inclua opções para ver Aluno no Mapa e Navegar no site●
Ações do ContextMenu
Padrão para
Busca em mapa
Item que Navega
no site do Aluno
• Altere o método onContextItemSelected da ListaAlunos:
• Última opção: Enviar e-mail para aluno.
Ações do ContextMenu
•Para completar o cadastro do aluno, queremos usar a câmera para capturar sua foto;
•O arquivo .jpeg da foto ficará armazenado no device
•No SQLite, guardaremos apenas o caminho para o arquivo físico
•Na hora de carregar a foto, recupera-se o caminho armazenado no SQLite, acessa o device e faz-se a carga a imagem na tela.
Completando a App
• No Android, também existem as classes tradicionais de arquivos:
FileInputStream e FileOutputStream;
• A Activity tem métodos para gerar esses objetos:
FileInputStream stream = openFileInput("arquivo.txt");
• E se você precisar trabalhar com memória externa?
File diretorio = Enviroment.getExternalStorageDirectory()
• Devolve um diretório externo, provavelmente, um sdcard
Recordando...
•O android nos oferece duas formas de manipular câmera, assim como ocorreu com a Chamada Telefônica
usar e controlar todo o ciclo de vida e opções do uso da câmera, como, por exemplo, habilita flash e controlar a entrada de luz
chamar uma Activity especialista no tratamento da câmera. Essa Activity recebe como parâmetro, o local para salvar a foto capturada.
Parece que a 2a alternativa é mais simples.
Usando a Câmera
• Crie o método FormularioHelper.carregarFoto()
Carregar jpeg com a foto
Converte um
Arquivo em um
Objeto JAVA
Definição de uma
Imagem reduzida
Atualiza o
atributo foto
do Aluno
Atualiza a imagem
na Tela
• Para acessar a câmera, vamos seguir a estratégia de chamar uma Intent implícita, especialista em câmera:
Intent irParaCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
• Podemos informar o local para salvar a foto:
irParaCamera.putExtra(MediaStore.EXTRA_OUTPUT, localFoto);
• E esperar o retorno, com nome do arquivo gerado.
• Para isso, informamos um código para a requisição (requestCode), comumente associado a uma constante:
startActivityForResult(irParaCamera, FAZER_FOTO);
Chamando a câmera
• O retorno do método startActivityForResult() vem no callback method onActivityResult()
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { … }
• O requestCode == FAZER_FOTO
• Já o resultCode pode ser:
RESULT_OK: ocorreu tudo bem. :-)
RESULT_CANCELED: em caso de problemas ou cancelamento :-(
Chamando a câmera (cont.)
• Na classe FormularioActivity, inclua novos atributos para lidar com a câmera:
Novas mudanças no formulário
• No método FormularioActivity.onCreate(), implemente o click da foto:
Click da Imagem
Local em que
a Foto será
armazenada
Referência para
o Local de
armazenamento
Intent Implícita
para uso da
câmera
Chamando a
Câmera
• No método FormularioActivity.onCreate(), implemente o click da foto:
Click da Imagem
Chamando a
Câmera
Parâmetro: local de
armazenamento
Inicia a Activity da
Câmera. A resposta é
lançada no método de
Callback
onActivityResult()
Parâmetro: local de
armazenamento
• Na ForumlarioActivity, crie o método onActivityResult(), para verificar o resultado retornado pela Intent da Câmera:
Verificação do resultado
Tratamento
da resposta
da Intent da
câmera
• Quando cadastramos um aluno, o formulário está vazio;
• Se clicar na foto, a câmera é chamada;
• A foto é, então, salva no dispositivo;
• Assim, é exibida na tela de formulário;
• Porém, se girarmos a tela, o que acontece?
• Isso mesmo, a foto é perdida.
• Como Resolver esse problema, recorrente em Android Apps?
• Ideia fantástica: tente usar o Bundle.
Desafio...