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 :)
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??
TVs
Smartphones
1.5 Bilhões
3 Bilhões
Você anytime, anywhere
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
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)
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>
<?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>
<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?
Incrementando um pouco mais nosso app...
<?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
O Android possui uma série de modelos de interface para organizar os componentes da tela.
Modelos Mais comuns:
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
...
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()
...
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
"Não ligue para gente, nós ligaremos para você"
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
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;
}
}
Tela responsável por listar os filmes cadastrados até o momento
Baseado no conceito de Adapter
<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
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...
É possível Customizar o Layout de cada linha:
<?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;
}
FABs: utilizados para prover ações essenciais a tela
<?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
@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
Classe responsável por "criar" as intenções no sistema
<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>
<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>
Layout que organiza a interface em linhas (verticais ou horizontais)
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();
}
});
}
}
Exibe pop-ups no dispositivo
NewMovieActivity.java
Mas como cadastrar o filme???
startActivity()
startActivityForResult()
startActivity()
startActivityForResult()
finish()
finish()
onActivityResult()
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();
}
});
}
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
}
}
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