SlideShare uma empresa Scribd logo
1 de 40
Baixar para ler offline
Projeto e Desenvolvimento de
Aplicações Android
● Três encontros 04/04, 18/04 e 25/04.
● Projeto de aplicações Android.
● Orientações para elaboração de interface de usuário para Android.
● Boas práticas no desenvolvimento móvel e Android.
● Teste de aplicações Android.
● Desenvolvimento Prático.
● Publicação de aplicações Android.
Projeto e Desenvolvimento de
Aplicações Android
● Avaliação:
● Conceito C:
○ Apresentação da idéia (04/04)
○ Entrega de uma aplicação com uso de, no mínimo, 3
bibliotecas do Android JetPack (ViewModel, LiveData e
DataBinding)
● Conceito B:
○ Uso de mais 2 pacotes JetPack, sendo um deles o Navigation.
● Conceito A:
○ Uso de mais 2 pacotes JetPack.
Projeto e Desenvolvimento de
Aplicações Android
● Foco da Disciplina:
● Android JetPack
● Porém, antes disso, alguma dúvida sobre Android?
JetPack
https://developer.android.com/jetpack
JetPack
● O Jetpack é um conjunto de bibliotecas, ferramentas e
orientações para ajudar os desenvolvedores a criar apps de alta
qualidade com mais facilidade. Esses componentes ajudam você
a seguir as práticas recomendadas, acabando com os códigos de
texto clichê e simplificando tarefas complexas, para que você
possa se concentrar na parte do código do seu interesse.
● O Jetpack compõe as bibliotecas de pacotes androidx.*,
separadas das APIs da plataforma. Isso significa que ele oferece
compatibilidade com versões anteriores e é atualizado com mais
frequência que a Plataforma Android, garantindo que você sempre
tenha acesso às versões melhores e mais recentes dos
componentes do Jetpack.
https://developer.android.com/jetpack
JetPack
https://developer.android.com/jetpack/docs/guide
JetPack
https://medium.com/android-dev-moz/introdu%C3%A7%C3%A3o-ao-android-jetpack-68697c5fcff2
ViewModel, LiveData e DataBinding
● Passo 1) Criamos um projeto Android
ViewModel, LiveData e DataBinding
● Passo 2) Criar uma Activity
ViewModel, LiveData e DataBinding
● Passo 3) Nomear como ListaCarros
ViewModel, LiveData e DataBinding
● Passo 4) Remover a MainActivity e limpar suas referências.
<application ...>
<activity android:name=".ListaCarros">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
ViewModel, LiveData e DataBinding
● Passo 5) Verificar se a criação da ViewModel não está depreciada.
viewModel =
ViewModelProvider(this).get(ListaCarrosViewModel::class.java)
ViewModel, LiveData e DataBinding
https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e
ViewModel, LiveData e DataBinding
● Passo 5) Provando os conceitos
class ListaCarrosViewModel : ViewModel() {
init {
Log.e("teste", "init viewmodel ${this.toString()}");
}
override fun onCleared() {
super.onCleared()
Log.e("teste", "init onCleared");
}
}
ViewModel, LiveData e DataBinding
● Passo 5) Provando os conceitos
class ListaCarrosFragment : Fragment() {
...
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel =
ViewModelProvider(this).get(ListaCarrosViewModel::class.java)
Log.e("teste", "viewModel ${viewModel.toString()}")
}
}
ViewModel, LiveData e DataBinding
● Passo 6) Inserindo dados - criando uma DataClass
data class Car(
val manufacturer: String,
val model: String,
val price: Float,
val photo: String)
ViewModel, LiveData e DataBinding
● Passo 6) Alterar o lista_carros_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout ...>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_cars"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
ViewModel, LiveData e DataBinding
● Passo 6) Criar um arquivo item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:padding="10dp"
android:id="@+id/txt_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
ViewModel, LiveData e DataBinding
● Passo 6) Criaremos um adapter para o RecyclerView
class CarsAdapter(private val myDataset: List<Car>) :
RecyclerView.Adapter<CarsAdapter.MyViewHolder>() {
class MyViewHolder(val viewRoot: View) : RecyclerView.ViewHolder(viewRoot)
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int): CarsAdapter.MyViewHolder {
val textView = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)
return MyViewHolder(textView)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.viewRoot.txt_detail.text = "${myDataset[position].model} -
${myDataset[position].manufacturer}"
}
override fun getItemCount() = myDataset.size
}
ViewModel, LiveData e DataBinding
● Passo 6) Editar ListaCarrosFragment
private lateinit var viewAdapter: RecyclerView.Adapter<*>
private lateinit var viewManager: RecyclerView.LayoutManager
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(ListaCarrosViewModel::class.java)
viewManager = LinearLayoutManager(activity)
viewAdapter = CarsAdapter(viewModel.cars)
rv_cars.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
}
}
ViewModel, LiveData e DataBinding
● Passo 6) Edição do ViewModel
class ListaCarrosViewModel : ViewModel() {
var cars: MutableList<Car> = ArrayList<Car>();
init {
val ecosport = Car("Ford", "EcoSport", 59000.0f, "https://www...");
val i30 = Car("Hiunday", "i30", 27000.0f, "https://cdn….");
cars.add(ecosport);
cars.add(i30);
}
}
ViewModel, LiveData e DataBinding
● Passo 7) Vamos fazer um teste!
class ListaCarrosViewModel : ViewModel() {
var cars: MutableList<Car> = ArrayList<Car>();
fun getCars(){
GlobalScope.launch {
Thread.sleep(10000)
val ecosport = Car("Ford", "EcoSport", 59000.0f, "https://ww...");
val i30 = Car("Hiunday", "i30", 27000.0f, "https://cd...");
cars.add(ecosport);
cars.add(i30);
}
}
}
ViewModel, LiveData e DataBinding
● Passo 8) Observer
class ListaCarrosViewModel : ViewModel() {
var cars: MutableLiveData<List<Car>> = MutableLiveData<List<Car>>();
fun getCars(){
val ecosport = Car("Ford", "EcoSport", 59000.0f, "https://www.slavie...");
val i30 = Car("Hiunday", "i30", 27000.0f, "https://cdn.salaodo...");
val tempCars: MutableList<Car> = ArrayList();
tempCars.add(ecosport);
tempCars.add(i30);
cars.value = tempCars;
}
}
ViewModel, LiveData e DataBinding
● Passo 8) Observer
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(ListaCarrosViewModel::class.java)
viewManager = LinearLayoutManager(activity)
rv_cars.apply {
setHasFixedSize(true)
layoutManager = viewManager
}
viewModel.cars.observe(viewLifecycleOwner, Observer {
viewModel.cars.value?.let {
viewAdapter = CarsAdapter(it)
rv_cars.adapter = viewAdapter;
}
})
viewModel.getCars();
}
ViewModel, LiveData e DataBinding
● Passo 9) Nova tela Fragment+ViewModel com o nome
DetalheCarro.
ViewModel, LiveData e DataBinding
● Passo 10) Corrija a instância do ViewModel.
viewModel =
ViewModelProvider(this).get(DetalheCarroViewModel::class.java)
ViewModel, LiveData e DataBinding
● Passo 11) Navegação entre telas. Mudança no adapter.
class CarsAdapter(
private val myDataset: List<Car>,
private val context: Context) :
RecyclerView.Adapter<CarsAdapter.MyViewHolder>() {
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.viewRoot.setOnClickListener {
context.startActivity(Intent(context, DetalheCarro::class.java))
}
}
}
ViewModel, LiveData e DataBinding
● Passo 11) Navegação entre telas. Instância precisa passar o
contexto.
viewModel.cars.observe(viewLifecycleOwner, Observer {
viewModel.cars.value?.let {
viewAdapter = CarsAdapter(it, activity as Context)
rv_cars.adapter = viewAdapter;
}
})
ViewModel, LiveData e DataBinding
● Passo 12) Último conceito: DataBinding.
ViewModel, LiveData e DataBinding
● Passo 13) Último conceito: DataBinding.
apply plugin: 'kotlin-kapt'
android {
dataBinding {
enabled true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.2.0'
kapt 'com.android.databinding:compiler:3.1.4'
}
ViewModel, LiveData e DataBinding
● Passo 14) Tags layout e data.
class DetalheCarroViewModel : ViewModel() {
var car: Car? = null;
}
ViewModel, LiveData e DataBinding
● Passo 14) Tags layout e data.
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="com.study.aula1possenac.ui.detalhecarro.DetalheCarroViewMode
l" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout ...>
...
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
ViewModel, LiveData e DataBinding
● Passo 14) Tags layout e data.
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/detalhecarro"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.detalhecarro.DetalheCarroFragment">
<LinearLayout
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:text="@{viewModel.car.model}"
android:textSize="25dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:textSize="20dp"
android:text="@{viewModel.car.manufacturer}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
ViewModel, LiveData e DataBinding
● Passo 14) DataBinding é a mágica final.
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(
DetalheCarroViewModel::class.java)
val binding:
DetalheCarroFragmentBinding =
DataBindingUtil.setContentView(
activity!!,
R.layout.detalhe_carro_fragment)
binding.viewModel = viewModel
viewModel.car = arguments?.getSerializable("car") as Car
}
ViewModel, LiveData e DataBinding
● Passo 14) Mudança no adapter.
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.viewRoot.txt_detail.text = "${myDataset[position].model} -
${myDataset[position].manufacturer}"
holder.viewRoot.setOnClickListener {
val intent = Intent(context, DetalheCarro::class.java)
intent.putExtra("car", myDataset[position])
context.startActivity(intent)
}
}
ViewModel, LiveData e DataBinding
● Passo 14) Na classe DetalheCarro.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.detalhe_carro_activity)
val car = intent.getSerializableExtra("car") as Car
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container,
DetalheCarroFragment.newInstance(car))
.commitNow()
}
}
ViewModel, LiveData e DataBinding
● Passo 14) Na classe DetalheCarroFragment.
companion object {
fun newInstance(car: Car): DetalheCarroFragment {
val f = DetalheCarroFragment()
val args = Bundle()
args.putSerializable("car", car)
f.arguments = args
return f
}
}

