Meu Primeiro App Android
EATI 2016 - João Eduardo Montandon
Sobre Mim
Professor no COLTEC/MG
Área de Atuação: Engenharia de Software
Experiências:
Web
Mobile
Detecção de Bugs/Defeitos
Compreensão de APIs
Este sou eu :)
Sobre o Minicurso
O que, Por quê e como é Android?
Ferramentas, instalação & configuração
Hello, Droid!!
Nosso Primeiro App: MovieMe
Quem não possui um telefone hoje??
O Celular Hoje
O Celular Hoje
TVs
Smartphones
1.5 Bilhões
3 Bilhões
O Celular Hoje
- O celular é hoje o dispositivo mais pessoal existente
- Representa a extensão do nós mesmos
- Compartilhamos, registramos, controlamos, vivemos...
Você anytime, anywhere
O Ecossistema Android
- Sistema Operacional Móvel mantido pelo Google*
- Líder mundial no segmento
- Disponível para diversas plataformas
- TVs
- Relógios
- Carros
- Smartphones (é claro!!)
O Ecossistema Android
A Open Handset Alliance
- Consórcio formado por 84 empresas
- Objetivo: Contribuir para criação de um S.O. móvel aberto
- Fabricantes: HTC, Samsung, LG, Motorola, etc.
- Operadoras: Nextel, T-Mobile, Telefonica, etc.
- Semicondutores: Intel, Broadcom, Nvidia, Qualcomm, etc.
- Software: Google, eBay, Ascender, etc.
- Comércio: Aplix, Noser, TAT, Wind River, etc.
O Ecossistema Android
Histórico de versões
1.5
1.6
05/09
2.1
2.2
2.3
3.0
4.0
4.1
4.4
5.0
6.0
09/09
10/09
05/10
12/10
02/11
10/11
06/12
10/13
11/14
10/15
1.6: Android Cupcake
2.3: Gingerbread
4.0: Ice Cream Sandwich
5.0: Lollipop
O Ecossistema Android
Principais Características
Dispositivo
- Recursos limitados:
- Bateria
- Memória
- Armazenamento
- Processamento...
Aplicação
- Mashups
- Sandbox
- Programação Intencional
O Ecossistema Android
Softwares Necessários
Java JDK Versão 1.5 a 1.7 (http://www.java.com/pt_BR/)
Android Studio & SDK (http://developer.android.com/intl/pt-br/sdk/index.html)
Hello, Droid
Criando um Novo Projeto
File > New > Project
Minimum SDK: API 22
Template: Empty Activity
Activity: HelloActivity
package edu.ifmg.eati.hellodroid;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class HelloActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello);
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="edu.ifmg.eati.hellodroid.HelloActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
Executando a Aplicação
- Run > Run app
- Selecionar Emulador
- Criar se não existir um
- Executar
- Alternativas ao emulador:
- Genymotion
- Xamarin Android Player
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.ifmg.eati.hellodroid">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".HelloActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Hello World pt. 2
<resources>
<string name="app_name">HelloDroid</string>
<string name="main_description">Meu primeiro App!!</string>
</resources>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_description" />
strings.xml
activity_hello.xml
Porque dessa vez foi mais rápido?
Hello, Cara!!
Incrementando um pouco mais nosso app...
Hello, Cara!!
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_description"
android:textSize="40px"
android:id="@+id/lbl_titulo"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/lbl_titulo"
android:id="@+id/txt_nome"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/txt_nome"
android:text="@string/btn_title"
android:id="@+id/btn_update"/>
</RelativeLayout>
activity_hello.xml
Layouts
O Android possui uma série de modelos de interface para organizar os componentes da tela.
Modelos Mais comuns:
- RelativeLayout
- LinearLayout
- TableLayout
- FrameLayout
Hello, Cara!!
public class HelloActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello);
final TextView lblHello = (TextView) findViewById(R.id.lbl_titulo);
final EditText txtNome = (EditText) findViewById(R.id.txt_nome);
Button btnAtualizar = (Button) findViewById(R.id.btn_update);
btnAtualizar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
lblHello.setText("Olá, " + txtNome.getText());
}
});
}
}
HelloActivity.java
A Classe R.java
...
final TextView lblHello = (TextView) findViewById(R.id.lbl_titulo);
final EditText txtNome = (EditText) findViewById(R.id.txt_nome);
Button btnAtualizar = (Button) findViewById(R.id.btn_update);
...
Todos os componentes de interface são mapeados na classe R.java
Dessa forma é possível recuperá-los dinamicamente, por meio do método findViewById()
O Princípio de Hollywood
...
btnAtualizar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
lblHello.setText("Olá, " + txtNome.getText());
}
});
...
O desenvolvimento em Android é baseado no conceito de arcabouço
- Você desenvolve, mas o Android decide quando ele será executado
"Não ligue para gente, nós ligaremos para você"
Executando no Celular
- Para executar no celular, precisamos habilitar o modo desenvolvedor
- Configurações > Programador
- Caso ainda não esteja visível, tocar "Número da versão" 7 vezes.
MovieMe
MovieMe
Aplicativo onde o usuário poderá cadastrar quais filmes, seriados e documentários ele assistiu.
Todo mundo assiste a filmes, seriados, documentários, desenhos, etc.
Contudo, nunca nos lembramos do filme para compartilhar com os amigos..
Ideia
MovieMe
- Listagem dos filmes cadastrados
- Interface para cadastro de novos filmes
Requisitos Principais
Setup do Projeto
- Novo projeto...
- SDK versão 21 ou superior
- Selecionar Empty Activity
A Classe Movie
Classe responsável por representar cada filme
public class Movie {
private String name;
private int rating;
private String comment;
public Movie(String name, int rating, String comment) {
this.name = name;
this.rating = rating;
this.comment = comment;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRating() {
return rating;
}
public void setGrade(int rating) {
this.rating = rating;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
- name: Nome do filme
- rating: Nota do filme
- comment: Comentário do filme
Listagem de Filmes
- A listagem será feita por meio de um ListView
- Um botão irá redirecionar para o cadastro de um novo filme
Tela responsável por listar os filmes cadastrados até o momento
Listagem de Filmes
Lidando com ListView
Baseado no conceito de Adapter
- Adapter: "Cola" entre interface e modelo
Listagem de Filmes
ListView: Interface
<RelativeLayout ...>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/main_filmes_cadastrados"
android:textSize="20dp"
android:layout_marginBottom="20dp"
android:id="@+id/txt_title"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/txt_title"
android:id="@+id/movies_list"/>
</RelativeLayout>
activity_main.xml
Listagem de Filmes
ListView: Adapter
public class MoviesAdapter extends BaseAdapter {
private ArrayList<Movie> movies;
private Context context;
public MoviesAdapter(Context context) {
this.context = context;
this.movies = new ArrayList<>();
}
.
.
.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Movie movie = this.movies.get(position);
TextView lblMovie = new TextView(context);
lblMovie.setTextSize(20);
lblMovie.setText(movie.getName() + " -- " + movie.getRating());
return lblMovie;
}
}
Não ficou mto legal...
Listagem de Filmes
ListView: Adapter Customizado
É possível Customizar o Layout de cada linha:
- Criar o layout customizado do adapter
- Importar o layout no método getView()
Listagem de Filmes
ListView: Adapter Customizado
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...>
<TextView ... android:text="My Movie"/>
<TextView ... android:text="5"/>
<TextView ... android:text="lorem ipsum comment"/>
</RelativeLayout>
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Movie movie = this.movies.get(position);
View view = LayoutInflater.from(this.context).inflate(R.layout.adapter_movies, parent, false);
TextView lblName = (TextView) view.findViewById(R.id.lbl_movie_name);
TextView lblGrade = (TextView) view.findViewById(R.id.lbl_movie_grade);
TextView lblComment = (TextView) view.findViewById(R.id.lbl_movie_comment);
lblName.setText(movie.getName());
lblGrade.setText(String.valueOf(movie.getRating()));
lblComment.setText(movie.getComment());
return view;
}
Listagem de Filmes
- Adicionar FAB no arquivo XML da interface
- Implementar evento de click no arquivo Java da Interface
FABs: utilizados para prover ações essenciais a tela
Floating Action Buttons
Listagem de Filmes
Floating Action Buttons
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout ...>
.
.
<android.support.design.widget.FloatingActionButton
android:id="@+id/btn_new_movie"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:layout_alignBottom="@id/movies_list"
android:layout_alignRight="@id/movies_list"
android:tint="@color/white"
android:src="@android:drawable/ic_input_add" />
</RelativeLayout>
activity_main.xml
@Override
protected void onCreate(Bundle savedInstanceState) {
.
.
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.btn_new_movie);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(MainActivity.this.getClass().getName(), "Novo filme");
}
});
}
MainActivity.Java
Listagem de Filmes
FABs: Redirecionando para nova tela
@Override
protected void onCreate(Bundle savedInstanceState) {
.
.
FloatingActionButton fab = ...;
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Criação da Intent
Intent intent = new Intent(MainActivity.this,
NewMovieActivity.class);
// Requisição ao Android para iniciar a Intent
startActivity(intent);
}
});
}
Nós não invocamos novas Telas diretamente (Princípio de Hollywood)
Precisamos registrar a nossa intenção de abrir a nova tela
Intent
Classe responsável por "criar" as intenções no sistema
Cadastro de Novos Filmes
- O cadastro deverá ser realizado em uma tela separada
- O Formulário deverá ter três campos
- Nome (Campo de Texto)
- Nota (Slider)
- Comentário (Campo de Texto)
- Um botão de confirmação deverá realizar o cadastro
Cadastro de Novos Filmes
Criando a NewMovieActivity
- File > New > Empty Activity
- Dar um título a Activity
- Implementar Interface
- Implementar ação de click
Cadastro de Novos Filmes
Dando um título a Activity
- O título é uma propriedade da Activity
- Pode ser customizado no AndroidManifest.xml
<application
...
android:label="@string/app_name">
<!-- Atividade Principal -->
<activity android:name=".MainActivity">
...
</activity>
<!-- Atividade de cadastro dos filmes -->
<activity android:name=".NewMovieActivity"
android:label="@string/activity_new_movie_title"></activity>
</application>
Cadastro de Novos Filmes
Implementando Interface
<LinearLayout ...
android:orientation="vertical">
<!-- Nome do filme -->
<TableRow ... >
<TextView ...
android:text="@string/new_movie_name"/>
<EditText ...
android:id="@+id/txt_movie_name"/>
</TableRow>
<!-- Nota do filme -->
<TableRow ...>
<TextView ...
android:text="@string/new_movie_rating"/>
<SeekBar ...
android:max="10"
android:id="@+id/sk_movie_rating" />
</TableRow>
<!-- Comentário do filme -->
<TextView ...
android:text="@string/new_movie_comment"/>
<EditText ...
android:layout_height="120dp"
android:inputType="textMultiLine"
android:id="@+id/txt_comment" />
<!-- Botão de cadastro -->
<Button ...
android:text="@string/new_movie_btn_ok"/>
</LinearLayout>
LinearLayout
Layout que organiza a interface em linhas (verticais ou horizontais)
Cadastro de Novos Filmes
Implementando ação de click
public class NewMovieActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_movie);
Button okButton = (Button) findViewById(R.id.btn_new_movie);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Invoca o pop up para dizer que foi cadastrado
Toast.makeText(NewMovieActivity.this,
"Filme cadastrado com sucesso", Toast.LENGTH_LONG).show();
// finaliza a Atividade
NewMovieActivity.this.finish();
}
});
}
}
Toast
Exibe pop-ups no dispositivo
NewMovieActivity.java
Mas como cadastrar o filme???
Cadastro de Novos Filmes
Implementando ação de click
startActivity()
startActivityForResult()
startActivity()
startActivityForResult()
finish()
finish()
onActivityResult()
Cadastro de Novos Filmes
Implementando ação de click
protected void onCreate(Bundle savedInstanceState) {
...
final EditText txtName = (EditText) findViewById(R.id.txt_movie_name);
final SeekBar skRating = (SeekBar) findViewById(R.id.sk_movie_rating);
final EditText txtComment = (EditText) findViewById(R.id.txt_comment);
Button okButton = (Button) findViewById(R.id.btn_new_movie);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent returnIntent = new Intent();
returnIntent.putExtra("name", txtName.getText().toString());
returnIntent.putExtra("rating", skRating.getProgress());
returnIntent.putExtra("comment", txtComment.getText().toString());
setResult(RESULT_OK, returnIntent);
Toast.makeText(NewMovieActivity.this,
"Filme cadastrado com sucesso", Toast.LENGTH_LONG).show();
NewMovieActivity.this.finish();
}
});
}
Cadastro de Novos Filmes
Implementando ação de click
private static final int NEW_MOVIE_CODE = 1;
MoviesAdapter adapter; // deve ser global para adicionar o filme posteriormente
protected void onCreate(Bundle savedInstanceState) {
.
.
.
fab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, NewMovieActivity.class);
startActivityForResult(intent, NEW_MOVIE_CODE);
}
});
}
.
.
.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_MOVIE_CODE && resultCode == RESULT_OK) {
String name = data.getStringExtra("name"); // recupera o nome
int rating = data.getIntExtra("rating", -1); // recupera a nota
String comment = data.getStringExtra("comment"); // recupera o comentário
Movie newMovie = new Movie(name, rating, comment); // cria o objeto filme
adapter.addNewMovie(newMovie); // adiciona filme no adapter
}
}
Cadastro de Novos Filmes
Implementando ação de click
public class MoviesAdapter extends BaseAdapter {
.
.
.
public void addNewMovie(Movie newMovie) {
this.movies.add(newMovie);
// atualiza o adapter com o novo filme
this.notifyDataSetChanged();
}
}
Precisamos adicionar o novo filme na lista.
Essa adição pode ser feita por meio do adapter
Próximos Passos...
- Armazenamento persistente
- Compartilhamento por e-mail
- Geolocalização & Maps
- Consumo web services (Rotten Tomatoes)
- Submissão a play store
Resumo de Hoje
- A importância do mobile em nossas vidas
- O ecossistema Android
- Principais características
- Conceitos básicos (app Hello, Droid)
- MovieMe App
Muito Obrigado!!
eati2016
By João Eduardo Montandon
eati2016
- 850