Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Training Program - Portugal, Aula 3

ATP Portugal
November 04, 2020

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
Tweet

More Decks by ATP Portugal

Other Decks in Programming

Transcript

  1. • 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
  2. Andres-Leonardo Martinez-Ortiz Google Carlos Mota Formador Renato Almeida Formador @davilagrau

    @cafonsomota @tallnato Equipa Daniela Ferreira Gestora de comunidades
  3. • 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
  4. #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 ✅ ✅
  5. 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
  6. • Descreve a interface gráfica • Tipicamente declarado num XML,

    mas pode ser construído programaticamente Layouts
  7. • Os elementos estão alinhados numa direção ◦ Horizontal ◦

    Vertical • Os filhos podem ter pesos LinearLayout
  8. 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>
  9. 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>
  10. 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>
  11. 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>
  12. • 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
  13. 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>
  14. <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
  15. <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
  16. • Os elementos estão dispostos numa grelha • Os elementos

    podem ocupar mais do que uma coluna ou linha GridLayout
  17. 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>
  18. • Normalmente utilizado para ocupar uma determinada área do ecrã

    • Filhos posicionados através da gravidade • Tipicamente utilizado para colocar os Fragments FrameLayout
  19. 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>
  20. • 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
  21. 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" /> ...
  22. 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>
  23. Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)

    Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5
  24. Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)

    Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5
  25. Resolução medium resolution (mdpi) HTC Wildfire S high resolution (hdpi)

    Samsung Galaxy S2 extra extra extra high resolution (xxxhdpi) Pixel 5 2x2 pixels
  26. 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
  27. • 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
  28. • 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
  29. ImageView • Permite adicionares uma imagem e/ou cor ao ecrã

    • Podes fazê-lo a partir: ◦ android:src ◦ android:background
  30. 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 ❓
  31. 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() } } }
  32. 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 } } }
  33. 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 } } }
  34. Voltar para trás class MainActivity : AppCompatActivity() { override fun

    onBackPressed() { Toast.makeText(this, "Bobi", Toast.LENGTH_SHORT).show() } }
  35. Instagram Action bar Custom layout Custom layout Custom layout BottomNavigationView

    LinearLayout • RecyclerView • TextView • ImageView
  36. Trabalho para casa • Implementar a página inicial do Instagram

    ◦ ActionBar ◦ Histórias ◦ Feed ◦ BottomNavigationView
  37. DogsO’gram • Implementar a página inicial do Instagram ◦ ActionBar

    ◦ Histórias ◦ Feed ◦ BottomNavigationView
  38. 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
  39. DogsO’gram override fun onCreateOptionsMenu(menu: Menu?): Boolean { val inflater =

    menuInflater inflater.inflate(R.menu.menu_action, menu) return true } MainActivity.kt action bar
  40. 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
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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
  46. class Dog { companion object { const val TAG =

    “Dog” } } public class Dog { public static final String TAG = "Dog"; } Static
  47. 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
  48. 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
  49. 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>
  50. 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>
  51. 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>
  52. Limites dos layouts Para ativar: 1. Definições 2. Sistema 3.

    Opções de programador 4. Mostrar limites do esquema
  53. 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>
  54. 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>
  55. 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>
  56. 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>
  57. 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>
  58. 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
  59. Trabalho para casa • Mensagem de boas vindas no ecrã

    principal ◦ Com o nome de utilizador introduzido
  60. 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