Mais conteúdo relacionado

Semelhante a Desenvolvimento de Aplicativos Android com JetPack

Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineCampus Party Brasil
 
JSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com JavaJSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com JavaDr. Spock
 
SESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao AndroidSESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao AndroidRafael Sakurai
 
Material Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu AppMaterial Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu Appalissin
 
2017 08-11 - Androidos V - Minicurso - Introdução ao android
2017 08-11 - Androidos V - Minicurso - Introdução ao android2017 08-11 - Androidos V - Minicurso - Introdução ao android
2017 08-11 - Androidos V - Minicurso - Introdução ao androidMessias Batista
 
Aula02 android hands_on
Aula02 android hands_onAula02 android hands_on
Aula02 android hands_onRoberson Alves
 
InterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecer
InterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecerInterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecer
InterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouqueceriMasters
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysDr. Spock
 
Curso de android
Curso de androidCurso de android
Curso de androidflaviokreis
 
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.Sergio Lima
 
Phonegap - Framework Mobile
Phonegap - Framework MobilePhonegap - Framework Mobile
Phonegap - Framework MobileIldyone Martins
 
Android Palestra
Android PalestraAndroid Palestra
Android PalestraRenato
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifaguestea329c
 

Semelhante a Desenvolvimento de Aplicativos Android com JetPack (20)

Desenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App EngineDesenvolvimento de aplicações para o Google App Engine
Desenvolvimento de aplicações para o Google App Engine
 
JSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com JavaJSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com Java
 
Apresentação Google Android
Apresentação Google AndroidApresentação Google Android
Apresentação Google Android
 
SESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao AndroidSESTINFO 2011 Apresentacao Android
SESTINFO 2011 Apresentacao Android
 
Material Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu AppMaterial Design - Melhorando a experiência de seu App
Material Design - Melhorando a experiência de seu App
 
2017 08-11 - Androidos V - Minicurso - Introdução ao android
2017 08-11 - Androidos V - Minicurso - Introdução ao android2017 08-11 - Androidos V - Minicurso - Introdução ao android
2017 08-11 - Androidos V - Minicurso - Introdução ao android
 
Aula02 android hands_on
Aula02 android hands_onAula02 android hands_on
Aula02 android hands_on
 
InterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecer
InterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecerInterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecer
InterCon 2016 - Gerenciando deploy e atualização de 450 apps sem enlouquecer
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
 
Curso de android
Curso de androidCurso de android
Curso de android
 
Android Libs - AndroidDevConf
Android Libs - AndroidDevConfAndroid Libs - AndroidDevConf
Android Libs - AndroidDevConf
 
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
Introduzindo StimulusJS: o novo Framework JavaScript para Ruby On Rails.
 
