Conceitos básicos da AWS
Criar uma aplicação Android
Criar uma aplicação Android simples usando o AWS Amplify

criar aplicativo android
Módulo 1: Criar e implantar um aplicativo Android
Neste módulo, você criará uma aplicação Android e a implantará na nuvem usando o serviço de hospedagem na Web do AWS Amplify.
Introdução
O AWS Amplify fornece um fluxo de trabalho baseado em Git para criar, gerenciar, integrar e implantar back-ends sem servidor para aplicações móveis e Web. A CLI do Amplify fornece uma interface de usuário simples baseada em texto para provisionar e gerenciar serviços de back-end, como autenticação de usuário ou API REST ou GraphQL para suas aplicações. As Bibliotecas do Amplify permitem integrar facilmente esses serviços de back-end com apenas algumas linhas de código em suas aplicações.
Neste módulo, começaremos criando uma aplicação Android nova para fazer anotações (notas) de viagem. Uma nota é composta de um título, uma descrição e uma imagem. Vamos aprimorar essa aplicação nos próximos módulos.
O que você aprenderá
- Criar uma aplicação Android
- Atualizar a visualização principal para exibir uma lista de itens
- Compilar e testar sua aplicação
Conceitos principais
Kotlin – a Kotlin foi escolhida como a linguagem de programação deste tutorial porque permite reduzir muito do código padronizado e foi projetada para segurança de tipo (type safety).
Jetpack – este tutorial usa o Jetpack do Android, uma coleção de bibliotecas do Android que incorporam as melhores práticas e garantem compatibilidade com versões anteriores em seus aplicativos Android.
Tempo para a conclusão
10 minutos
Serviços usados
Implementação
-
Criar um projeto do Android
Inicie o Android Studio e selecione Start a new Android Studio project (Iniciar um novo projeto do Android Studio) na tela inicial:
EmPhone and Tablet (Telefone e tablet), selecione Basic Activity (Atividade básica) e clique em Next (Avançar):
Digite um nome para o projeto, por exemplo Conceitos básicos do Android. Verifique se a linguagem é Kotlin e se o SDK mínimo é API 26: Android 8.0 (oreo) e clique em Finish (Concluir):
Com a estrutura do projeto pronta, seguimos quatro etapas para colocar nosso aplicativo básico em execução:
- Excluir classes e arquivos indesejados e adicionar plug-ins
- Criar classes para manter nossas estruturas de dados
- Criar uma visualização para manter uma nota individual na lista
- Modificar a MainActivity para exibir uma lista de notas
-
Excluir arquivos desnecessários e adicionar plug-ins
Em res/layout e java/com.example.androidgettingstarted, exclua os quatro arquivos de fragmento (selecione os quatro arquivos, clique com o botão direito e escolha Delete [Excluir] no menu contextual):
Em Gradle Scripts (Scripts do Gradle), abra build.gradle (Module:app) e adicione o plug-in de extensão Kotlin.
plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-android-extensions' // <== add this line }
-
Criar uma classe de dados UserData
A classe UserData armazena o estado do usuário: um sinalizador isSignedIn e uma lista de valores de nota.
Para criar uma classe nova, clique com o botão direito em java/com.example/androidgettingstarted e selecione New (Novo) -> Kotlin file/class (Arquivo/classe Kotlin). Digite UserData como o nome.
Cole o código abaixo no arquivo recém-criado (UserData.kt)
package com.example.androidgettingstarted import android.graphics.Bitmap import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData // a singleton to hold user data (this is a ViewModel pattern, without inheriting from ViewModel) object UserData { private const val TAG = "UserData" // // observable properties // // signed in status private val _isSignedIn = MutableLiveData<Boolean>(false) var isSignedIn: LiveData<Boolean> = _isSignedIn fun setSignedIn(newValue : Boolean) { // use postvalue() to make the assignation on the main (UI) thread _isSignedIn.postValue(newValue) } // the notes private val _notes = MutableLiveData<MutableList<Note>>(mutableListOf()) // please check https://stackoverflow.com/questions/47941537/notify-observer-when-item-is-added-to-list-of-livedata private fun <T> MutableLiveData<T>.notifyObserver() { this.postValue(this.value) } fun notifyObserver() { this._notes.notifyObserver() } fun notes() : LiveData<MutableList<Note>> = _notes fun addNote(n : Note) { val notes = _notes.value if (notes != null) { notes.add(n) _notes.notifyObserver() } else { Log.e(TAG, "addNote : note collection is null !!") } } fun deleteNote(at: Int) : Note? { val note = _notes.value?.removeAt(at) _notes.notifyObserver() return note } fun resetNotes() { this._notes.value?.clear() //used when signing out _notes.notifyObserver() } // a note data class data class Note(val id: String, val name: String, val description: String, var imageName: String? = null) { override fun toString(): String = name // bitmap image var image : Bitmap? = null } }
O que acabamos de adicionar?
- A classe UserData é responsável por armazenar os dados do usuário, ou seja, um sinalizador isSignedIn para acompanhar o status de autenticação atual e uma lista de objetos Note.
- Essas duas propriedades são implementadas de acordo com a estrutura de trabalho de publicação/assinatura do LiveData. Isso permite que a interface gráfica do usuário (GUI) assine as alterações e reaja de acordo. Para saber mais sobre o LiveData, você pode ler este documento ou seguir este breve tutorial em vídeo. Para seguir a melhor prática, mantenha a propriedade MutableLiveData privada e exponha apenas a propriedade LiveData somente leitura. É necessário algum código padronizado adicional quando os dados a publicar são uma lista, para garantir que os observadores sejam notificados quando componentes individuais na lista forem modificados.
- Também adicionamos uma nota data class, apenas para armazenar os dados de notas individuais. Duas propriedades distintas são usadas para ImageName e Image. Image será tratado em um módulo subsequente.
- O padrão de projeto singleton foi implementado para o objeto UserData, pois permite que sejam feitas referências a ele de qualquer lugar na aplicação apenas com UserData.
-
Adicionar GUI para células individuais na lista
Células individuais em uma lista de rolagem são chamadas de RecyclerView, pois a visualização pode ser reciclada quando o usuário rola para cima e para baixo, e a visualização não está mais visível na tela.
Assim como em uma visualização normal, criamos arquivos XML de layout e uma classe Kotlin. Esta é a aparência de uma célula:
Para criar o arquivo de layout, clique com o botão direito em res/layout e selecione New -> Layout Resource File (Novo -> Arquivo de recursos de layout). Digite content_note como o nome e mantenha todos os outros valores, pois vamos editar diretamente o arquivo XML.
Abra a visualização Code (Código) do arquivo recém-criado.
Na visualização Code (Código) do arquivo novo recém-criado (content_note.xml), cole o código abaixo para substituir o código gerado:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingVertical="16dp"> <ImageView android:id="@+id/image" android:layout_width="100dp" android:layout_height="match_parent" android:padding="8dp" android:scaleType="centerCrop" android:src="@drawable/ic_launcher_background" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="5dp" android:orientation="vertical"> <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Title" android:textSize="20sp" android:textStyle="bold" /> <TextView android:id="@+id/description" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Title" android:textSize="15sp" /> </LinearLayout> </LinearLayout>
Por fim, crie a classe Kotlin: clique com o botão direito em java/com.example/androidgettingstarted e selecione New -> Kotlin file/class (Novo -> Arquivo/classe Kotlin). Digite NoteRecyclerViewAdapter como o nome.
Cole o código abaixo no arquivo recém-criado (NoteRecyclerViewAdapter.kt)
package com.example.androidgettingstarted import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView // this is a single cell (row) in the list of Notes class NoteRecyclerViewAdapter( private val values: MutableList<UserData.Note>?) : RecyclerView.Adapter<NoteRecyclerViewAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.content_note, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = values?.get(position) holder.nameView.text = item?.name holder.descriptionView.text = item?.description if (item?.image != null) { holder.imageView.setImageBitmap(item.image) } } override fun getItemCount() = values?.size ?: 0 inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val imageView: ImageView = view.findViewById(R.id.image) val nameView: TextView = view.findViewById(R.id.name) val descriptionView: TextView = view.findViewById(R.id.description) } }
O que acabamos de adicionar?
O código acima é composto de- um arquivo xml de layout que descreve o layout do componente em uma célula que representa uma nota. Ele exibe a imagem, além do título e a descrição da nota.
- uma classe Kotlin de suporte. Recebe um objeto de dados de nota no momento da criação e atribui valores individuais às visualizações correspondentes (imagem, título e descrição)
-
Atualizar a atividade principal
Agora que temos as classes de dados (UserData e Note) e a visualização da nota (NoteRecyclerViewAdapter), criaremos a lista de notas na atividade principal.
Na lista de arquivos à esquerda do Android Studio, abra res/layout/content_main.xml e substitua o código por este conteúdo:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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" android:id="@+id/frameLayout" android:layout_width="match_parent" android:layout_height="match_parent" > <androidx.recyclerview.widget.RecyclerView android:id="@+id/item_list" android:name="com.example.myapplication.ItemListFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="60dp" android:paddingHorizontal="8dp" android:paddingVertical="8dp" app:layoutManager="LinearLayoutManager" tools:context=".MainActivity" tools:listitem="@layout/content_note" /> </FrameLayout>
Na lista de arquivos à esquerda do Android Studio, abra java/com.example/androidgettingstarted/MainActivity.kt e substitua o código por este conteúdo:
package com.example.androidgettingstarted import android.os.Bundle import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.content_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setSupportActionBar(toolbar) // prepare our List view and RecyclerView (cells) setupRecyclerView(item_list) } // recycler view is the list of cells private fun setupRecyclerView(recyclerView: RecyclerView) { // update individual cell when the Note data are modified UserData.notes().observe(this, Observer<MutableList<UserData.Note>> { notes -> Log.d(TAG, "Note observer received ${notes.size} notes") // let's create a RecyclerViewAdapter that manages the individual cells recyclerView.adapter = NoteRecyclerViewAdapter(notes) }) } companion object { private const val TAG = "MainActivity" } }
O que acabamos de adicionar?
- o layout principal é um RecyclerView que gerencia a lista de células individuais que criamos anteriormente
- a classe de atividade principal observa as alterações na lista de notas e cria um NoteRecyclerViewAdapter para criar células individuais.
-
Verificar as dependências de compilação
Em Gradle Scripts, abra build.gradle (Module:app) e verifique se as dependências geradas estão corretas. As `versões das bibliotecas` precisam ser verificadas.
```gradle dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.2' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1' implementation 'androidx.navigation:navigation-ui-ktx:2.3.1' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' }
-
Compilar e testar
Agora compile e inicie o aplicativo no simulador. Clique no ícone Run (Executar) ▶️ na barra de ferramentas ou digite ^ R.
Após algum tempo, o aplicativo é iniciado no simulador Android, com uma tela inicial vazia.
Nesse estágio, não há dados a serem renderizados em tempo de execução. Eliminaremos o ícone de e-mail em uma etapa posterior.