Share
Embed
Android Training Program - Portugal, Aula 3
Aula #3: Fundações II 🏘
Como é que customizamos e embelezamos a nossa aplicação? O que acontece quando o utilizador carrega num botão?
- Layouts
- Views (TextView, ImageView, Button, etc.)
- Interação com o utilizador
ATP Portugal
November 04, 2020
Transcript
129 slides
-
• Sejam excelentes uns para os outros • Fale mais
alto se vir ou ouvir alguma coisa • O assédio não é tolerado • Pratique "Sim e" um ao outro Código de conduta Mais informações: http://bit.ly/2IhF0l3 -
Andres-Leonardo Martinez-Ortiz Google Carlos Mota Formador Renato Almeida Formador @davilagrau
@cafonsomota @tallnato Equipa Daniela Ferreira Gestora de comunidades -
• 12 aulas • 1h30 cada aula • ~1 aula
por semana • 14 Outubro a 16 Dezembro • YouTube live • Suporte assíncrono contínuo via Discord/email • Todo o código disponível no GitHub Photo by Arif Riyanto on Unspla O programa -
#0 14 de Outubro Pronto para começar #1 21 de
Outubro Bem-vindos ao Android #2 28 de Outubro Fundações I #3 04 de Novembro Fundações II #4 11 de Novembro Fundações III #5 18 de Novembro Listas, listas e mais listas #6 25 de Novembro Jetpack, Jetpack, Jetpack! #7 - #8 02 - 03 de Dezembro Firebase #9 - #10 09 - 10 de Dezembro MLKit & TensorFlow #11 16 de Dezembro Resumo Semana Semana Calendário ✅ Direto ✅ ✅ -
Sumário Photo by Mika Baumeister on Unsplash • Resumo da
aula anterior • Layouts, views, interações • Passaporte para a Google • Kotlin para principiantes • Sexta-Feira negra -
AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pt.atp.bobi"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true"
android:theme="@style/Theme.Bobi"> ... </application> </manifest> -
• Descreve a interface gráfica • Tipicamente declarado num XML,
mas pode ser construído programaticamente Layouts -
• Os elementos estão alinhados numa direção ◦ Horizontal ◦
Vertical • Os filhos podem ter pesos LinearLayout -
LinearLayout <LinearLayout ... android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bobi" /> <Button
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Max" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Rex" /> </LinearLayout> -
LinearLayout <LinearLayout ... android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bobi" /> <Button
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Max" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Rex" /> </LinearLayout> -
LinearLayout <LinearLayout ... android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bobi" /> <Button
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Max" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Rex" /> </LinearLayout> -
LinearLayout <LinearLayout ... android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Bobi" />
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Max" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Rex" /> </LinearLayout> -
• Dispõe os elementos em posições relativas ◦ Relativo ao
pai, ou a outros elementos ◦ Esquerda ou direita, cima ou baixo • Permite ‘achatar’ o layout, melhorando a performance RelativeLayout -
RelativeLayout <RelativeLayout ...> <Button android:text="Bobi" android:id="@+id/bobi" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button
android:text="Rex" android:id="@+id/rex" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_below="@id/bobi" android:layout_alignParentStart="true" android:layout_toStartOf="@+id/max" /> <Button android:text="Max" android:id="@id/max" android:layout_width="96dp" android:layout_height="wrap_content" android:layout_below="@id/bobi" android:layout_alignParentEnd="true" /> <Button android:text="Luna" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/max" android:layout_centerHorizontal="true" /> </RelativeLayout> -
<RelativeLayout ...> <Button android:id="@+id/bobi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="Bobi" /> <Button
android:id="@+id/rex" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/bobi" android:layout_alignStart="@id/bobi" android:text="Rex" /> <Button android:id="@+id/luna" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/rex" android:layout_alignStart="@id/rex" android:text="Luna" /> <Button android:id="@+id/max" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/luna" android:layout_alignStart="@id/luna" android:text="Max" /> </RelativeLayout> RelativeLayout -
<RelativeLayout ...> <Button android:id="@+id/bobi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Bobi" /> <Button
android:id="@+id/rex" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/bobi" android:layout_alignStart="@id/bobi" android:text="Rex" /> <Button android:id="@+id/luna" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/rex" android:layout_alignStart="@id/rex" android:text="Luna" /> <Button android:id="@+id/max" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/luna" android:layout_alignStart="@id/luna" android:text="Max" /> </RelativeLayout> RelativeLayout -
• Os elementos estão dispostos numa grelha • Os elementos
podem ocupar mais do que uma coluna ou linha GridLayout -
GridLayout <GridLayout ... android:columnCount="3"> <Button android:layout_row="0" android:layout_column="0" android:text="Bobi" /> <Button
android:layout_row="0" android:layout_column="1" android:text="Rex" /> <Button android:layout_row="0" android:layout_rowSpan="2" android:layout_column="2" android:layout_gravity="fill_vertical" android:text="Luna" /> <Button android:layout_row="1" android:layout_column="0" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" android:text="Max" /> </GridLayout> -
• Normalmente utilizado para ocupar uma determinada área do ecrã
• Filhos posicionados através da gravidade • Tipicamente utilizado para colocar os Fragments FrameLayout -
FrameLayout <FrameLayout ...> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bobi" /> <Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_gravity="center" android:text="Rex" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center|bottom" android:text="Luna" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|end" android:text="Max" /> </FrameLayout> -
• Permite criar layouts grandes e complexos, com uma hierarquia
plana • Relações entre os filhos e o pai definem as posições • Muito parecido com o RelativeLayout, mas com melhor performance ConstraintLayout -
ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout ...> <Button android:id="@+id/bobi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bobi" /> <Button
android:layout_width="0dp" android:layout_height="wrap_content" android:text="Rex" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> ... -
ConstraintLayout ... <Button android:id="@+id/luna" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Luna" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Max" app:layout_constraintBottom_toTopOf="@+id/luna" app:layout_constraintEnd_toStartOf="@+id/luna" /> </androidx.constraintlayout.widget.ConstraintLayout> -
Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)
Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5 -
Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)
Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5 -
Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)
Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5 2x2 pixels -
Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)
Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5 2x2 dp’s -
• DP vem de density-independent pixel ◦ Este valor é
calculado pelo sistema consoante a resolução do vosso telemóvel ◦ Devem utilizar sempre dp e não px (pixel) ◦ Se usarem px vão ter diferentes comportamentos em telemóveis com diferentes resoluções Resolução dp’s -
• SP vem de scale-independent pixel ◦ Semelhante ao dp
◦ Tem em consideração o tamanho da fonte escolhida pelo utilizador ◦ Deve ser utilizado em TextView (em vez de dp/px) Resolução sp’s -
TextView <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="@string/say_hello"
android:textSize="21sp" android:textStyle="bold"/> textStyle -
TextView <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="@string/say_hello"
android:textSize="21sp" android:textStyle="bold"/> android:textColor="@color/colorPrimary"/> textColor -
ImageView • Permite adicionares uma imagem e/ou cor ao ecrã
• Podes fazê-lo a partir: ◦ android:src ◦ android:background -
ImageView <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:src="@drawable/android_logo"/>
<!-- Default value for android:scaleType is fitCenter --> scaletype -
ImageView <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:src="@drawable/android_logo"/>
<!-- Default value for android:scaleType is fitCenter --> scaletype -
ImageView <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:src="@drawable/android_logo"
android:background="@color/colorPrimary"/> src vs background -
ImageView <?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:src="@color/colorPrimary"
android:background="@drawable/android_logo"/> src vs background -
Drawable <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="@color/colorPrimary" />
<corners android:topRightRadius="25dp" android:topLeftRadius="25dp" android:bottomRightRadius="25dp" android:bottomLeftRadius="25dp"/> </shape> background res/drawable/bg_button.xml ❓ -
• Clique (clickListener) • Clique longo (longClickListener) • Tocar/deslizar (touchListener)
• Voltar para trás (back) Interação -
Clique class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val bobiButton = findViewById<Button>(R.id.bobi) bobiButton.setOnClickListener { Toast.makeText(this, "Bobi", Toast.LENGTH_SHORT).show() } } } -
Clique longo class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState:
Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val bobiButton = findViewById<Button>(R.id.bobi) bobiButton.setOnLongClickListener { Toast.makeText(this, "Bobi Longo", Toast.LENGTH_SHORT) .show() true } } } -
Tocar/deslizar class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val root = findViewById<View>(android.R.id.content) root.setOnTouchListener { view, motionEvent -> Toast.makeText(this, "x:${motionEvent.x} y:${motionEvent.y}", Toast.LENGTH_SHORT).show() true } } } -
Voltar para trás class MainActivity : AppCompatActivity() { override fun
onBackPressed() { Toast.makeText(this, "Bobi", Toast.LENGTH_SHORT).show() } } -
Voltar para trás class MainActivity : AppCompatActivity() { ... override
fun onBackPressed() { showDialog() } } -
Voltar para trás class MainActivity : AppCompatActivity() { ... override
fun onBackPressed() { showDialog() } } -
Instagram Action bar Custom layout Custom layout Custom layout BottomNavigationView
LinearLayout • RecyclerView • TextView • ImageView -
Trabalho para casa • Implementar a página inicial do Instagram
◦ ActionBar ◦ Histórias ◦ Feed ◦ BottomNavigationView -
DogsO’gram • Implementar a página inicial do Instagram ◦ ActionBar
◦ Histórias ◦ Feed ◦ BottomNavigationView -
DogsO’gram <?xml version="1.0" encoding="utf-8"?> <menu xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" > <item
android:id="@+id/action_photo" android:orderInCategory="100" android:icon="@drawable/ic_camera" android:title="@string/action_camera" app:showAsAction="always" tools:ignore="AlwaysShowAction"/> <item android:id="@+id/action_live" android:orderInCategory="100" android:icon="@drawable/ic_live" android:title="@string/action_live" app:showAsAction="always" tools:ignore="AlwaysShowAction" /> //.. res/menu/menu_action.xml action bar -
DogsO’gram override fun onCreateOptionsMenu(menu: Menu?): Boolean { val inflater =
menuInflater inflater.inflate(R.menu.menu_action, menu) return true } MainActivity.kt action bar -
DogsO’gram <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:orientation="horizontal"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1"
android:text="@string/stories"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" android:text="@string/watch_all" android:textSize="15sp" android:fontFamily="sans-serif" app:drawableLeftCompat="@drawable/ic_play" /> </LinearLayout> res/layout/activity_main.xml histórias -
DogsO’gram <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="8dp"
android:orientation="vertical" > //.. </LinearLayout> res/layout/item_story.xml histórias -
DogsO’gram <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="8dp"
android:orientation="vertical" > <ImageView android:id="@+id/iv_user_image" android:layout_width="75dp" android:layout_height="75dp" android:contentDescription="@string/description_user_story" android:scaleType="centerCrop" android:background="@drawable/circle" android:src="@drawable/alan_king_unsplash"/> <TextView android:id="@+id/tv_user_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/app_name" android:textSize="15sp" android:textStyle="bold" android:fontFamily="sans-serif"/> </LinearLayout> res/layout/item_story.xml histórias -
DogsO’gram <?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="vertical"> //...
<pt.atp.dogsogram.SquareImageView android:id="@+id/iv_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:contentDescription="@string/description_feed_photo" android:scaleType="centerCrop" android:src="@drawable/alan_king_unsplash"/> </LinearLayout> res/layout/item_feed.xml feed -
DogsO’gram class SquareImageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null,
defStyleAttr: Int = 0) : AppCompatImageView(context, attrs, defStyleAttr){ override fun onMeasure(width: Int, height: Int) = super.onMeasure(width, width) } SquareImageView.kt criar a tua implementação de um componente -
DogsO’gram <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/nav_home" android:icon="@drawable/ic_home" android:title="@string/navigation_home"
/> <item android:id="@+id/nav_search" android:icon="@drawable/ic_search" android:title="@string/navigation_search" /> <item android:id="@+id/nav_more" android:icon="@drawable/ic_more" android:title="@string/navigation_more" /> //... </menu> res/menu/menu_navigation.xml BottomNavigationView -
class Dog { companion object { fun newDog(name: String){ return
Dog(name) } } } public class Dog { static Dog newDog(String name){ return new Dog(name); } ... } Métodos estáticos -
class Dog { companion object { const val TAG =
“Dog” } } public class Dog { public static final String TAG = "Dog"; } Static -
val dog = Dog() dog.apply { name = "Bobi" legs
= 5 color = "Amarelo às pintinhas" weight = 30 } Dog dog = new Dog(); dog.name = "Bobi"; dog.legs = 5; dog.color = "Amarelo às pintinhas" dog.weight = 30 apply -
fun petDog(dog: Dog, after: (Dog)-> Unit ){ println("Festas no $dog")
after(dog) } val bobi = Dog("Bobi") petDog(bobi, { dog -> println("E depois $dog") }) // Festas no Dog(name=Bobi) // E depois Dog(name=Bobi) Funções como parâmetro -
lateinit var dog : Dog println(dog.name) // dog = Dog("bobi")
println(dog.name) // ✅ lateinit -
TextView <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/say_hello" android:textSize="21sp" android:textStyle="bold" android:textColor="@color/colorPrimary" app:drawableLeftCompat="@drawable/ic_favorite"/> </LinearLayout> -
TextView <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/say_hello" android:textSize="21sp" android:textStyle="bold" android:textColor="@color/colorPrimary" app:drawableLeftCompat="@drawable/ic_favorite"/> </LinearLayout> -
TextView <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center">
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/say_hello" android:textSize="21sp" android:textStyle="bold" android:textColor="@color/colorPrimary" app:drawableLeftCompat="@drawable/ic_favorite" app:drawableRightCompat="@drawable/ic_favorite" app:drawableTopCompat="@drawable/ic_favorite" app:drawableBottomCompat="@drawable/ic_favorite"/> </LinearLayout> -
Limites dos layouts Para ativar: 1. Definições 2. Sistema 3.
Opções de programador 4. Mostrar limites do esquema -
imeOptions actionDone <androidx.constraintlayout.widget.ConstraintLayout ...> <EditText android:id="@+id/bobi" android:layout_width="200dp" android:layout_height="wrap_content" android:backgroundTint="@color/red" android:inputType="text"
android:imeOptions="actionDone" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> -
imeOptions actionSearch <androidx.constraintlayout.widget.ConstraintLayout ...> <EditText android:id="@+id/bobi" android:layout_width="200dp" android:layout_height="wrap_content" android:backgroundTint="@color/red" android:inputType="text"
android:imeOptions="actionSearch" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> -
imeOptions actionGo <androidx.constraintlayout.widget.ConstraintLayout ...> <EditText android:id="@+id/bobi" android:layout_width="200dp" android:layout_height="wrap_content" android:backgroundTint="@color/red" android:inputType="text"
android:imeOptions="actionGo" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> -
imeOptions actionNext <androidx.constraintlayout.widget.ConstraintLayout ...> <EditText android:id="@+id/bobi" android:layout_width="200dp" android:layout_height="wrap_content" android:backgroundTint="@color/red" android:inputType="text"
android:imeOptions="actionNext" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> -
imeOptions actionPrevious <androidx.constraintlayout.widget.ConstraintLayout ...> <EditText android:id="@+id/bobi" android:layout_width="200dp" android:layout_height="wrap_content" android:backgroundTint="@color/red" android:inputType="text"
android:imeOptions="actionPrevious" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> -
Trabalho para casa • Ao carregar no botão de ação
do teclado ◦ Validar se as credenciais estão corretas ◦ Navegar para o ecrã principal ◦ Terminar a LoginActivity -
Trabalho para casa • Mensagem de boas vindas no ecrã
principal ◦ Com o nome de utilizador introduzido -
Trabalho para casa • O utilizador consegue ver toda a
informação no ecrã ◦ Desliza o dedo sobre o ecrã ◦ O resto do conteúdo passa a ser visível