Phonegap - Framework Mobile
Phonegap - Framework MobilePhonegap - Framework Mobile
Phonegap - Framework Mobile
 
Mini curso de c#.net
Mini curso de c#.netMini curso de c#.net
Mini curso de c#.net
 
Desenvolvimento iOS
Desenvolvimento iOSDesenvolvimento iOS
Desenvolvimento iOS
 
Android Palestra
Android PalestraAndroid Palestra
Android Palestra
 
Selenium - WebDriver
Selenium - WebDriverSelenium - WebDriver
Selenium - WebDriver
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifa
 
ASP.NET MVC
ASP.NET MVCASP.NET MVC
ASP.NET MVC
 
RodoCap no JustJava 2008
RodoCap no JustJava 2008RodoCap no JustJava 2008
RodoCap no JustJava 2008
 

Mais de Ricardo Ogliari

Clean Code/Architecture com Android e Flutter
Clean Code/Architecture com Android e FlutterClean Code/Architecture com Android e Flutter
Clean Code/Architecture com Android e FlutterRicardo Ogliari
 
Mobile, Flutter e Mercado
Mobile, Flutter e MercadoMobile, Flutter e Mercado
Mobile, Flutter e MercadoRicardo Ogliari
 
Programando em ruby para arduino
Programando em ruby para arduinoProgramando em ruby para arduino
Programando em ruby para arduinoRicardo Ogliari
 
Intel edison Primeiro Projeto
Intel edison Primeiro ProjetoIntel edison Primeiro Projeto
Intel edison Primeiro ProjetoRicardo Ogliari
 
Internacionalizando um aplicativo BlackBerry API
Internacionalizando um aplicativo BlackBerry APIInternacionalizando um aplicativo BlackBerry API
Internacionalizando um aplicativo BlackBerry APIRicardo Ogliari
 
Como criar interfaces gráficas com android
Como criar interfaces gráficas com androidComo criar interfaces gráficas com android
Como criar interfaces gráficas com androidRicardo Ogliari
 
Criando itens de menu em aplicativos nativos com a BlackBerry API
Criando itens de menu em aplicativos nativos com a BlackBerry APICriando itens de menu em aplicativos nativos com a BlackBerry API
Criando itens de menu em aplicativos nativos com a BlackBerry APIRicardo Ogliari
 
Utilizando O Cell Id Para Popularizar Os Sistemas Lbs
Utilizando O Cell Id Para Popularizar Os Sistemas LbsUtilizando O Cell Id Para Popularizar Os Sistemas Lbs
Utilizando O Cell Id Para Popularizar Os Sistemas LbsRicardo Ogliari
 
Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.
Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.
Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.Ricardo Ogliari
 
A hora de criar LBS para pequenos dispositivos é agora!!
A hora de criar LBS para pequenos dispositivos é agora!!A hora de criar LBS para pequenos dispositivos é agora!!
A hora de criar LBS para pequenos dispositivos é agora!!Ricardo Ogliari
 

Mais de Ricardo Ogliari (15)

IoT além do Arduino
IoT além do ArduinoIoT além do Arduino
IoT além do Arduino
 
Clean Code/Architecture com Android e Flutter
Clean Code/Architecture com Android e FlutterClean Code/Architecture com Android e Flutter
Clean Code/Architecture com Android e Flutter
 
Mobile, Flutter e Mercado
Mobile, Flutter e MercadoMobile, Flutter e Mercado
Mobile, Flutter e Mercado
 
Programando em ruby para arduino
Programando em ruby para arduinoProgramando em ruby para arduino
Programando em ruby para arduino
 
Intel edison Primeiro Projeto
Intel edison Primeiro ProjetoIntel edison Primeiro Projeto
Intel edison Primeiro Projeto
 
Internacionalizando um aplicativo BlackBerry API
Internacionalizando um aplicativo BlackBerry APIInternacionalizando um aplicativo BlackBerry API
Internacionalizando um aplicativo BlackBerry API
 
Como criar interfaces gráficas com android
Como criar interfaces gráficas com androidComo criar interfaces gráficas com android
Como criar interfaces gráficas com android
 
Bada
BadaBada
Bada
 
Internacionalizacao
InternacionalizacaoInternacionalizacao
Internacionalizacao
 
Palm e web os
Palm e web osPalm e web os
Palm e web os
 
Trechos interessantes
Trechos interessantesTrechos interessantes
Trechos interessantes
 
Criando itens de menu em aplicativos nativos com a BlackBerry API
Criando itens de menu em aplicativos nativos com a BlackBerry APICriando itens de menu em aplicativos nativos com a BlackBerry API
Criando itens de menu em aplicativos nativos com a BlackBerry API
 
Utilizando O Cell Id Para Popularizar Os Sistemas Lbs
Utilizando O Cell Id Para Popularizar Os Sistemas LbsUtilizando O Cell Id Para Popularizar Os Sistemas Lbs
Utilizando O Cell Id Para Popularizar Os Sistemas Lbs
 
Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.
Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.
Instalando e Configurando o JIL SDK. Crie seu primeiro widget com a ferramenta.
 
A hora de criar LBS para pequenos dispositivos é agora!!
A hora de criar LBS para pequenos dispositivos é agora!!A hora de criar LBS para pequenos dispositivos é agora!!
A hora de criar LBS para pequenos dispositivos é agora!!
 

Desenvolvimento de Aplicativos Android com JetPack

  • 1.
  • 2. Projeto e Desenvolvimento de Aplicações Android ● Três encontros 04/04, 18/04 e 25/04. ● Projeto de aplicações Android. ● Orientações para elaboração de interface de usuário para Android. ● Boas práticas no desenvolvimento móvel e Android. ● Teste de aplicações Android. ● Desenvolvimento Prático. ● Publicação de aplicações Android.
  • 3. Projeto e Desenvolvimento de Aplicações Android ● Avaliação: ● Conceito C: ○ Apresentação da idéia (04/04) ○ Entrega de uma aplicação com uso de, no mínimo, 3 bibliotecas do Android JetPack (ViewModel, LiveData e DataBinding) ● Conceito B: ○ Uso de mais 2 pacotes JetPack, sendo um deles o Navigation. ● Conceito A: ○ Uso de mais 2 pacotes JetPack.
  • 4. Projeto e Desenvolvimento de Aplicações Android ● Foco da Disciplina: ● Android JetPack ● Porém, antes disso, alguma dúvida sobre Android?
  • 5.
  • 7. JetPack ● O Jetpack é um conjunto de bibliotecas, ferramentas e orientações para ajudar os desenvolvedores a criar apps de alta qualidade com mais facilidade. Esses componentes ajudam você a seguir as práticas recomendadas, acabando com os códigos de texto clichê e simplificando tarefas complexas, para que você possa se concentrar na parte do código do seu interesse. ● O Jetpack compõe as bibliotecas de pacotes androidx.*, separadas das APIs da plataforma. Isso significa que ele oferece compatibilidade com versões anteriores e é atualizado com mais frequência que a Plataforma Android, garantindo que você sempre tenha acesso às versões melhores e mais recentes dos componentes do Jetpack. https://developer.android.com/jetpack
  • 10.
  • 11. ViewModel, LiveData e DataBinding ● Passo 1) Criamos um projeto Android
  • 12. ViewModel, LiveData e DataBinding ● Passo 2) Criar uma Activity
  • 13. ViewModel, LiveData e DataBinding ● Passo 3) Nomear como ListaCarros
  • 14. ViewModel, LiveData e DataBinding ● Passo 4) Remover a MainActivity e limpar suas referências. <application ...> <activity android:name=".ListaCarros"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
  • 15. ViewModel, LiveData e DataBinding ● Passo 5) Verificar se a criação da ViewModel não está depreciada. viewModel = ViewModelProvider(this).get(ListaCarrosViewModel::class.java)
  • 16. ViewModel, LiveData e DataBinding https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e
  • 17. ViewModel, LiveData e DataBinding ● Passo 5) Provando os conceitos class ListaCarrosViewModel : ViewModel() { init { Log.e("teste", "init viewmodel ${this.toString()}"); } override fun onCleared() { super.onCleared() Log.e("teste", "init onCleared"); } }
  • 18. ViewModel, LiveData e DataBinding ● Passo 5) Provando os conceitos class ListaCarrosFragment : Fragment() { ... override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProvider(this).get(ListaCarrosViewModel::class.java) Log.e("teste", "viewModel ${viewModel.toString()}") } }
  • 19. ViewModel, LiveData e DataBinding ● Passo 6) Inserindo dados - criando uma DataClass data class Car( val manufacturer: String, val model: String, val price: Float, val photo: String)
  • 20. ViewModel, LiveData e DataBinding ● Passo 6) Alterar o lista_carros_fragment.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout ...> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_cars" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
  • 21. ViewModel, LiveData e DataBinding ● Passo 6) Criar um arquivo item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:padding="10dp" android:id="@+id/txt_detail" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
  • 22. ViewModel, LiveData e DataBinding ● Passo 6) Criaremos um adapter para o RecyclerView class CarsAdapter(private val myDataset: List<Car>) : RecyclerView.Adapter<CarsAdapter.MyViewHolder>() { class MyViewHolder(val viewRoot: View) : RecyclerView.ViewHolder(viewRoot) override fun onCreateViewHolder( parent: ViewGroup, viewType: Int): CarsAdapter.MyViewHolder { val textView = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false) return MyViewHolder(textView) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.viewRoot.txt_detail.text = "${myDataset[position].model} - ${myDataset[position].manufacturer}" } override fun getItemCount() = myDataset.size }
  • 23. ViewModel, LiveData e DataBinding ● Passo 6) Editar ListaCarrosFragment private lateinit var viewAdapter: RecyclerView.Adapter<*> private lateinit var viewManager: RecyclerView.LayoutManager override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProvider(this).get(ListaCarrosViewModel::class.java) viewManager = LinearLayoutManager(activity) viewAdapter = CarsAdapter(viewModel.cars) rv_cars.apply { setHasFixedSize(true) layoutManager = viewManager adapter = viewAdapter } }
  • 24. ViewModel, LiveData e DataBinding ● Passo 6) Edição do ViewModel class ListaCarrosViewModel : ViewModel() { var cars: MutableList<Car> = ArrayList<Car>(); init { val ecosport = Car("Ford", "EcoSport", 59000.0f, "https://www..."); val i30 = Car("Hiunday", "i30", 27000.0f, "https://cdn…."); cars.add(ecosport); cars.add(i30); } }
  • 25. ViewModel, LiveData e DataBinding ● Passo 7) Vamos fazer um teste! class ListaCarrosViewModel : ViewModel() { var cars: MutableList<Car> = ArrayList<Car>(); fun getCars(){ GlobalScope.launch { Thread.sleep(10000) val ecosport = Car("Ford", "EcoSport", 59000.0f, "https://ww..."); val i30 = Car("Hiunday", "i30", 27000.0f, "https://cd..."); cars.add(ecosport); cars.add(i30); } } }
  • 26. ViewModel, LiveData e DataBinding ● Passo 8) Observer class ListaCarrosViewModel : ViewModel() { var cars: MutableLiveData<List<Car>> = MutableLiveData<List<Car>>(); fun getCars(){ val ecosport = Car("Ford", "EcoSport", 59000.0f, "https://www.slavie..."); val i30 = Car("Hiunday", "i30", 27000.0f, "https://cdn.salaodo..."); val tempCars: MutableList<Car> = ArrayList(); tempCars.add(ecosport); tempCars.add(i30); cars.value = tempCars; } }
  • 27. ViewModel, LiveData e DataBinding ● Passo 8) Observer override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProvider(this).get(ListaCarrosViewModel::class.java) viewManager = LinearLayoutManager(activity) rv_cars.apply { setHasFixedSize(true) layoutManager = viewManager } viewModel.cars.observe(viewLifecycleOwner, Observer { viewModel.cars.value?.let { viewAdapter = CarsAdapter(it) rv_cars.adapter = viewAdapter; } }) viewModel.getCars(); }
  • 28. ViewModel, LiveData e DataBinding ● Passo 9) Nova tela Fragment+ViewModel com o nome DetalheCarro.
  • 29. ViewModel, LiveData e DataBinding ● Passo 10) Corrija a instância do ViewModel. viewModel = ViewModelProvider(this).get(DetalheCarroViewModel::class.java)
  • 30. ViewModel, LiveData e DataBinding ● Passo 11) Navegação entre telas. Mudança no adapter. class CarsAdapter( private val myDataset: List<Car>, private val context: Context) : RecyclerView.Adapter<CarsAdapter.MyViewHolder>() { override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.viewRoot.setOnClickListener { context.startActivity(Intent(context, DetalheCarro::class.java)) } } }
  • 31. ViewModel, LiveData e DataBinding ● Passo 11) Navegação entre telas. Instância precisa passar o contexto. viewModel.cars.observe(viewLifecycleOwner, Observer { viewModel.cars.value?.let { viewAdapter = CarsAdapter(it, activity as Context) rv_cars.adapter = viewAdapter; } })
  • 32. ViewModel, LiveData e DataBinding ● Passo 12) Último conceito: DataBinding.
  • 33. ViewModel, LiveData e DataBinding ● Passo 13) Último conceito: DataBinding. apply plugin: 'kotlin-kapt' android { dataBinding { enabled true } } dependencies { implementation 'androidx.core:core-ktx:1.2.0' kapt 'com.android.databinding:compiler:3.1.4' }
  • 34. ViewModel, LiveData e DataBinding ● Passo 14) Tags layout e data. class DetalheCarroViewModel : ViewModel() { var car: Car? = null; }
  • 35. ViewModel, LiveData e DataBinding ● Passo 14) Tags layout e data. <?xml version="1.0" encoding="utf-8"?> <layout 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"> <data> <variable name="viewModel" type="com.study.aula1possenac.ui.detalhecarro.DetalheCarroViewMode l" /> </data> <androidx.constraintlayout.widget.ConstraintLayout ...> ... </androidx.constraintlayout.widget.ConstraintLayout> </layout>
  • 36. ViewModel, LiveData e DataBinding ● Passo 14) Tags layout e data. <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/detalhecarro" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.detalhecarro.DetalheCarroFragment"> <LinearLayout android:id="@+id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <TextView android:text="@{viewModel.car.model}" android:textSize="25dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:textSize="20dp" android:text="@{viewModel.car.manufacturer}" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
  • 37. ViewModel, LiveData e DataBinding ● Passo 14) DataBinding é a mágica final. override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProvider(this).get( DetalheCarroViewModel::class.java) val binding: DetalheCarroFragmentBinding = DataBindingUtil.setContentView( activity!!, R.layout.detalhe_carro_fragment) binding.viewModel = viewModel viewModel.car = arguments?.getSerializable("car") as Car }
  • 38. ViewModel, LiveData e DataBinding ● Passo 14) Mudança no adapter. override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.viewRoot.txt_detail.text = "${myDataset[position].model} - ${myDataset[position].manufacturer}" holder.viewRoot.setOnClickListener { val intent = Intent(context, DetalheCarro::class.java) intent.putExtra("car", myDataset[position]) context.startActivity(intent) } }
  • 39. ViewModel, LiveData e DataBinding ● Passo 14) Na classe DetalheCarro. override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.detalhe_carro_activity) val car = intent.getSerializableExtra("car") as Car if (savedInstanceState == null) { supportFragmentManager.beginTransaction() .replace(R.id.container, DetalheCarroFragment.newInstance(car)) .commitNow() } }
  • 40. ViewModel, LiveData e DataBinding ● Passo 14) Na classe DetalheCarroFragment. companion object { fun newInstance(car: Car): DetalheCarroFragment { val f = DetalheCarroFragment() val args = Bundle() args.putSerializable("car", car) f.arguments = args return f } }