<repo_name>TainaRegina/Netflix<file_sep>/CURSO ANDROID UDEMY/KotlinRecylcerView/app/src/main/java/com/example/kotlinrecylcerview/LiveAdapter.kt
package com.example.kotlinrecylcerview

import android.app.DownloadManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.kotlinrecylcerview.models.Live
import kotlinx.android.synthetic.main.res_item_live.view.*

class LiveAdapter(private val onItemClick : (Live) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private var items : List<Live> = ArrayList()

//cria o layout do xml para o código
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return LiveViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.res_item_live, parent, false)
        )

    }

// faz a ligação do xml com o recyclerview
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder){
            is LiveViewHolder ->{
                holder.bind(items[position], onItemClick)

            }
        }

    }

//conta os items que possui na lista
    override fun getItemCount(): Int {
        return items.size

    }

    //pega os items da lista
    fun setDataSet(lives : List<Live>) {
        this.items = lives
    }



    class LiveViewHolder constructor(
        itemView : View
    ): RecyclerView.ViewHolder(itemView){

        private val liveTitle = itemView.textTitulo
        private val autorLive = itemView.textAutor
        private val banerLive = itemView.imageBaner

        fun bind(live: Live, onItemClick: (Live) -> Unit) {
            liveTitle.text = live.title
            autorLive.text = live.autor


            //PARA CHAMAR A URL DA IMAGEM
//            val requestOptions = RequestOptions
//                .placeholder(R.drawable.rocket)
//                .error(R.drawable.rocket)
//
//            Glide.with(itemView.context)
//                .applyDefaultRequestoptions(requestOptions)
//                .load(live.tumbnailURL)
//                .into(banerLive)


//CHAMANDO O CLICK
            itemView.setOnClickListener{
                onItemClick(live)
            }


        }
    }


}<file_sep>/aad-main/app/src/test/java/br/com/programadordeelite/gdc/codelab/debugging/calc/CalculatorTest.kt
package br.com.programadordeelite.gdc.codelab.debugging.calc

import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.equalTo
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

// +-------------------------------------------------------------------------------------+
// | Caso vc tenha algum problema para rodar os testes este link pode ajudar a resolver  |
// +-------------------------------------------------------------------------------------+
// https://stackoverflow.com/questions/47926382/how-to-configure-shorten-command-line-method-for-whole-project-in-intellij

@RunWith(JUnit4::class)
class CalculatorTest {

    private lateinit var calculator: Calculator

    @Before
    fun setUp() {
        calculator = Calculator()
    }

    @Test
    fun add() = assertThat(calculator.add(1.0, 1.0), `is`(equalTo(2.0)))

    @Test
    fun sub() = assertThat(calculator.sub(1.0, 1.0), `is`(equalTo(0.0)))

    @Test
    fun div() = assertThat(calculator.div(1.0, 1.0), `is`(equalTo(1.0)))

    @Test
    fun mul() = assertThat(calculator.mul(2.0, 1.5), `is`(equalTo(3.0)))

    @Test
    fun add_one_positive_number_to_one_negative_number() = assertThat(calculator.add(-1.0, 2.0), `is`(equalTo(1.0)))

    @Test
    fun `add to floats with decimal values to each other` () = assertThat(calculator.add(1.111, 1.111), `is`(equalTo(2.222)))

    @Test
    fun subWorksWithNegativeResult() = assertThat(calculator.sub(1.0, 17.0), `is`(equalTo(-16.0)))

    @Test
    fun divTwoNumbersThroughZero_ShouldReturn_PositiveInfinity() = assertThat(calculator.div(32.0, 0.0), `is`(equalTo(Double.POSITIVE_INFINITY)))

    @Test
    fun divTwoNumbersZeroNegative() = assertThat(calculator.div(-32.0, 0.0), `is`(equalTo(Double.NEGATIVE_INFINITY)))

    @Test
    fun divTwoNumbersNegative() = assertThat(calculator.div(32.0, -2.0), `is`(equalTo(-16.0)))

    // +--------------------------------------------------------------------------+
    // | Boas práticas: separar testes em blocos de positivos e negativos         |
    // +--------------------------------------------------------------------------+
    @Test
    fun positive__divide_two_numbers_should_succeed() = assertThat(calculator.div(3.0, 2.0), `is`(equalTo(1.5)))

    @Test
    fun negative__divide_number_through_zero_should_return_infinity() = assertThat(calculator.div(10.0, 0.0), `is`(equalTo(Double.POSITIVE_INFINITY)))
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/workmanager/BlurViewModel.kt
package br.com.programadordeelite.gdc.codelab.core.workmanager

import android.app.Application
import android.net.Uri
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.work.*

// Modelo que retem as informações e faz a mediação entre workers e observa os estados
class BlurViewModel(application: Application) : AndroidViewModel(application) {

    internal var imageUri: Uri? = null
    internal var outputUri: Uri? = null
    private val workManager = WorkManager.getInstance(application)
    internal val outputWorkInfos: LiveData<List<WorkInfo>>

    init {
        // Adquire um live data do workmanager, para poder observar as mudanças de estado na view
        outputWorkInfos = workManager.getWorkInfosByTagLiveData(TAG_OUTPUT)
    }

    internal fun cancelWork() = workManager.cancelUniqueWork(IMAGE_MANIPULATION_WORK_NAME)

    // cria o input data para o worker
    private fun createInputDataForUri(): Data {
        val builder = Data.Builder()
        imageUri?.let {
            builder.putString(KEY_IMAGE_URI, imageUri.toString())
        }
        return builder.build()
    }

    /**
     * Cria uma requisição de trabalho para liberar espaço, realizar o blur e salvar a imagem
     * @param blurLevel nivel do blur como reflexo da seleção do usuario nos radio buttons
     */
    internal fun applyBlur(blurLevel: Int) {
        // 1) Adiciona o worker de cleanup para limpar arquivos temporarios
        var continuation = workManager
                .beginUniqueWork(
                        IMAGE_MANIPULATION_WORK_NAME,
                        ExistingWorkPolicy.REPLACE,
                        OneTimeWorkRequest.from(CleanupWorker::class.java)
                )

        // 2) adiciona tarefa de blur a quantidade de vezes requisitada
        for (i in 0 until blurLevel) {
            val blurBuilder = OneTimeWorkRequestBuilder<BlurWorker>()

            // Input the Uri if this is the first blur operation
            // After the first blur operation the input will be the output of previous
            // blur operations.
            if (i == 0) {
                blurBuilder.setInputData(createInputDataForUri())
            }

            continuation = continuation.then(blurBuilder.build())
        }

        // Criar um pre-requisito(constraint) de carregamento de bateria
        val constraints = Constraints.Builder()
                .setRequiresCharging(true)
                .build()

        // 3) criar terceira tarefa agora para salvar o arquivo mas so quando estiver carregando
        val save = OneTimeWorkRequestBuilder<SaveImageToFileWorker>()
                .setConstraints(constraints)
                .addTag(TAG_OUTPUT)
                .setInputData(createInputDataForUri())
                .build()

        continuation = continuation.then(save)

        // Por ultimo coloca tudo em uma fila sequencial e inicia o trabalho
        continuation.enqueue()
    }

    private fun uriOrNull(uriString: String?): Uri? {
        return if (!uriString.isNullOrEmpty()) Uri.parse(uriString) else null
    }

    internal fun setImageUri(uri: String?) {
        imageUri = uriOrNull(uri)
    }

    internal fun setOutputUri(outputImageUri: String?) {
        outputUri = uriOrNull(outputImageUri)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabPagerAdapter.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentStatePagerAdapter

// OLD school implementation
class TabPagerAdapter(private val numOfTabs: Int, private val tabViewModel: TabViewModel, fm: FragmentManager) : FragmentStatePagerAdapter(fm) {

    override fun getCount(): Int  = numOfTabs

    override fun getItem(position: Int): Fragment {
        return when (position) {
            0 -> TabOneFragment(tabViewModel)
            1 -> TabTwoFragment(tabViewModel)
            2 -> TabThreeFragment(tabViewModel)
            else -> TabOneFragment(tabViewModel)
        }
    }

    override fun getPageTitle(position: Int): CharSequence {
        return "OBJECT ${(position + 1)}"
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/debugging/calc/CalcFragment.kt
package br.com.programadordeelite.gdc.codelab.debugging.calc

import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentCalcBinding
import timber.log.Timber
import java.lang.IllegalArgumentException

// https://developer.android.com/studio/command-line/adb.html
class CalcFragment : Fragment(R.layout.fragment_calc) {

    private val calculator by lazy { Calculator() }
    private lateinit var binding: FragmentCalcBinding
    private val logTag by lazy { CalcFragment::class.java.simpleName }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentCalcBinding.bind(view)
        binding.operationAddBtn.setOnClickListener { compute(Calculator.Operator.ADD) }
        binding.operationSubBtn.setOnClickListener { compute(Calculator.Operator.SUB) }
        binding.operationDivBtn.setOnClickListener { compute(Calculator.Operator.DIV) }
        binding.operationMulBtn.setOnClickListener { compute(Calculator.Operator.MUL) }
    }

    private fun compute(operation: Calculator.Operator) {
        try {
            val operandOne = binding.operandOneEditText.text.toString().toDouble()
            val operandTwo = binding.operandTwoEditText.text.toString().toDouble()
            binding.operationResultTextView.setText(
                when (operation) {
                    Calculator.Operator.ADD -> calculator.add(operandOne, operandTwo).toString()
                    Calculator.Operator.SUB -> calculator.sub(operandOne, operandTwo).toString()
                    Calculator.Operator.MUL -> calculator.mul(operandOne, operandTwo).toString()
                    Calculator.Operator.DIV -> try {
                        val division = calculator.div(operandOne, operandTwo)
                        if(division.isFinite()) division.toString() else throw IllegalArgumentException("Illegal Division")
                    } catch (iae: IllegalArgumentException) {
                        Log.e(logTag, "IllegalArgumentException", iae) // para exemplificar o uso de Log
                        getString(R.string.computationError)
                    }
                }
            )
        } catch (nfe: NumberFormatException) {
            Timber.e(nfe, "NumberFormatException") // para exemplificar o uso do timber
            binding.operationResultTextView.setText(getString(R.string.computationError))
            return
        }
    }
}<file_sep>/Firebase-Authentication-Android-aula-3/app/src/main/java/br/com/alura/aluraesporte/repository/FirebaseAuthRepository.kt
package br.com.alura.aluraesporte.repository

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.firebase.auth.*
import java.lang.IllegalArgumentException

private const val TAG = "FirebaseAuthRepository"

class FirebaseAuthRepository(private val firebaseAuth: FirebaseAuth) {

    private fun desloga(firebaseAuth: FirebaseAuth) {
        firebaseAuth.signOut()
    }

    private fun verificaUsuario(firebaseAuth: FirebaseAuth) {
        val usuarioFirebase: FirebaseUser? = firebaseAuth.currentUser
        if (usuarioFirebase != null) {

        } else {
        }
    }

    private fun autenticaUsuario(firebaseAuth: FirebaseAuth) {
        firebaseAuth.signInWithEmailAndPassword("<EMAIL>", "<PASSWORD>")
            .addOnSuccessListener {
            }.addOnFailureListener {
            }
    }

    fun cadastra(email: String, senha: String): LiveData<Resource<Boolean>> {
        val liveData = MutableLiveData<Resource<Boolean>>()
        try {
            val tarefa =
                firebaseAuth.createUserWithEmailAndPassword(email, senha)
            tarefa.addOnSuccessListener {
                Log.i(TAG, "cadastra: cadastro sucedido")
                liveData.value = Resource(true)
            }
            tarefa.addOnFailureListener {exception ->
                Log.e(TAG, "cadastra: cadastro falhou", exception)
                val mensagemErro: String = when(exception){
                    is FirebaseAuthWeakPasswordException -> "Senha precisa de pelo menos 6 dígitos"
                    is FirebaseAuthInvalidCredentialsException -> "E-mail inválido"
                    is FirebaseAuthUserCollisionException -> "E-mail já cadastrado"
                    else -> "Erro desconhecido"
                }
                liveData.value = Resource(false, mensagemErro)
            }
        } catch (e: IllegalArgumentException) {
            liveData.value = Resource(false, "E-mail ou senha não ser vazio")
        }
        return liveData
    }

}<file_sep>/AppContatos/app/src/main/java/com/example/appcontatos/MainActivity.kt
package com.example.appcontatos

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Adapter
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private val contatoAdapter = ContatoAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = contatoAdapter

        val contatos = listOf(
            Contato("Contato 1", "99999999", "email"),
            Contato("Contato 2", "99999993", "email"),
            Contato("Contato 3", "99999997", "email"),
            Contato("Contato 4", "99999995", "email"),
            Contato("Contato 5", "99999966", "email")

        )
        contatoAdapter.upDateItems(contatos)

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_cadastrar -> {
                val intent = Intent(this, CadastroActivity::class.java )
                startActivity(intent)
                true
            }
            else -> {
                false
            }
    }

        return super.onOptionsItemSelected(item)
    }
}<file_sep>/white-label-firebase-tutorial-master/app/src/main/java/br/com/douglasmotta/whitelabeltutorial/domain/usecase/GetProductsUseCase.kt
package br.com.douglasmotta.whitelabeltutorial.domain.usecase

import br.com.douglasmotta.whitelabeltutorial.domain.model.Product

interface GetProductsUseCase {

    suspend operator fun invoke(): List<Product>
}<file_sep>/Firebase-Authentication-Android-aula-3/app/src/main/java/br/com/alura/aluraesporte/ui/fragment/CadastroUsuarioFragment.kt
package br.com.alura.aluraesporte.ui.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import br.com.alura.aluraesporte.R
import br.com.alura.aluraesporte.ui.viewmodel.CadastroUsuarioViewModel
import br.com.alura.aluraesporte.ui.viewmodel.ComponentesVisuais
import br.com.alura.aluraesporte.ui.viewmodel.EstadoAppViewModel
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.cadastro_usuario.*
import org.koin.android.viewmodel.ext.android.sharedViewModel
import org.koin.android.viewmodel.ext.android.viewModel

class CadastroUsuarioFragment : Fragment() {

    private val controlador by lazy {
        findNavController()
    }
    private val estadoAppViewModel: EstadoAppViewModel by sharedViewModel()
    private val viewModel: CadastroUsuarioViewModel by viewModel()

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(
            R.layout.cadastro_usuario,
            container,
            false
        )
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        estadoAppViewModel.temComponentes = ComponentesVisuais()
        cadastro_usuario_botao_cadastrar.setOnClickListener {

            cadastro_usuario_email.error = null
            cadastro_usuario_senha.error = null
            cadastro_usuario_confirma_senha.error = null

            val email = cadastro_usuario_email.editText?.text.toString()
            val senha = cadastro_usuario_senha.editText?.text.toString()
            val confirmaSenha = cadastro_usuario_confirma_senha.editText?.text.toString()

            var valido = true

            if(email.isBlank()){
                cadastro_usuario_email.error = "E-mail é necessário"
                valido = false
            }

            if(senha.isBlank()){
                cadastro_usuario_senha.error = "Senha é necessária"
                valido = false
            }

            if(senha != confirmaSenha){
                cadastro_usuario_confirma_senha.error = "Senhas diferentes"
                valido = false
            }

            if(valido){
                viewModel.cadastra(email, senha).observe(viewLifecycleOwner, Observer {
                    it?.let {recurso ->
                        if(recurso.dado){
                            Snackbar.make(
                                view,
                                "Cadastro realizado com sucesso",
                                Snackbar.LENGTH_SHORT
                            ).show()
                            controlador.popBackStack()
                        } else {
                            val mensagemErro = recurso.erro ?: "Ocorreu uma falha no cadastro"
                            Snackbar.make(
                                view,
                                mensagemErro,
                                Snackbar.LENGTH_SHORT
                            ).show()
                        }

                    }
                })
            }
        }
    }

}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabHostFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentTabHostBinding
import com.google.android.material.tabs.TabLayoutMediator

// See doc: https://developer.android.com/training/animation/vp2-migration
// See doc: https://developer.android.com/topic/libraries/architecture/livedata
class TabHostFragment : Fragment(R.layout.fragment_tab_host) {

    private lateinit var binding: FragmentTabHostBinding
    private val viewModel: TabViewModel by viewModels()

    // Outra maneira de definir o view model
    // private lateinit var viewModel: TabViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        binding = FragmentTabHostBinding.bind(view)

        // outra maneira de inicializar o view model
        // viewModel = ViewModelProvider(this).get(TabViewModel::class.java)

        // setup tabs
        val tabLayout = binding.tabLayout
        val titles = arrayOf(R.string.tab_label1, R.string.tab_label2, R.string.tab_label3)
        val pager = binding.pager
        pager.adapter = TabPagerAdapter2(titles.size, this)

        TabLayoutMediator(tabLayout, pager) { tab, position ->
            tab.text = getString(titles[position])
        }.attach()

//        Old School way before ViewPager2
//        tabLayout.tabGravity = TabLayout.GRAVITY_FILL
//        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label1))
//        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label2))
//        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label3))
//
//
//        pager.adapter = TabPagerAdapter(tabLayout.tabCount, viewModel, childFragmentManager)
//        pager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabLayout))
//        tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
//            override fun onTabSelected(tab: TabLayout.Tab?) {
//               tab?.let { pager.currentItem = it.position }
//            }
//            override fun onTabUnselected(tab: TabLayout.Tab?) = Unit
//            override fun onTabReselected(tab: TabLayout.Tab?) = Unit
//        })
//        tabLayout.setupWithViewPager(pager)
    }

    fun getTabViewModel(): TabViewModel = viewModel
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/MainFragment.kt
package br.com.programadordeelite.gdc

import android.os.Bundle
import android.view.View
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.codelab.util.toast
import br.com.programadordeelite.gdc.databinding.FragmentMainBinding

/** Main Menu Study Guide */
class MainFragment : androidx.fragment.app.Fragment(R.layout.fragment_main) {

    private lateinit var binding: FragmentMainBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onViewCreated(view, savedInstanceState)

        // +-------------------------------------------------------------------------------------+
        // | Orientação do app: Portrait(em pé) or Landscape(deitado) or Unspecified (os dois)   |
        // +-------------------------------------------------------------------------------------+
        // if you not define it in the manifest, you could also do it that way programmatically
        //requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

        binding = FragmentMainBinding.bind(view)
        binding.codelabToastSnake.setOnClickListener { navTo(R.id.toastSnakeFragment) }
        binding.codelabNotification.setOnClickListener { navTo(R.id.notificationFragment) }
        binding.codelabWorkManager.setOnClickListener { navTo(R.id.selectImageFragment) }
        binding.codelabMaterialComponents.setOnClickListener { navTo(R.id.materialComponentsFragment) }
        binding.codelabInteractiveUi.setOnClickListener { navTo(R.id.interactiveUiFragment) }
        binding.codelabActivitiesIntents.setOnClickListener { navTo(R.id.sendFragment) }
        binding.codelabRecyclerviewWithPaging.setOnClickListener{ navTo(R.id.recyclerViewPagingFragment) }
        binding.codelabAppSettings.setOnClickListener{ navTo(R.id.appSettingsFragment) }
        binding.codelabRecyclerview.setOnClickListener { navTo(R.id.recyclerViewFragment) }
        binding.codelabAccessibility.setOnClickListener { navTo(R.id.accessibilityFragment) }
        binding.codelabCreateCustomView.setOnClickListener { navTo(R.id.customViewFragment) }
        binding.codelabUserNavigationTab.setOnClickListener { navTo(R.id.tabHostFragment) }
        binding.codelabUserNavigationDrawer.setOnClickListener { navTo(R.id.drawerFragment) }
        binding.codelabMenuPickers.setOnClickListener { navTo(R.id.menuFragment) }
        binding.codelabThemesTouches.setOnClickListener { navTo(R.id.themeFragment) }
        binding.codelabThemesTouchesBaterry.setOnClickListener { navTo(R.id.batteryFragment) }

        binding.codelabRoomWithView.setOnClickListener { navTo(R.id.wordFragment) }

        binding.codelabCustomTheme.setOnClickListener { toast(getString(R.string.duplicated_dynamic, "Day / Night")) }
        binding.codelabDrawableStyleThemes.setOnClickListener { toast(getString(R.string.duplicated_dynamic, "Day / Night")) }
        binding.codelabRoomLivedataViewmodel.setOnClickListener { toast(getString(R.string.duplicated)) }
        binding.codelabRepository.setOnClickListener { toast(getString(R.string.duplicated)) }
        binding.codelabSharedPreferences.setOnClickListener { navTo(R.id.sharedPrefFragment) }
        binding.codelabAnimPulseExplode.setOnClickListener { navTo(R.id.pulseExplodeFragment) }
        binding.codelabViewmodelViewmodelfactory.setOnClickListener { navTo(R.id.titleFragment) }
        binding.codelabAndroidStudioDebugger.setOnClickListener { navTo(R.id.calcFragment) }
        binding.codelabAddLogStatements.setOnClickListener { toast(getString(R.string.duplicated_dynamic, "Debugger")) }
        // +-----------------------------------------------------------------+
        // | Codelab: Navegação entre activities (no fragments for show case) |
        // +-----------------------------------------------------------------+
        binding.codelabUserNavigation.setOnClickListener { navTo(R.id.showTabsActivity) }

        // +-----------------------------------------------------------------+
        // | Espresso Cheat Sheet (spike muito bom para quando for testar)   |
        // +-----------------------------------------------------------------+
        // https://android.github.io/android-test/downloads/espresso-cheat-sheet-2.1.0.pdf
        // Melhores práticas de teste >> https://developer.android.com/training/testing

        binding.codelabUnitTests.setOnClickListener { toast("Veja >> Pacote: test") }
        binding.codelabTestingJunitMockito.setOnClickListener { toast("Veja >> Pacote: androidTest") }
        binding.codelabEspressoUiTesting.setOnClickListener { toast("Veja >> Pacote: AndroidTest") }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/roomwithview/WordFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import br.com.programadordeelite.gdc.MainApplication
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview.NewWordFragment.Companion.BUNDLE_KEY_WORD
import br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview.NewWordFragment.Companion.BUNDLE_REQUEST_KEY
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.databinding.FragmentWordBinding

// +-----------------------------------------------------------------+
// | TELA QUE EXIBIRA AS PALAVRAS SALVAS EM NOSSO BANCO DE DADOS     |
// +-----------------------------------------------------------------+
class WordFragment : Fragment(R.layout.fragment_word) {

    private lateinit var binding: FragmentWordBinding

    // OBTER VIEW MODEL ATRAVÉS DE EXTENCÕES DE KOTLIN
    private val wordViewModel: WordViewModel by viewModels {
        // FACTORY CRIA NOSSO MODELO INJETANDO O REPOSITÓRIO QUE CRIAMOS
        WordViewModelFactory((requireActivity().application as MainApplication).repository)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentWordBinding.bind(view)

        val adapter = WordListAdapter()
        binding.recyclerview.adapter = adapter

        // PODE SER DEFINIDO NO XML TAMBEM SE PREFERIR, MAS QUERIA TE MOSTAR MAIS UMA FORMA DE FAZER
        binding.recyclerview.layoutManager = LinearLayoutManager(requireContext())

        binding.fab.setOnClickListener { navTo(R.id.newWordFragment) }

        wordViewModel.allWords.observe(requireActivity(), { words ->
            // Atualize a cópia em cache das palavras no adaptador.
            words?.let { adapter.submitList(it) }
        })

        // DEFINIR O QUE SERA TETORNADO COMO PARAMETRO, QUANDO ESTA TELA FOR FECHADA
        setFragmentResultListener(BUNDLE_REQUEST_KEY) { _, bundle ->
            val result = bundle.getString(BUNDLE_KEY_WORD, "vazio")
            wordViewModel.insert(Word(result))
        }
    }

}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/materialcomponents/ProductGridFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.materialcomponents

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentProductGridBinding

class ProductGridFragment : Fragment(R.layout.fragment_product_grid) {

    private lateinit var binding: FragmentProductGridBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
}<file_sep>/white-label-firebase-tutorial-master/app/src/main/java/br/com/douglasmotta/whitelabeltutorial/config/di/ConfigModule.kt
package br.com.douglasmotta.whitelabeltutorial.config.di

import br.com.douglasmotta.whitelabeltutorial.config.Config
import br.com.douglasmotta.whitelabeltutorial.config.ConfigImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent

@Module
@InstallIn(ViewModelComponent::class)
interface ConfigModule {

    @Binds
    fun bindConfig(config: ConfigImpl): Config
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/workmanager/BlurWorker.kt
package br.com.programadordeelite.gdc.codelab.core.workmanager

import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.ImageDecoder
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import androidx.annotation.RequiresApi
import androidx.work.Worker
import androidx.work.WorkerParameters
import br.com.programadordeelite.gdc.R
import timber.log.Timber

// worker que vai aplicar o blur
class BlurWorker(private val ctx: Context, params: WorkerParameters) : Worker(ctx, params) {
    @RequiresApi(Build.VERSION_CODES.P)
    override fun doWork(): Result {
        val appContext = applicationContext
        makeStatusNotification("Blurring image", appContext)
        return try {
            val resourceUri = inputData.getString(KEY_IMAGE_URI)
            val pic = MediaStore.Images.Media.getBitmap(ctx.contentResolver, Uri.parse(resourceUri))
            val output = blurBitmap(pic, appContext)
            // Write bitmap to a temp file
            val outputUri = writeBitmapToFile(appContext, output)
            makeStatusNotification("Output is $outputUri", appContext)
            Result.success()
        } catch (throwable: Throwable) {
            Timber.e(throwable, "Error applying blur")
            Result.failure()
        }
    }
}<file_sep>/aad-main/app/build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

// ATENCAO, NAO FUNCIONA, POR ISSO, JOGA EXCECAO:
// Class 'ActionGameToScore' is not abstract and does not implement abstract member public abstract val actionId: Int defined in androidx.navigation.NavDirections
//apply plugin: 'androidx.navigation.safeargs.kotlin' // Codelabs -> ViewModel and ViewModelFactory

// POR ISSO OPTEI POR ESSA SOLUCAO, ATE ELES ENTREGAREM UM FIX
apply plugin: 'androidx.navigation.safeargs' // Codelabs -> ViewModel and ViewModelFactory



// +-----------------------------------------------------------------+
// | Annotation processor for Room                                   |
// +-----------------------------------------------------------------+
apply plugin: 'kotlin-kapt'


android {
    compileSdkVersion 31
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "br.com.programadordeelite.gdc"
        minSdkVersion 23
        targetSdkVersion 31
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // +-----------------------------------------------------------------+
        // | Workmanager                                                     |
        // +-----------------------------------------------------------------+
        renderscriptTargetApi 11
        renderscriptSupportModeEnabled true
        vectorDrawables {
            useSupportLibrary true
        }
        // The following argument makes the Android Test Orchestrator run its
        // "pm clear" command after each test invocation. This command ensures
        // that the app's state is completely cleared between tests.
        testInstrumentationRunnerArguments clearPackageData: 'true'
    }

    signingConfigs {
        release {
            storeFile file("release-key.keystore")
            storePassword '<PASSWORD>'
            keyAlias 'alias'
            keyPassword '<PASSWORD>'
        }
    }
    // +-----------------------------------------------------------------+
    // | Build types you'll encounter in every projects (Build Variants) |
    // +-----------------------------------------------------------------+
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        // debug don't need to be specified, only if you want to change something
        debug {
            pseudoLocalesEnabled true // para exibir idiomas fakes no seu dispositivo
            minifyEnabled false // para nao compactar o código durante desenvolvimento
            debuggable true // para poder usar break points e depurar valores
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        /**
         * The `initWith` property allows you to copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.softsuit.com"]
            applicationIdSuffix ".debugStaging"
        }
    }

    // +-----------------------------------------------------------------+
    // | Java Compile Options                                            |
    // +-----------------------------------------------------------------+
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_11
        targetCompatibility JavaVersion.VERSION_11
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    // +-----------------------------------------------------------------+
    // | exclude atomic functions module from package prevent warnings   |
    // +-----------------------------------------------------------------+
    packagingOptions {
        exclude 'META-INF/atomicfu.kotlin_module'
    }

    // +-----------------------------------------------------------------+
    // | Enables view binding                                            |
    // +-----------------------------------------------------------------+
    buildFeatures {
        viewBinding true
        dataBinding true
    }

    useLibrary("android.test.runner")

}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.10"
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'

    // +-----------------------------------------------------------------+
    // | Layouting                                                       |
    // +-----------------------------------------------------------------+
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'

    // +-----------------------------------------------------------------+
    // | Workmanager                                                     |
    // +-----------------------------------------------------------------+
    implementation "androidx.work:work-runtime-ktx:2.6.0-rc01"
    implementation "com.github.bumptech.glide:glide:4.10.0"
    implementation "com.jakewharton.timber:timber:4.7.1"
    implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

    // +-----------------------------------------------------------------+
    // | com.android... are old, using material instead                  |
    // +-----------------------------------------------------------------+
    // implementation "com.android.support:design:26.1.0"

    // +-----------------------------------------------------------------+
    // | TabExperience - UPDATE                                          |
    // +-----------------------------------------------------------------+
    implementation "androidx.viewpager2:viewpager2:1.0.0"

    // +-----------------------------------------------------------------+
    // | Material Components                                             |
    // +-----------------------------------------------------------------+
    implementation 'com.google.android.material:material:1.5.0-alpha02'
    implementation 'com.android.volley:volley:1.2.0'
    implementation 'com.google.code.gson:gson:2.8.6'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.10"
    implementation 'androidx.viewpager2:viewpager2:1.0.0'
    androidTestImplementation 'androidx.test:core:1.4.0'
    androidTestImplementation 'androidx.test:runner:1.4.0'

    // +-----------------------------------------------------------------+
    // | startFragmentForResult (setFragmentResultListener)              |
    // +-----------------------------------------------------------------+
    implementation "androidx.fragment:fragment-ktx:1.3.6"

    // +-----------------------------------------------------------------+
    // | Codelab App Settings                                            |
    // +-----------------------------------------------------------------+
    implementation 'androidx.preference:preference-ktx:1.1.1'

    // +-----------------------------------------------------------------+
    // | Room with view                                                  |
    // +-----------------------------------------------------------------+
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1"
    implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1"
    implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"

    // +-----------------------------------------------------------------+
    // | Coroutines                                                      |
    // +-----------------------------------------------------------------+
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0"

    implementation "androidx.room:room-runtime:2.3.0"
    implementation "androidx.room:room-ktx:2.3.0"
    kapt "androidx.room:room-compiler:2.3.0"
    implementation "androidx.activity:activity-ktx:1.3.1"

    // +-----------------------------------------------------------------+
    // | Paging 3 Library                                                |
    // +-----------------------------------------------------------------+
    implementation("androidx.paging:paging-runtime-ktx:3.0.1")
    // alternatively - without Android dependencies for tests
    //testImplementation("androidx.paging:paging-common-ktx:3.0.0")
    // optional - RxJava2 support
    //implementation("androidx.paging:paging-rxjava2-ktx:3.0.0")
    // optional - RxJava3 support
    //implementation("androidx.paging:paging-rxjava3:3.0.0")
    // optional - Guava ListenableFuture support
    //implementation("androidx.paging:paging-guava:3.0.0")

    // +-----------------------------------------------------------------+
    // | Retrofit - Paging 3 Library                                     |
    // +-----------------------------------------------------------------+
    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
    implementation "com.squareup.retrofit2:retrofit-mock:2.9.0"
    implementation "com.squareup.okhttp3:logging-interceptor:4.9.0"

    // +-----------------------------------------------------------------+
    // | Accessibility                                                   |
    // +-----------------------------------------------------------------+
    androidTestImplementation "androidx.test.espresso:espresso-accessibility:3.4.0"
    androidTestImplementation "androidx.test.espresso:espresso-intents:3.4.0" // deprecated
    androidTestImplementation "androidx.test:core-ktx:1.4.0"        // use this instead now
    androidTestImplementation "androidx.test.ext:junit-ktx:1.1.3"   // use this instead now

    // +-----------------------------------------------------------------+
    // | Navigation                                                      |
    // +-----------------------------------------------------------------+
    def nav_version = "2.3.5"
    // Kotlin
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" //Codelabs -> ViewModel and ViewModelFactory
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version" //Codelabs -> ViewModel and ViewModelFactory
    // Feature module Support
    implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
    // Jetpack Compose Integration
    implementation "androidx.navigation:navigation-compose:2.4.0-alpha07"

    // +-----------------------------------------------------------------+
    // | Testing deps                                                    |
    // +-----------------------------------------------------------------+
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation "androidx.room:room-testing:2.3.0"
    androidTestImplementation "androidx.arch.core:core-testing:2.1.0"
    androidTestImplementation ("androidx.test.espresso:espresso-core:3.4.0", {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    androidTestImplementation "androidx.test.ext:junit:1.1.3"

    // Testing Navigation
    androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/sharedprefs/SharedPrefFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.sharedprefs

import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
import android.os.Bundle
import android.view.View
import androidx.annotation.ColorRes
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentSharedPrefBinding

class SharedPrefFragment : Fragment(R.layout.fragment_shared_pref) {

    companion object {
        const val COUNT_KEY = "COUNT_KEY"
        const val COLOR_KEY = "COLOR_KEY"
        const val SHARED_PREFS = "com.softsuit.codelab.datamanagement.sharedprefs"
    }

    private var mCount = 0
    @ColorRes private var mColor = R.color.black_text_color
    private val mPreferences: SharedPreferences by lazy { requireActivity().getSharedPreferences(SHARED_PREFS, MODE_PRIVATE) }

    private lateinit var binding: FragmentSharedPrefBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentSharedPrefBinding.bind(view)

        mPreferences.getInt(COUNT_KEY, 0).let { mCount = it }
        mPreferences.getInt(COLOR_KEY, 0).let { mColor = it }

        if (mCount != 0) binding.countText.text = String.format("%s", mCount)
        if (mColor != 0) binding.countText.setTextColor(getColorFromResourceId(mColor))

        binding.reset.setOnClickListener { reset() }
        binding.blackButton.setOnClickListener {
            mColor = R.color.design_default_color_on_secondary
            updateUi(R.color.design_default_color_on_secondary)
        }

        binding.greenButton.setOnClickListener {
            mColor = R.color.design_default_color_secondary
            updateUi(R.color.design_default_color_secondary)
        }

        binding.blueButton.setOnClickListener {
            mColor = R.color.titleColor
            updateUi(R.color.titleColor)
        }

        binding.redButton.setOnClickListener {
            mColor = R.color.design_default_color_error
            updateUi(R.color.design_default_color_error)
        }
        binding.count.setOnClickListener {
            binding.countText.text = (++mCount).toString()
        }
    }

    private fun updateUi(@ColorRes colorId: Int) {
        binding.countText.setTextColor(getColorFromResourceId(colorId))
    }

    override fun onPause() {
        super.onPause()
        // NA HORA DO "APERREIO" DA PROVA, DA UM SWITCH PRA CÁ, LEMBRA E VOLTA! :)
        mPreferences.let {
            val editor = it.edit()
            editor.putInt(COUNT_KEY, mCount)
            editor.putInt(COLOR_KEY, mColor)
            editor.apply()
        }
    }

    private fun reset() {
        mCount = 0
        binding.countText.text = String.format("%s", mCount)

        mColor = android.R.color.white
        binding.countText.setBackgroundColor(getColorFromResourceId(mColor))

        // NA HORA DO "APERREIO" DA PROVA, DA UM SWITCH PRA CÁ, LEMBRA E VOLTA! :)
        mPreferences.let {
            val editor = it.edit()
            editor.clear()
            editor.apply()
        }
    }

    private fun getColorFromResourceId(@ColorRes colorId: Int) : Int {
        return if(colorId != 0) requireContext().getColor(colorId) else R.color.black_text_color
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/menu/OrderFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.menu

import android.os.Bundle
import android.view.ContextMenu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.snake
import br.com.programadordeelite.gdc.codelab.util.toast
import br.com.programadordeelite.gdc.databinding.FragmentOrderBinding

class OrderFragment : Fragment(R.layout.fragment_order) {
    private lateinit var binding: FragmentOrderBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentOrderBinding.bind(view)
        setHasOptionsMenu(true)
        registerForContextMenu(binding.title)

        binding.alertButton.setOnClickListener {
            AlertDialog
                .Builder(requireContext())
                .setTitle("Alerta")
                .setMessage("Olá!")
                .setPositiveButton("OK") { _, _ -> toast("Pressed OK") }
                .setNegativeButton("Cancel") { _, _ -> snake(it,"Pressed Cancel") }
                .show()
        }
        binding.datePickerButton.setOnClickListener {
            DatePickerFragment { result -> binding.selectedDateText.text = result }
                .show(childFragmentManager,"datePicker")
        }
        binding.timePickerButton.setOnClickListener {
            TimePickerFragment { result -> binding.selectedTimeText.text = result }
                .show(childFragmentManager,"timePicker")
        }
    }

    override fun onCreateContextMenu(
        menu: ContextMenu,
        v: View,
        menuInfo: ContextMenu.ContextMenuInfo?
    ) {
        super.onCreateContextMenu(menu, v, menuInfo)
        requireActivity().menuInflater.inflate(R.menu.menu_main, menu)
    }

    override fun onContextItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_status -> {
                toast(getString(R.string.action_status_message))
                return true
            }
            R.id.action_favorites -> {
                toast(getString(R.string.action_favorites_message))
                return true
            }
            R.id.action_contact -> {
                toast(getString(R.string.action_contact_message))
                return true
            }
            else -> Unit
        }
        return super.onContextItemSelected(item)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/animation/PulseExplodeFragment.kt
package br.com.programadordeelite.gdc.codelab.animation

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.codelab.util.setVisible
import br.com.programadordeelite.gdc.databinding.FragmentPulseExplodeBinding

class PulseExplodeFragment : Fragment(R.layout.fragment_pulse_explode) {
    private lateinit var binding: FragmentPulseExplodeBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentPulseExplodeBinding.bind(view)

        // ==================================================
        //  PULSE EXPLODE ANIMATION       -------------------
        // ==================================================
        startPulseAnim(binding.buttonPulseBackgroundAnimation)
        binding.buttonPulse.setOnClickListener {
            binding.buttonPulse.setVisible(false)
            startExplodeAnim(binding.buttonPulseBackgroundAnimation, ::showNextScreen)
        }
    }

    private fun showNextScreen() {
        navTo(R.id.pulseExplodeDestinationFragment_with_custom_animation)
    }

    private fun startPulseAnim(view: View) = scaleDown(view)
    private fun scaleUp(view: View) {
        view.animate()
            .scaleX(SCALE_UP_VALUE)
            .scaleY(SCALE_UP_VALUE)
            .setDuration(PULSE_DURATION)
            .withEndAction { kotlin.run { scaleDown(view) } }
    }

    private fun scaleDown(view: View) {
        view.animate()
            .scaleX(SCALE_DOWN_VALUE)
            .scaleY(SCALE_DOWN_VALUE)
            .setDuration(PULSE_DURATION)
            .withEndAction { kotlin.run { scaleUp(view) } }
    }

    private fun startExplodeAnim(view: View, endAction: () -> Unit) = shrink(view, endAction)
    private fun shrink(view: View, endAction: () -> Unit) {
        // if any previous animation is running, make sure it is canceled first
        view.animation?.let {
            it.cancel()
            it.reset()
        }
        view.animate()
            .scaleX(SHRINK_VALUE)
            .scaleY(SHRINK_VALUE)
            .setDuration(SHRINK_DURATION)
            .withEndAction { kotlin.run { explode(view, endAction) } }
    }

    private fun explode(view: View, endAction: () -> Unit) {
        view.animate()
            .scaleX(EXPLODE_VALUE)
            .scaleY(EXPLODE_VALUE)
            .setDuration(EXPLODE_DURATION)
            .withEndAction { kotlin.run { endAction() } }
    }

    companion object AnimProps {
        private const val PULSE_DURATION = 1500L
        private const val SHRINK_DURATION = 600L
        private const val EXPLODE_DURATION = 300L
        private const val SCALE_DOWN_VALUE = 0.9f
        private const val SCALE_UP_VALUE = 1f
        private const val SHRINK_VALUE = 0.3f
        private const val EXPLODE_VALUE = 4f
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/util/SharedPrefExt.kt
package br.com.programadordeelite.gdc.codelab.util

import android.content.Context
import androidx.annotation.StyleRes

const val GLOBAL_SHARED_PREFS = "br.com.programadordeelite.global.sharedprefs"
const val GLOBAL_APP_STYLE = "GLOBAL_APP_STYLE"

fun Context.putStyleIntSharedPref(key:String, @StyleRes value:Int){
    val sharedPref = getSharedPreferences(GLOBAL_SHARED_PREFS, Context.MODE_PRIVATE)
    sharedPref?.edit()?.putInt(key, value)?.apply()
}

fun Context.putStringSharedPref(key:String, value:String){
    val sharedPref = getSharedPreferences(GLOBAL_SHARED_PREFS, Context.MODE_PRIVATE)
    sharedPref?.edit()?.putString(key, value)?.apply()
}

fun Context.putBooleanSharedPref(key:String, value:Boolean){
    val sharedPref = getSharedPreferences(GLOBAL_SHARED_PREFS, Context.MODE_PRIVATE)
    sharedPref?.edit()?.putBoolean(key, value)?.apply()
}

fun Context.getIntSharedPref(key:String): Int{
    val sharedPref = getSharedPreferences(GLOBAL_SHARED_PREFS, Context.MODE_PRIVATE)
    return sharedPref?.getInt(key, -1) ?: -1
}

fun Context.getStringSharedPref(key:String): String{
    val sharedPref = getSharedPreferences(GLOBAL_SHARED_PREFS, Context.MODE_PRIVATE)
    return sharedPref?.getString(key, "") ?: ""
}

fun Context.getBooleanSharedPref(key:String): Boolean{
    val sharedPref = getSharedPreferences(GLOBAL_SHARED_PREFS, Context.MODE_PRIVATE)
    return sharedPref?.getBoolean(key, false) ?: false
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/appsettings/SettingsFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.appsettings

import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import br.com.programadordeelite.gdc.R


const val KEY_PREF_SIGNATURE = "signature"
const val KEY_PREF_REPLY = "reply"
const val KEY_PREF_SYNC = "sync"
const val KEY_PREF_ATTACHMENT = "attachment"

class SettingsFragment : PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.root_preferences, rootKey)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/menu/TimePickerFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.menu

import android.app.Dialog
import android.app.TimePickerDialog
import android.os.Bundle
import android.text.format.DateFormat
import android.widget.TimePicker
import androidx.fragment.app.DialogFragment
import java.util.*

class TimePickerFragment(val callback: (result: String) -> Unit) : DialogFragment(), TimePickerDialog.OnTimeSetListener {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val c: Calendar = Calendar.getInstance()
        val hour = c[Calendar.HOUR_OF_DAY]
        val minute = c[Calendar.MINUTE]

        return TimePickerDialog(requireContext(), this, hour, minute, DateFormat.is24HourFormat(activity))
    }

    override fun onTimeSet(time: TimePicker?, hour: Int, minute: Int) {
        val hourString = hour.toString()
        val minuteString = minute.toString()
        callback("$hourString : $minuteString")
    }
}<file_sep>/AppContatos/app/src/main/java/com/example/appcontatos/ContatoViewHolder.kt
package com.example.appcontatos

import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class ContatoViewHolder (view: View): RecyclerView.ViewHolder(view) {

    private val textViewNome = itemView.findViewById<TextView>(R.id.textViewNome)
    private val textViewTelefone = itemView.findViewById<TextView>(R.id.textViewTelefone)

    fun bind(item: Contato) {
        textViewNome.text = item.nome
        textViewTelefone.text = item.telefone


    }
}<file_sep>/aad-main/README.md
# Google Developer Certification 🥇 (Android Associated Certification)

🇧🇷 **Preparatório** para Certificação de desenvolvedor do Google 🏁 **EM APENAS 23 DIAS** (Android Associate Certification) - um guia passo a passo completo com vídeos no Youtube passando por todas as seções oficiais de cada codelab, POREM TUDO EM PORTUGUÊS 🇧🇷 E EM **KOTLIN!** ⚽😀

### ⚙️ **SETUP PROJETO**
| Titulo        | 📺 Youtube Link |
| :------------- |:-------------:|
| Criando o projeto e fazendo todo o setup usando navigation graph | <a href="https://youtu.be/NjhT6ZA62LQ" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/google_certification_android_associated_developer_setup_mini.png" width="100" height="56"></a> |


### 🧪 **CODELAB: CORE**
| Titulo        | 📺 Youtube Link |
| :------------- |:-------------:|
| Alertas e Mensagens com ações (toast & snake), extenções Kotlin e NavGraph    | <a href="https://youtu.be/9vfXfq1RfTo" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/google_certification_android_associated_developer_toast_and_snake_alertas_e_mensagens_mini.png" width="100" height="56"></a>|
| Como disparar notificações de push personalizadas e com ações  | <a href="https://youtu.be/iDlRsZ-hAU8" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BPASSO-A-PASSO%5D-Como-Criar-ANDROID-PUSH-NOTIFICATIONS-PERSONALIZADAS-sem-Google-Cloud-Message_mini.png" width="100" height="56"></a>|
| Como reagir a eventos do sistema (BroadCastReceiver)    | <a href="https://youtu.be/vGwr9XZ8xDY" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BPASSO-A-PASSO%5D-Broadcastreceiver-Android-Studio-Tutorial-Notifica%C3%A7%C3%B5es-Actions-Tarefas-Background_mini.png" width="100" height="56"></a>|
| Como traduzir seu aplicativo para vários idiomas | <a href="https://youtu.be/XHT5RXsp8uM" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BAPP-INTERNACIONAL%5D-Como-Criar-Um-Aplicativo-Para-Celular-Com-Suporte-A-V%C3%A1rios-Idiomas-ANDROID-STUDIO_mini.png" width="100" height="56"></a> |
| Como executar tarefas em Segundo Plano - Parte 1 | <a href="https://youtu.be/5AGWzq9JpYo" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BWORKMANAGER%5D-Como-Executar-Tarefas-(Threads)-Em-Segundo-Plano-(Background)-em-uma-Android-App-parte1_mini.png" width="100" height="56"></a> |
| Como executar tarefas em Segundo Plano - Parte 2  | <a href="https://youtu.be/MJpeoRopmgw" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BWORKMANAGER%5D-Como-Executar-Tarefas-(Threads)-Em-Segundo-Plano-(Background)-em-uma-Android-App-parte2_mini.png" width="100" height="56"></a> |


### 🧪 **CODELAB: USER INTERFACE(INTERAÇÃO COM O USUÁRIO)**
| Titulo        | 📺 Youtube Link |
| :------------- |:-------------:|
| Como criar textos, campos, botões e reagir a EVENTOS DE CLICK | <a href="https://youtu.be/qE5lZRSrgxo" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BTEXTOS-CAMPOS-BOT%C3%95ES%5D-Como-manipular-textos-campos-bot%C3%B5es-reagindo-a-eventos-de-click-android_mini.png" width="100" height="56"></a> |
| Como criar um app layout profissional em 10min | <a href="https://youtu.be/XBUbvKczRRI" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BINCR%C3%8DVEL%5D-Como-criar-um-APP-PROFISSIONAL-do-zero-em-10-minutos-no-ANDROID-STUDIO-usando-KOTLIN_mini.png" width="100" height="56"></a> |
| Como abrir uma segunda tela (Activity/Fragment) e navegar entre telas | <a href="https://youtu.be/5gqNUeNi9es" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BF%C3%81CIL%5D-Como-abrir-uma-segunda-tela-Activity-ou-Fragment-e-navegar-entre-elas-no-Android-Studio_mini.png" width="100" height="56"></a> |
| Como criar listas dinâmicas com RecyclerView | <a href="https://youtu.be/Da3PCGnIagE" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BPASSO-A-PASSO%5D-Como-Criar-listas-personalizadas-com-Recyclerview-no-Android-Studio-Tutorial_mini.png" width="100" height="56"></a> |
| Como criar listas infinitas com paginação fazendo requests na internet | <a href="https://youtu.be/lAAlxi2IH0U" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BLISTAS-INFINITAS%5D-Como-Criar-Listas-fluidas-com-Recyclerview-usando-Paging-3-Library-Android_mini.png" width="100" height="56"></a> |
| Como desenvolver aplicativos com acessibilidade - Guia completo | <a href="https://youtu.be/riAGnGv5aAs" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BAcessibilidade%5D-Como-desenvolver-aplicativos-acess%C3%ADveis-ativar-narrador-de-voz-Sistema-Android_mini.png" width="100" height="56"></a> |
| Como implementar a navegação de abas e guias usando TabLayout e ViewPager | <a href="https://youtu.be/SGazP_G4ek0" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BFACIL%5D-Como-implementar-o-Tablayout-abas-usando-Fragments-e-ViewPager-Guia-no-Android-Studio_mini.png" width="100" height="56"></a> |
| Como criar views e componentes personalizados com Custom Views | <a href="https://youtu.be/fpNEife2cYo" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BANDROID-CUSTOM-VIEW-TUTORIAL%5D-Como-criar-componentes-personalizados-no-android-usando-KOTLIN_mini.png" width="100" height="56"></a> |
| Como criar a navegação de hambuger lateral (Navigation Drawer) usando fragments | <a href="https://youtu.be/X5B8Q6q22FU" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BDO%20ZERO%5D-Como-criar-ou-implementar-o-navigation-drawer-com-fragments-no-Android-Studio-kotlin_mini.png" width="100" height="56"></a> |
| Como implementar TIME OU DATEPICKER (Data e Hora) com Fragments em KOTLIN no Android Studio | <a href="https://youtu.be/QJj3T8H8myI" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BDATA-E-HORA%5D-Como-implementar-TIME-OU-DATEPICKER-com-Fragments-em-KOTLIN-no-Android-Studio-2021_mini.png" width="100" height="56"></a> |
| Como criar ou alterar ÍCONE PADRÃO do aplicativo no Android Studio KOTLIN | <a href="https://youtu.be/JMvXUjISoFo" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BCRIANDO-%C3%8DCONES%5D-Como-criar-ou-alterar-%C3%8DCONES-PADR%C3%83O-do-app-no-Android-Studio-din%C3%A2micamente-KOTLIN_mini.png" width="100" height="56"></a> |


### 🧪 **CODELAB: DATA MANAGEMENT(ROOM E ARMAZENAMENTO DE DADOS)**
| Titulo        | 📺 Youtube Link |
| :------------- |:-------------:|
| Como usar o ViewModel com o banco de dados Room e LiveData no android studio Kotlin STUDIO | <a href="https://youtu.be/EqkqNjY7uGs" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BMVVM%5D-Como-usar-o-ViewModel-com-o-banco-de-dados-Room-e-LiveData-no-android-studio-Kotlin_mini.png" width="100" height="56"></a> |
| Como USAR SHARED PREFERENCES e PERSISTIR na MEMÓRIA? KOTLIN ANDROID  | <a href="https://youtu.be/ScctmGl47tc" target="_blank"><img src="https://github.com/treslines/aad/blob/main/app/src/main/mini/%5BSALVAR-PREFER%C3%8ANCIAS%5D-Como-USAR-SHARED-PREFERENCES-e-PERSISTIR-na-MEM%C3%93RIA-KOTLIN-ANDROID-STUDIO_mini.png" width="100" height="56"></a> |


### 🧪 **CODELAB: DEGUBBING(CORRIGINDO BUGS DO SEU APP)**
- EM ANDAMENTO


### 🧪 **CODELAB: TESTING(APRENDA A TESTAR SEU APP > INTERFACE GRÁFICA e CÓDIGO)**
- EM ANDAMENTO


### 🧪 **CODELAB: ANIMATION(ANIMAÇÕES COM KOTLIN)**
- EM ANDAMENTO
<file_sep>/AulaMvvM/app/src/main/java/com/example/aulamvvm/MainActivity.kt
package com.example.aulamvvm

import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.aulamvvm.adapters.MainAdapter
import com.example.aulamvvm.databinding.ActivityMainBinding
import com.example.aulamvvm.databinding.ResItemLiveBinding
import com.example.aulamvvm.repositories.MainRepository
import com.example.aulamvvm.rest.RetrofitService
import com.example.aulamvvm.viewmodel.main.MainViewModel
import com.example.aulamvvm.viewmodel.main.MainViewModelFactory

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    lateinit var viewModel: MainViewModel

    private val retrofitService = RetrofitService.getInstance()

    private val adapter = MainAdapter {
        openLink(it.link)

    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        viewModel = ViewModelProvider(this, MainViewModelFactory(MainRepository(retrofitService))).get(
                MainViewModel::class.java
            )

        binding.recyclerview.adapter = adapter

    }


    override fun onStart() {
        super.onStart()

        viewModel.liveList.observe(this, Observer { lives ->
            Log.i("Taina", "livelist.observe")
            adapter.setLiveList(lives)
        })

        viewModel.errorMessage.observe(this, Observer { message ->
            Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
        })
    }

    override fun onResume() {
        super.onResume()
        Log.i("Taina", "onResponse")
        viewModel.getAllLives()
    }

    private fun openLink(link: String) {

        val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
        startActivity(browserIntent)

    }


}
<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/util/FragmentExt.kt
package br.com.programadordeelite.gdc.codelab.util

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.annotation.IdRes
import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import br.com.programadordeelite.gdc.R
import com.google.android.material.snackbar.Snackbar

fun Fragment.navTo(@IdRes dest: Int) = findNavController().navigate(dest)
fun Fragment.navTo(@IdRes dest: Int, args: Bundle) = findNavController().navigate(dest, args)
fun Fragment.toast(msg: String) = Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
fun Fragment.snake(view: View, msg: String) = Snackbar.make(view, msg, Snackbar.LENGTH_SHORT).show()

fun Fragment.startActivity(clazz: Class<*>, name: String = "", args: Bundle = Bundle()){
    val intent = Intent(requireContext(), clazz).apply {
        if(!(name.isNullOrEmpty() && args.isEmpty)) {
            putExtra(name,args)
        }
    }
    requireActivity().startActivity(intent)
}

<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/drawer/DrawerFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.drawer

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentDrawerBinding

class DrawerFragment : Fragment(R.layout.fragment_drawer) {
    private lateinit var binding: FragmentDrawerBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
}<file_sep>/white-label-firebase-tutorial-master/app/src/main/java/br/com/douglasmotta/whitelabeltutorial/domain/usecase/CreateProductUseCase.kt
package br.com.douglasmotta.whitelabeltutorial.domain.usecase

import android.net.Uri
import br.com.douglasmotta.whitelabeltutorial.domain.model.Product

interface CreateProductUseCase {

    suspend operator fun invoke(description: String, price: Double, imageUri: Uri): Product
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/viewmodelfactory/TitleFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.viewmodelfactory

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentSharedPrefBinding
import br.com.programadordeelite.gdc.databinding.FragmentTitleBinding

class TitleFragment : Fragment(R.layout.fragment_title) {

    private lateinit var binding: FragmentTitleBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentTitleBinding.bind(view)

        binding.playGameButton.setOnClickListener {
            findNavController().navigate(TitleFragmentDirections.actionTitleToGame())
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabThreeFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentTabThreeBinding

class TabThreeFragment(val viewModel: TabViewModel) : Fragment(R.layout.fragment_tab_three) {

    private lateinit var binding: FragmentTabThreeBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentTabThreeBinding.bind(view)

        // Criar um observador que atualiza a UI
        val tabContentObserver = Observer<String> { newContent ->
            binding.contentTitle.text = viewModel.getCurrent(newContent)
        }

        viewModel.getContentObserver().observe(viewLifecycleOwner, tabContentObserver)

        binding.btnTabThree.setOnClickListener {
            viewModel.getContentObserver().setValue("Tab Three!")
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/util/ViewExt.kt
package br.com.programadordeelite.gdc.codelab.util

import android.view.View
import android.view.animation.Animation

fun View.startAnimation(anim: Animation, onEnd: () -> Unit) {
    anim.setAnimationListener(object : Animation.AnimationListener {
        override fun onAnimationEnd(anim: Animation?) = onEnd()
        override fun onAnimationRepeat(anim: Animation?) = Unit
        override fun onAnimationStart(anim: Animation?) = Unit
    })
    this.startAnimation(anim)
}

fun View.setVisible(show: Boolean) {
    if (show) this.visibility = View.VISIBLE else this.visibility = View.GONE
}<file_sep>/Firebase-Authentication-Android-aula-3/app/src/main/java/br/com/alura/aluraesporte/ui/viewmodel/CadastroUsuarioViewModel.kt
package br.com.alura.aluraesporte.ui.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import br.com.alura.aluraesporte.repository.FirebaseAuthRepository
import br.com.alura.aluraesporte.repository.Resource

class CadastroUsuarioViewModel(private val repository: FirebaseAuthRepository) : ViewModel(){

    fun cadastra(email: String, senha: String): LiveData<Resource<Boolean>> {
        return repository.cadastra(email, senha)
    }

}<file_sep>/CURSO ANDROID UDEMY/KotlinRecylcerView/app/src/main/java/com/example/kotlinrecylcerview/DataSource.kt
package com.example.kotlinrecylcerview

import com.example.kotlinrecylcerview.models.Live

class DataSource {

    companion object {

        fun createDataSet(): ArrayList<Live> {
            val list = ArrayList<Live>()

            list.add(
                Live(
                    "Live 001 da Tainá na twitch",
                    "Tainá Regina",
                    "file:///C:/Users/tainasantos/Downloads/banner%20para%20Twitch.png",
                    "https://www.twitch.tv/tainadmissivel"
                )
            )

            list.add(
                Live(
                    "Live 002 da Tainá na twitch",
                    "Tainá Regina",
                    "file:///C:/Users/tainasantos/Downloads/banner%20para%20Twitch.png",
                    "https://www.twitch.tv/tainadmissivel"
                )
            )

            list.add(
                Live(
                    "Live 003 da Tainá na twitch",
                    "Tainá Regina",
                    "file:///C:/Users/tainasantos/Downloads/banner%20para%20Twitch.png",
                    "https://www.twitch.tv/tainadmissivel"
                )
            )

            list.add(
                Live(
                    "Live 004 da Tainá na twitch",
                    "Tainá Regina",
                    "file:///C:/Users/tainasantos/Downloads/banner%20para%20Twitch.png",
                    "https://www.twitch.tv/tainadmissivel"
                )
            )

            return list
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/customview/Password.kt
package br.com.programadordeelite.gdc.codelab.userinterface.customview

import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import androidx.annotation.LayoutRes
import androidx.annotation.StyleableRes
import androidx.constraintlayout.widget.ConstraintLayout
import br.com.programadordeelite.gdc.R
import com.google.android.material.button.MaterialButton
import com.google.android.material.textfield.TextInputLayout
import kotlinx.android.synthetic.main.item_password.view.*
import kotlin.properties.Delegates

abstract class Password @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = R.style.CustomComponents_TextInputLayout,
    @LayoutRes layoutRes: Int = R.layout.item_password,
    @StyleableRes styleableRes: IntArray = R.styleable.PasswordItem
) : ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {

    private val emptyString = ""
    private val defaultMinLength = 4
    private val defaultMaxLength = 25

    var passwordForgottenButtonEnabled: Boolean by Delegates.observable(false) { _, _, new ->
        pwdButton.visibility = if (new) VISIBLE else GONE
        pwdLayout.endIconMode = if (!new) TextInputLayout.END_ICON_PASSWORD_TOGGLE else TextInputLayout.END_ICON_NONE
    }

    var passwordForgottenButtonText: String by Delegates.observable(initialValue = emptyString) { _, old, new ->
        if (old != new) pwdButton.text = new
    }

    var passwordCounterEnabled: Boolean by Delegates.observable(false) { _, _, new ->
        pwdLayout.isCounterEnabled = new
    }

    var passwordCounterMaxLength: Int by Delegates.observable(defaultMaxLength) { _, _, new ->
        pwdLayout.counterMaxLength = new
    }

    var passwordHintText: String by Delegates.observable(initialValue = resources.getString(R.string.input_password_hint_text)) { _, old, new ->
        if (old != new) pwdLayout.hint = new
    }

    var passwordErrorText: String = resources.getString(R.string.input_password_error_text_default)
    var passwordCounterMinLength: Int = defaultMinLength

    var passwordSuccessTextEnabled: Boolean by Delegates.observable(false) { _, _, new ->
        pwdLayout.isHelperTextEnabled = new
    }

    var passwordSuccessText: String by Delegates.observable(resources.getString(R.string.input_helper_text_blank_space)) { _, old, new ->
        if (pwdEdit.text != null && pwdEdit.text.toString().length > passwordCounterMinLength) {
            if (old != new) pwdLayout.helperText = new
        }
    }

    val passwordForgottenButton: MaterialButton?
        get() = pwdButton

    init {
        inflate(context, layoutRes, this)
        context.theme.obtainStyledAttributes(
            attrs,
            styleableRes,
            defStyleAttr,
            defStyleRes
        ).apply {
            try {
                passwordForgottenButtonText = getString(R.styleable.PasswordItem_passwordForgottenButtonText)
                    ?: emptyString
                passwordHintText = getString(R.styleable.PasswordItem_passwordHintText)
                    ?: resources.getString(R.string.input_password_hint_text)
                passwordForgottenButtonEnabled = getBoolean(R.styleable.PasswordItem_passwordForgottenButtonEnabled, false)
                passwordCounterEnabled = getBoolean(R.styleable.PasswordItem_passwordCounterEnabled, false)
                passwordCounterMaxLength = getInt(R.styleable.PasswordItem_passwordCounterMaxLength, defaultMaxLength)
                passwordCounterMinLength = getInt(R.styleable.PasswordItem_passwordCounterMinLength, defaultMinLength)
                passwordSuccessTextEnabled = getBoolean(R.styleable.PasswordItem_passwordSuccessTextEnabled, false)
                val blankSpace = resources.getString(R.string.input_helper_text_blank_space)
                val customHelperText = getString(R.styleable.PasswordItem_passwordSuccessText)
                passwordSuccessText = customHelperText ?: blankSpace
                val customErrorText = getString(R.styleable.PasswordItem_passwordErrorText)
                val defaultErrorText = resources.getString(R.string.input_password_error_text_default)
                passwordErrorText = customErrorText ?: defaultErrorText
            } finally {
                recycle()
            }
        }
        pwdEdit.setOnFocusChangeListener { _, hasFocus ->
            if (!hasFocus) {
                if (pwdEdit.text.toString().length in passwordCounterMinLength..passwordCounterMaxLength) {
                    pwdLayout.isErrorEnabled = false
                    if (passwordSuccessTextEnabled) pwdLayout.helperText = passwordSuccessText
                } else {
                    if (pwdEdit.text != null && pwdEdit.text.toString().isEmpty()) {
                        showErrorHelperText()
                    }
                }
            }
        }
        pwdEdit.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(chars: CharSequence?, start: Int, count: Int, after: Int) = Unit

            override fun onTextChanged(chars: CharSequence?, start: Int, before: Int, count: Int) = Unit

            override fun afterTextChanged(editable: Editable?) {
                val passwordLayout = pwdLayout
                val passwordForgottenButton = pwdButton
                if (editable.isNullOrEmpty()) {
                    if (passwordForgottenButton.visibility != VISIBLE) passwordForgottenButton.visibility = VISIBLE
                    if (passwordLayout.endIconMode != TextInputLayout.END_ICON_NONE) passwordLayout.endIconMode = TextInputLayout.END_ICON_NONE
                } else {
                    if (passwordForgottenButton.visibility != GONE) passwordForgottenButton.visibility = GONE
                    if (passwordLayout.endIconMode != TextInputLayout.END_ICON_PASSWORD_TOGGLE) passwordLayout.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
                    if (pwdEdit.text.toString().length in passwordCounterMinLength..passwordCounterMaxLength) {
                        passwordLayout.isErrorEnabled = false
                        if (passwordSuccessTextEnabled) passwordLayout.helperText = passwordSuccessText
                    } else {
                        showErrorHelperText()
                    }
                }
            }
        })
    }

    private fun showErrorHelperText() {
        val defaultErrorText = resources.getString(R.string.input_password_error_text_default)
        pwdLayout.error = if (passwordErrorText.isNotEmpty()) passwordErrorText else defaultErrorText
        pwdLayout.isErrorEnabled = true
        pwdLayout.helperText = emptyString
    }
}<file_sep>/white-label-firebase-tutorial-master/app/src/main/java/br/com/douglasmotta/whitelabeltutorial/domain/usecase/GetProductUseCaseImpl.kt
package br.com.douglasmotta.whitelabeltutorial.domain.usecase

import br.com.douglasmotta.whitelabeltutorial.data.ProductRepository
import br.com.douglasmotta.whitelabeltutorial.domain.model.Product
import javax.inject.Inject

class GetProductUseCaseImpl @Inject constructor(
    private val productRepository: ProductRepository
) : GetProductsUseCase {

    override suspend fun invoke(): List<Product> {
        return productRepository.getProducts()
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/notification/NotificationFragment.kt
package br.com.programadordeelite.gdc.codelab.core.notification

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Bundle
import android.view.View
import androidx.core.app.NotificationCompat
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import kotlinx.android.synthetic.main.fragment_notification.*

private const val NOTIFICATION_ID = 0
private const val PRIMARY_CHANNEL_ID = "primary_notification_channel"
private const val ACTION_UPDATE = "ACTION_UPDATE_NOTIFICATION"
private const val ACTION_CANCEL = "ACTION_CANCEL_NOTIFICATION"
private const val ACTION_DELETE_ALL = "ACTION_DELETED_NOTIFICATIONS"

class NotificationFragment : Fragment(R.layout.fragment_notification) {

    private lateinit var notificationManager: NotificationManager
    private val notificationReceiver = NotificationReceiver()
    private val dynamicReceiver = DynamicReceiver()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setupUiButtonListeners()
        setupUiButtonStates(enableNotify = true, enableUpdate = false, enableCancel = false)
        createNotificationChannel()
        registerNotificationReceiver()
        registerDynamicReceiver(dynamicReceiver)
    }

    private fun setupUiButtonListeners() {
        // Não estou usando o binding aqui propositalmente para vcs aprenderem mais uma coisa
        notify.setOnClickListener { sendNotification() }    // enviar notificação padrão
        update.setOnClickListener { updateNotification() }  // customizar / personalizar
        cancel.setOnClickListener { cancelNotification() }  // remover da barra de status
        // snake.setOnClickListener{ }
    }

    private fun setupUiButtonStates( // assegurar o estado inicial dos botões
        enableNotify: Boolean,
        enableUpdate: Boolean,
        enableCancel: Boolean
    ) {
        notify.isEnabled = enableNotify
        update.isEnabled = enableUpdate
        cancel.isEnabled = enableCancel
    }

    // A partir do android 8.0 (api 26) temos que definir o canal para que o usuário possa
    // eventualmente desabilitar as notificações do aplicativo através das configurações
    private fun createNotificationChannel() {
        notificationManager =
            requireActivity().getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            // Isso aqui é que aparece nas configurações do aparelho la no seu aplicativo
            val notificationChannel = NotificationChannel(
                PRIMARY_CHANNEL_ID,
                "Mascot Notification", NotificationManager.IMPORTANCE_HIGH
            )
            notificationChannel.enableVibration(true)
            notificationChannel.description = "Notification from Mascot"
            // serão exibidas se o telefone der suporte a essas coisas
            notificationChannel.enableLights(true)
            notificationChannel.lightColor = Color.RED
            // criar o canal com as propriedades definidas
            notificationManager.createNotificationChannel(notificationChannel)
        } else {
            // sua tarefinha de casa :) caso vc tenha um aparelho inferior a api 26
        }
    }

    private fun cancelNotification() {
        notificationManager.cancel(NOTIFICATION_ID)
        setupUiButtonStates(enableNotify = true, enableUpdate = false, enableCancel = false)
    }

    private fun updateNotification() {
        // personalização dinamica da notificação adicionando um icone
        val androidImage = BitmapFactory.decodeResource(resources, R.drawable.ic_notification)
        // atualizando o estilo e o titulo
        val notification = getNotificationBuilder()
            .setStyle(
                NotificationCompat.BigPictureStyle()
                    .bigPicture(androidImage)
                    .setBigContentTitle("Notificação atualizada!")
            )
        // atualizar a notificação atual
        notificationManager.notify(NOTIFICATION_ID, notification.build())
        // e habilitar o botão de cancelamento
        setupUiButtonStates(enableNotify = false, enableUpdate = false, enableCancel = true)
    }

    private fun sendNotification() {
        val builder = getNotificationBuilder()

        createNotificationAction(builder, NOTIFICATION_ID, ACTION_UPDATE, "Atualize")
        createNotificationAction(builder, NOTIFICATION_ID, ACTION_CANCEL, "Remover")

        val deleteAllAction = Intent(ACTION_DELETE_ALL) // remove com slide left/right ou lixeira
        val deletedAction = PendingIntent.getBroadcast(
            requireContext(),
            NOTIFICATION_ID,
            deleteAllAction,
            PendingIntent.FLAG_ONE_SHOT
        )
        builder.setDeleteIntent(deletedAction)

        notificationManager.notify(NOTIFICATION_ID, builder.build())
        // como neste passo aqui a notificação foi enviada, eu deshabilito o botão de enviar
        // e habilito os botões de customização e cancelamento
        setupUiButtonStates(enableNotify = false, enableUpdate = true, enableCancel = true)
    }

    private fun createNotificationAction(
        builder: NotificationCompat.Builder,
        notificationId: Int,
        actionId: String,
        actionTitle: String
    ) {
        val updateActionFilter = Intent(actionId) // for broadcast receiver
        val updateAction = PendingIntent.getBroadcast(
            requireContext(),
            notificationId,
            updateActionFilter,
            PendingIntent.FLAG_ONE_SHOT
        )
        builder.addAction(
            // mudanças nas notificação desde o Android N
            // esse icone nao aparece mais e esta presente apenas para manter compatibilidade
            // em aparelhos antigos. Em compensação se ganhou mais espaço para os titulos
            // // https://android-developers.googleblog.com/2016/06/notifications-in-android-n.html
            R.drawable.ic_android,
            actionTitle,
            updateAction
        )
    }

    private fun getNotificationBuilder(): NotificationCompat.Builder {
        val notificationIntent = Intent(requireContext(), NotificationFragment::class.java)
        val notificationPendingIntent = PendingIntent.getActivity(
            requireContext(),
            NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT
        )
        return NotificationCompat.Builder(requireContext(), PRIMARY_CHANNEL_ID)
            .setContentTitle("Você recebeu uma notificação!")
            .setContentText("Valeu, já vou me inscrever no canal!")
            .setSmallIcon(R.drawable.ic_notification_update)
            .setContentIntent(notificationPendingIntent)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setDefaults(NotificationCompat.DEFAULT_ALL)
            .setAutoCancel(false)
    }

    private fun registerNotificationReceiver() {
        val notificationActionFilters = IntentFilter()
        notificationActionFilters.addAction(ACTION_UPDATE)
        notificationActionFilters.addAction(ACTION_DELETE_ALL)
        notificationActionFilters.addAction(ACTION_CANCEL)
        requireActivity().registerReceiver(notificationReceiver, notificationActionFilters)
    }

    // for broadcast receiver
    override fun onDestroy() {
        requireActivity().unregisterReceiver(notificationReceiver)
        super.onDestroy()
    }

    inner class NotificationReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            // Update the notification
            when (intent.action) {
                ACTION_UPDATE -> updateNotification()
                ACTION_CANCEL -> {
                    notificationManager.cancel(NOTIFICATION_ID)
                    setupUiButtonStates(
                        enableNotify = true,
                        enableUpdate = false,
                        enableCancel = false
                    )
                }
                ACTION_DELETE_ALL -> setupUiButtonStates(
                    enableNotify = true,
                    enableUpdate = false,
                    enableCancel = false
                )
            }
        }
    }

    // API level 26 a maioria dos broadcastreceiver sao declarados dinamicamente
    private fun registerDynamicReceiver(dynamicReceiver: BroadcastReceiver) {
        IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED).also {
            requireActivity().registerReceiver(dynamicReceiver, it)
        }
    }

    private fun unregisterDynamicReceiver() {
        requireActivity().unregisterReceiver(dynamicReceiver)
    }

    override fun onStop() {
        super.onStop()
        unregisterDynamicReceiver()
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/notification/DynamicReceiver.kt
package br.com.programadordeelite.gdc.codelab.core.notification

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast

class DynamicReceiver: BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if(intent?.action == Intent.ACTION_BOOT_COMPLETED) {
            Toast.makeText(context, "app reinicio com sucesso", Toast.LENGTH_SHORT).show()
        }
        if(intent?.action == Intent.ACTION_AIRPLANE_MODE_CHANGED){
            Toast.makeText(context, "modo avião foi alterado", Toast.LENGTH_LONG).show()
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/workmanager/SelectImageFragment.kt
package br.com.programadordeelite.gdc.codelab.core.workmanager

import android.Manifest
import android.app.Activity
import android.content.ContentResolver
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.databinding.FragmentSelectImageBinding
import timber.log.Timber

class SelectImageFragment : Fragment(R.layout.fragment_select_image) {

    // ATUALIZADO
    companion object {
        private const val KEY_PERMISSIONS_GRANTED = "KEY_PERMISSIONS_GRANTED"
        private const val KEY_PERMISSIONS_REQUEST_COUNT = "KEY_PERMISSIONS_REQUEST_COUNT"
        private const val MAX_NUMBER_REQUEST_PERMISSIONS = 2
    }

    private var permissionRequestCount: Int = 0
    private lateinit var binding: FragmentSelectImageBinding
    private lateinit var launcher: ActivityResultLauncher<String>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // deve ser definido ou no onAttach ou onCreate
        launcher = registerForActivityResult(ActivityResultContracts.GetContent()){
            handleImageRequestResult(it)
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentSelectImageBinding.bind(view)

        // recuperando o ultimo estado caso o usuário rotacione o aparelho
        savedInstanceState?.let {
            permissionRequestCount = it.getInt(KEY_PERMISSIONS_REQUEST_COUNT, 0)
            userHasPermission = it.getBoolean(KEY_PERMISSIONS_GRANTED, false)
        }

        // asseguresse que o usuário tens as permissões necessárias
        requestPermissionsOnlyTwice(userHasPermission)

        // abrir o file chooser
        binding.selectImage.setOnClickListener {
            launcher.launch("image/*")
        }
    }

    private var userHasPermission = false
    private val permissions = arrayOf(
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
    )
    private fun requestPermissionsOnlyTwice(hasPermissionsAlready: Boolean) {
        if(!hasPermissionsAlready){
            if (permissionRequestCount < MAX_NUMBER_REQUEST_PERMISSIONS) {
                permissionRequestCount += 1
                // NOVA API: PRESTA A ATENCÃO AGORA
                val permissionChecker = registerForActivityResult(
                    ActivityResultContracts.RequestMultiplePermissions()
                ) { acceptedPermissions ->
                    val permissionsIdentified = acceptedPermissions.all{it.key in permissions}
                    val permissionsGrant = acceptedPermissions.all{it.value == true}
                    if(permissionsIdentified && permissionsGrant) {
                        permissionRequestCount = 0
                        userHasPermission = true
                    }
                }
                if(!userHasPermission){
                    permissionChecker.launch(permissions)
                }
            } else {
                Toast.makeText(
                    requireContext(),
                    R.string.set_permissions_in_settings,
                    Toast.LENGTH_LONG
                ).show()
                binding.selectImage.isEnabled = false
            }
        }
    }

    private fun handleImageRequestResult(uri: Uri) {
        // navegar para proxima etapa onde exibimos as opções de blur
        navTo(R.id.blurFragment, bundleOf(Pair(KEY_IMAGE_URI, uri.toString())))
        //findNavController().navigate(R.id.blurFragment, bundleOf(Pair(KEY_IMAGE_URI, uri.toString())))
    }

    // salvar estados em caso que o usuario rotacione o aparelho
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt(KEY_PERMISSIONS_REQUEST_COUNT, permissionRequestCount)
        outState.putBoolean(KEY_PERMISSIONS_GRANTED, userHasPermission)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/menu/MenuFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.menu

import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.codelab.util.toast
import br.com.programadordeelite.gdc.databinding.FragmentMenuBinding

class MenuFragment : Fragment(R.layout.fragment_menu) {
    private lateinit var binding: FragmentMenuBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.menu_main, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_order -> {
                navTo(R.id.action_menuFragment_to_orderFragment)
                return true
            }
            R.id.action_status -> {
                toast(getString(R.string.action_status_message))
                return true
            }
            R.id.action_favorites -> {
                toast(getString(R.string.action_favorites_message))
                return true
            }
            R.id.action_contact -> {
                toast(getString(R.string.action_contact_message))
                return true
            }
            else -> Unit
        }
        return super.onOptionsItemSelected(item)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/themes/ThemeFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.themes

import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentThemeBinding

class ThemeFragment : Fragment(R.layout.fragment_theme) {

    private var scoreTeam1 = 0
    private var scoreTeam2 = 0
    private val stateScore1 = "Team 1 Score"
    private val stateScore2 = "Team 2 Score"

    private lateinit var binding: FragmentThemeBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onViewCreated(view, savedInstanceState)
        binding = FragmentThemeBinding.bind(view)

        // possibilitar mudanças de orientações nessa tela
        requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

        setHasOptionsMenu(true) // importante para que o menu seja exibido

        // recuperar valores em rotacões ou quando o tema recriar o app
        if (savedInstanceState != null) {
            scoreTeam1 = savedInstanceState.getInt(stateScore1)
            scoreTeam2 =savedInstanceState.getInt(stateScore2)
            binding.score1.text = scoreTeam1.toString()
            binding.score2.text = scoreTeam2.toString()
        }

        binding.decreaseButtonTeam1.setOnClickListener {
            binding.score1.text = (--scoreTeam1).toString()
        }
        binding.decreaseButtonTeam2.setOnClickListener {
            binding.score2.text = (--scoreTeam2).toString()
        }
        binding.increaseButtonTeam1.setOnClickListener {
            binding.score1.text = (++scoreTeam1).toString()
        }
        binding.increaseButtonTeam2.setOnClickListener {
            binding.score2.text = (++scoreTeam2).toString()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        outState.putInt(stateScore1, scoreTeam1)
        outState.putInt(stateScore2, scoreTeam2)
        super.onSaveInstanceState(outState)
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        requireActivity().menuInflater.inflate(R.menu.theme_menu, menu)
        val nightMode = AppCompatDelegate.getDefaultNightMode()
        if (nightMode == AppCompatDelegate.MODE_NIGHT_YES) {
            menu.findItem(R.id.night_mode).setTitle(R.string.day_mode)
        } else {
            menu.findItem(R.id.night_mode).setTitle(R.string.night_mode)
        }
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.night_mode) {
            val nightMode = AppCompatDelegate.getDefaultNightMode()
            if (nightMode == AppCompatDelegate.MODE_NIGHT_YES) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
            }
            // Recreate the activity for the theme change to take effect.
            requireActivity().recreate()
        }
        return true
    }

    override fun onDetach() {
        super.onDetach()
        // assegurar que tudo esta como era antes
        requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/customview/PasswordItem.kt
package br.com.programadordeelite.gdc.codelab.userinterface.customview

import android.content.Context
import android.util.AttributeSet
import br.com.programadordeelite.gdc.R

open class PasswordItem @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = R.style.CustomComponents_TextInputLayout
) : Password(context, attrs, defStyleAttr, defStyleRes)<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabViewModel.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class TabViewModel : ViewModel() {

    var currentTabContent: String = "Current on Tab One!"
    var currentTab: String = "Tab One!"
    private val currentTabObserver: MutableLiveData<String> = MutableLiveData()

    // lógica é programada no view model a view geralmente so é atualizada
    // separando responsabilidades CoC (cerparation of concern)
    fun getCurrent(tab: String): String {
        if (currentTab != tab) {
            currentTabContent = "Toque anterior: $currentTab\nÚltimo toque: $tab"
            currentTab = tab
        }
        return currentTabContent
    }

    fun getContentObserver(): MutableLiveData<String> = currentTabObserver
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/MainApplication.kt
package br.com.programadordeelite.gdc

import android.app.Application
import br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview.WordRepository
import br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview.WordRoomDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import timber.log.Timber

class MainApplication : Application() {

    // NÃO HÁ NECESSIDADE DE CANCELAR ESTE ESCOPO, POIS ELE SERÁ DESTRUÍDO COM O PROCESSO
    private val applicationScope = CoroutineScope(SupervisorJob())

    // CRIACAO DO NOSSO BANCO DE DADOS LAZY (SO SERA INSTANCIADO QUANDO FOR USADO PELA PRIMEIRA VEZ)
    private val database by lazy { WordRoomDatabase.getDatabase(this@MainApplication, applicationScope) }

    // DEFINICAO DO NOSSO REPOSITORIO A NIVEL DE APLICACAO PARA FICAR DISPONIVEL EM TODO LUGAR
    val repository by lazy { WordRepository(database.wordDao()) }

    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree()) // Timber é o "novo" Logger recomendado pela google
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/GithubService.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging


import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query

const val IN_QUALIFIER = "in:name,description"

/**
 * Github API communication setup via Retrofit.
 */
interface GithubService {

    /**
     * Get repos ordered by stars.
     */
    @GET("search/repositories?sort=stars")
    suspend fun searchRepos(
        @Query("q") query: String,
        @Query("page") page: Int,
        @Query("per_page") itemsPerPage: Int
    ): RepoSearchResponse

    companion object {
        private const val BASE_URL = "https://api.github.com/"

        // factory method para criar serviços
        fun create(): GithubService {
            val logger = HttpLoggingInterceptor()
            logger.level = Level.BASIC

            val client = OkHttpClient.Builder()
                .addInterceptor(logger)
                .build()
            return Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(GithubService::class.java)
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabOneFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentTabOneBinding

class TabOneFragment (val viewModel: TabViewModel): Fragment(R.layout.fragment_tab_one) {

    private lateinit var binding: FragmentTabOneBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentTabOneBinding.bind(view)

        // Criar um observador que atualiza a UI
        val tabContentObserver = Observer<String> { newContent ->
            binding.contentTitle.text = viewModel.getCurrent(newContent)
        }

        viewModel.getContentObserver().observe(viewLifecycleOwner, tabContentObserver)

        binding.btnTabOne.setOnClickListener {
            viewModel.getContentObserver().setValue("Tab one!")
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/Repo.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import com.google.gson.annotations.SerializedName

/**
 * Immutable model class for a Github repo that holds all the information about a repository.
 * Objects of this type are received from the Github API, therefore all the fields are annotated
 * with the serialized name.
 * This class also defines the Room repos table, where the repo [id] is the primary key.
 */
data class Repo(
    @field:SerializedName("id") val id: Long,
    @field:SerializedName("name") val name: String,
    @field:SerializedName("full_name") val fullName: String,
    @field:SerializedName("description") val description: String?,
    @field:SerializedName("html_url") val url: String,
    @field:SerializedName("stargazers_count") val stars: Int,
    @field:SerializedName("forks_count") val forks: Int,
    @field:SerializedName("language") val language: String?
)<file_sep>/AppContatos/app/src/main/java/com/example/appcontatos/ContatoAdapter.kt
package com.example.appcontatos

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

class ContatoAdapter: RecyclerView.Adapter<ContatoViewHolder>() {

    private var items = listOf<Contato>()


    fun upDateItems(newItems: List<Contato>) {
        items = newItems
        notifyDataSetChanged()
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContatoViewHolder {

        val view = LayoutInflater
            .from(parent.context)
            .inflate(R.layout.item_contato, parent, false)
        return ContatoViewHolder(view)


    }
    override fun getItemCount() : Int = items.size

    override fun onBindViewHolder(holder: ContatoViewHolder, position: Int) {
        holder.bind(items[position])

    }




}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/viewmodelfactory/ScoreFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.viewmodelfactory

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentScoreBinding

class ScoreFragment : Fragment(R.layout.fragment_score) {
    private lateinit var binding: FragmentScoreBinding

    private lateinit var viewModel: ScoreViewModel
    private lateinit var viewModelFactory: ScoreViewModelFactory


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentScoreBinding.bind(view)

        // obtem argumentos passados pela action de gameFragment
        viewModelFactory = ScoreViewModelFactory(ScoreFragmentArgs.fromBundle(requireArguments()).score)
        // com o factory obtenho o view model
        viewModel = ViewModelProvider(this, viewModelFactory).get(ScoreViewModel::class.java)

        binding.scoreText.text = viewModel.score.toString()
    }
}<file_sep>/AppContatos/app/src/main/java/com/example/appcontatos/CadastroActivity.kt
package com.example.appcontatos

import android.app.DatePickerDialog
import android.app.ProgressDialog.show
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.textfield.TextInputEditText
import java.text.SimpleDateFormat
import java.util.*


private val DatePickerDialog.maxDate: Unit
    get() {
        TODO("Not yet implemented")
    }

class CadastroActivity : AppCompatActivity() {

    //    private lateinit var binding: CadastroActivity
    private lateinit var dataCompra: TextInputEditText


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_cadastro)


        dataCompra = findViewById(R.id.dataCompra)

        val calendario = Calendar.getInstance()

//        val picker = DatePickerDialog.OnDateSetListener { view, ano, mes, dia ->
//            calendario.set(Calendar.YEAR, ano)
//            calendario.set(Calendar.MONDAY, mes)
//            calendario.set(Calendar.DAY_OF_MONTH, dia)
//            calendario.add(Calendar.DATE, -7)
//            calendario.add(Calendar.DATE, 10)
//            upDate(calendario)
//
//        }
//
//        dataCompra.setOnClickListener {
//
//            DatePickerDialog(
//                this,
//                picker,
//                calendario.get(Calendar.YEAR),
//                calendario.get(Calendar.MONTH),
//                calendario.get(Calendar.DAY_OF_MONTH)
//
//            ).show()
//
//
//        }
//    }

//        fun upDate(calendario: Calendar) {
//            val formato = "dd-mm-yyyy"
//            val sdf = SimpleDateFormat(formato, Locale.US)
//            dataCompra.setText(sdf.format(calendario.time))
//        }
//    }
//setText(sdf.format.(calendario.time))

///////////////////////////////////


        dataCompra.setOnClickListener {

            val todayDate: Calendar = Calendar.getInstance()
            val ano: Int = todayDate.get(Calendar.YEAR)
            val mes: Int = todayDate.get(Calendar.MONTH)
            val dia: Int = todayDate.get(Calendar.DAY_OF_MONTH)


            val dateDialog = DatePickerDialog(this, this, ano, mes, dia)

            todayDate.add(Calendar.DATE, -7)
            dateDialog.datePicker.minDate = todayDate.timeInMillis

            todayDate.add(Calendar.DATE, 10)
            dateDialog.datePicker.maxDate = todayDate.timeInMillis

            dateDialog.datePicker.maxDate = Date().time


            dateDialog.show()


        }
    }

    private fun DatePickerDialog(
        cadastroActivity: CadastroActivity,
        cadastroActivity1: CadastroActivity,
        ano: Int,
        mes: Int,
        dia: Int
    ): DatePickerDialog {
        TODO("Not yet implemented")
    }
}




//
//    }
//        dataCompra.setOnClickListener {
//            val calendario = Calendar.getInstance()
//
//            val datePicker = DatePickerDialog.OnDateSetListener { view, ano, mes, dia ->
//
//                calendario.set(Calendar.YEAR, ano)
//                calendario.set(Calendar.MONDAY, mes)
//                calendario.set(Calendar.DAY_OF_MONTH, dia)
//                calendario.add(Calendar.DATE, -7)
//                calendario.add(Calendar.DATE, 10)
//
//
//
//
//
//                dateDialog.datePicker.minDate = todayDate.timeInMillis
//
//                todayDate.add(Calendar.DATE, 10)
//                dateDialog.datePicker.maxDate = todayDate.timeInMillis
//
//                dateDialog.show()
//
//
//
//
//                private fun DatePickerDialog(
//                    cadastroActivity: CadastroActivity,
//                    ano: Int,
//                    mes: Int,
//                    dia: Int
//                ): DatePickerDialog {
//
//                }



<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/roomwithview/RoomRepositoryViewModel.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview

import android.content.Context
import androidx.annotation.WorkerThread
import androidx.lifecycle.*
import androidx.room.*
import androidx.sqlite.db.SupportSQLiteDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch

// +----------------------------------------------------------------------+
// | >>> 1° <<< ENTITY: DEFINICÃO DA NOSSA TABELA POR MEIO DE ANOTACÕES   |
// +----------------------------------------------------------------------+
@Entity(tableName = "word_table")
class Word(@PrimaryKey @ColumnInfo(name = "word") val word: String)

// +-------------------------------------------------------------------------------------+
// | >>> 2° <<< DAO: DATA ACCESS OBJECT - OBJETO QUE REALIZA OPERACÕES NO BANCO DE DADOS |
// |            ESPECIFICA O QUE PODEREMOS ALTERA NA NOSSA TABELA E FACILITA O USO       |
// +-------------------------------------------------------------------------------------+
@Dao
interface WordDao {
    @Query("SELECT * FROM word_table ORDER BY word ASC")
    fun getAlphabetizedWords(): Flow<List<Word>> // Note: Estamos usando flow (o video de Paging Lib 3 explica)
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(word: Word)

    @Query("DELETE FROM word_table") // que mágica é essa?
    suspend fun deleteAll()
}

// +-----------------------------------------------------------------------------------------------+
// | >>> 3° <<< REPOSITORY: MEDIADOR DE ACESSO A DADOS LOCAIS OU REMOTO CASO EXISTAM VÁRIAS FONTES |
// +-----------------------------------------------------------------------------------------------+
// Declare o DAO como uma propriedade privada no construtor. Passe apenas o DAO
// em vez do banco de dados inteiro, porque você só precisamos acessar o DAO
class WordRepository(private val wordDao: WordDao) {

    // Room executa todas as consultas em um thread separado.
    // Flow observado notificará o observador quando os dados forem alterados.
    val allWords: Flow<List<Word>> = wordDao.getAlphabetizedWords()

    // Por padrão, o Room executa consultas suspensas fora do thread principal, portanto,
    // não precisamos implementar qualquer outra coisa para garantir que não estamos fazendo
    // um trabalho de banco de dados de longa duração fora da Thread principal.
    @Suppress("RedundantSuspendModifier")
    @WorkerThread
    suspend fun insert(word: Word) {
        wordDao.insert(word)
    }
}

// +-----------------------------------------------------------------------+
// | >>> 4° <<< ROOM - NOSSO BANCO DE DADOS COM AS DEFINICÕES DE TABELAS   |
// +-----------------------------------------------------------------------+
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
abstract class WordRoomDatabase : RoomDatabase() {

    abstract fun wordDao(): WordDao

    // +----------------------------------------------------------------------------------+
    // | CALLBACK - SERA USADA PARA INICIALIZAR O NOSSO BANCO DE DADOS NA HORA DA CRIACÃO |
    // +----------------------------------------------------------------------------------+
    private class WordDatabaseCallback(private val scope: CoroutineScope) : RoomDatabase.Callback() {

        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            INSTANCE?.let { database ->
                scope.launch {
                    populateDatabase(database.wordDao()) // SO PARA EXEMPLIFICAR COMO PRE-POPULAR UM BANCO DE DADOS
                }
            }
        }

        suspend fun populateDatabase(wordDao: WordDao) {
            // APAGAMOS TUDO QUE ESTEJA NO BANCO PRIMEIRO (NÃO FACA ISSO EM PRODUCÃO)
            wordDao.deleteAll()

            // ADICIONAMOS ALGUNS VALORES ALEATÓRIOS PARA TER ALGO PARA EXIBIR
            wordDao.insert(Word("Olá, não se esqueça de se inscrever no canal"))
            wordDao.insert(Word("Vai me agradecer na hora da prova! :)"))
        }
    }

    companion object {
        // +------------------------------------------------------------------------------------+
        // | SINGLETON - PREVINE QUE MULTIPLAS INSTANCIAS DO BANCO SEJAM ABERTAS AO MESMO TEMPO |
        // |             PADRÃO DE PROJETO QUE SO DEIXA UMA INSTANCIA DO MESMO OBJETO EXISTIR   |
        // +------------------------------------------------------------------------------------+
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context, scope: CoroutineScope): WordRoomDatabase {
            // SE O BANCO JA EXISTIR, RETORNE DIRETO, DO CONTRÁRIO CRIE O BANCO
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    WordRoomDatabase::class.java,
                    "word_database" // NOME DO NOSSO BANCO DE DADOS
                ).addCallback(WordDatabaseCallback(scope)).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

// +---------------------------------------------------------------------------+
// | >>> 5° <<< VIEW MODEL: ATUALIZAR DADOS E RETEM A LÓGICA DA UI EM QUESTÃO  |
// +---------------------------------------------------------------------------+
class WordViewModel(private val repository: WordRepository) : ViewModel() {

    // Usar LiveData e armazenar em cache o que allWords retorna tem vários benefícios:
    // - Podemos colocar um observador nos dados (em vez de pesquisar as alterações) e apenas
    //   atualizar a IU quando os dados realmente mudam.
    // - O repositório é completamente separado da IU por meio do ViewModel.
    val allWords: LiveData<List<Word>> = repository.allWords.asLiveData()

    /** Lançamento de uma nova co-rotina para inserir os dados de forma não bloqueadora */
    fun insert(word: Word) = viewModelScope.launch {
        repository.insert(word)
    }
}

// +---------------------------------------------------------+
// | >>> 6° <<< MODEL FACTORY: CRIADOR DE OBJETOS COMPLEXOS  |
// +---------------------------------------------------------+
class WordViewModelFactory(private val repository: WordRepository) : ViewModelProvider.Factory {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(WordViewModel::class.java)) return WordViewModel(repository) as T
        throw IllegalArgumentException("MODELO DESCONHECIDO")
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/viewmodelfactory/GameFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.viewmodelfactory

import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.codelab.util.toast
import br.com.programadordeelite.gdc.databinding.FragmentGameBinding

class GameFragment : Fragment(R.layout.fragment_game) {
    private lateinit var binding: FragmentGameBinding

    private lateinit var viewModel: GameViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentGameBinding.bind(view)
        Log.i("GameFragment", "Called ViewModelProvider.get")
        viewModel = ViewModelProvider(this).get(GameViewModel::class.java)
        binding.correctButton.setOnClickListener { onCorrect() }
        binding.skipButton.setOnClickListener { onSkip() }
        binding.endGameButton.setOnClickListener { onEndGame() }

        updateScoreText()
        updateWordText()

    }

    /** Methods for button click handlers **/

    private fun onSkip() {
        viewModel.onSkip()
        updateWordText()
        updateScoreText()
    }
    private fun onCorrect() {
        viewModel.onCorrect()
        updateScoreText()
        updateWordText()
    }

    /** Methods for updating the UI **/
    private fun updateWordText() {
        binding.wordText.text = viewModel.word
    }

    private fun updateScoreText() {
        binding.scoreText.text = viewModel.score.toString()
    }

    private fun onEndGame() {
        gameFinished()
    }

    /**
     * Called when the game is finished
     * ATENCAO: Para entender melhor directions, veja isso aqui:
     * https://developer.android.com/guide/navigation/navigation-navigate#groovy
     */
    private fun gameFinished() {
        toast("Game has just finished")
        // bacana para passar actions embora tbm possivel por bundles
        val action = GameFragmentDirections.actionGameToScore()
        action.score = viewModel.score
        // outra maneira de navegar
        NavHostFragment.findNavController(this).navigate(action)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabTwoFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentTabTwoBinding

class TabTwoFragment(val viewModel: TabViewModel) : Fragment(R.layout.fragment_tab_two) {

    private lateinit var binding: FragmentTabTwoBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentTabTwoBinding.bind(view)

        // Criar um observador que atualiza a UI
        val tabContentObserver = Observer<String> { newContent ->
            binding.contentTitle.text = viewModel.getCurrent(newContent)
        }

        viewModel.getContentObserver().observe(viewLifecycleOwner, tabContentObserver)

        binding.btnTabTwo.setOnClickListener {
            viewModel.getContentObserver().setValue("Tab Two!")
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/materialcomponents/MaterialComponentsFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.materialcomponents

import android.os.Bundle
import android.text.Editable
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.databinding.FragmentMaterialComponentsBinding
import kotlinx.android.synthetic.main.fragment_material_components.*

class MaterialComponentsFragment : Fragment(R.layout.fragment_material_components) {

    private lateinit var binding: FragmentMaterialComponentsBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentMaterialComponentsBinding.bind(view) // inicializa o binding

        binding.nextButton.setOnClickListener {
            if (!isPasswordValid(password_edit_text.text.toString())) {
                password_text_input.error = getString(R.string.shr_error_password)
            } else {
                password_text_input.error = null
                navTo(R.id.productGridFragment)
            }
        }

        // Clear the error once more than 8 characters are typed.
        binding.passwordEditText.setOnKeyListener { _, _, _ ->
            if (isPasswordValid(password_edit_text.text.toString())) {
                password_text_input.error = null
            }
            false
        }

        binding.cancelButton.setOnClickListener {
            binding.passwordEditText.setText("")
            binding.username.setText("")
        }

    }
    private fun isPasswordValid(text: String): Boolean = text.length >= 8
}<file_sep>/CURSO ANDROID UDEMY/KotlinRecylcerView/app/src/main/java/com/example/kotlinrecylcerview/MainActivity.kt
package com.example.kotlinrecylcerview

import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private lateinit var liveAdapter: LiveAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initRecyclerView()
        addDataSource()

    }

    private fun addDataSource() {
        val dataSource = DataSource.createDataSet()
        this.liveAdapter.setDataSet(dataSource)

    }


    private fun initRecyclerView() {
        this.liveAdapter = LiveAdapter{ live ->
        openLink(live.link)

    }
        recyclerview.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)
            adapter = liveAdapter
        }

        //OU PODE FAZER DA FORMA ABAIXO

//        recyclerview.layoutManager = LinearLayoutManager(this)
//        recyclerview.adapter = this.liveAdapter

    }


    //Pega link do canal para abrir no click
    private fun openLink(url : String) {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
        startActivity(intent)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/animation/PulseExplodeDestinationFragment.kt
package br.com.programadordeelite.gdc.codelab.animation

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentPulseExplodeDestinationBinding

class PulseExplodeDestinationFragment : Fragment(R.layout.fragment_pulse_explode_destination) {

    private lateinit var binding: FragmentPulseExplodeDestinationBinding
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentPulseExplodeDestinationBinding.bind(view)
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/GithubRepository.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import kotlinx.coroutines.flow.Flow
import timber.log.Timber

/**
 * Repository class that works with local and remote data sources.
 */
class GithubRepository(private val service: GithubService) {

    /**
     * Search repositories whose names match the query, exposed as a stream of data that will emit
     * every time we get more data from the network.
     */
    fun getSearchResultStream(query: String): Flow<PagingData<Repo>> {
        Timber.d("GithubRepository New query: $query")
        return Pager(
            config = PagingConfig(pageSize = NETWORK_PAGE_SIZE, enablePlaceholders = false),
            pagingSourceFactory = { GithubPagingSource(service, query) }
        ).flow
    }

    companion object {
        const val NETWORK_PAGE_SIZE = 50
    }
}<file_sep>/white-label-firebase-tutorial-master/app/src/main/java/br/com/douglasmotta/whitelabeltutorial/ui/products/ProductsViewModel.kt
package br.com.douglasmotta.whitelabeltutorial.ui.products

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import br.com.douglasmotta.whitelabeltutorial.config.Config
import br.com.douglasmotta.whitelabeltutorial.domain.model.Product
import br.com.douglasmotta.whitelabeltutorial.domain.usecase.GetProductsUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class ProductsViewModel @Inject constructor(
    private val getProductsUseCase: GetProductsUseCase,
    config: Config
) : ViewModel() {

    private val _productsData = MutableLiveData<List<Product>>()
    val productsData: LiveData<List<Product>> = _productsData

    private val _addButtonVisibilityData = MutableLiveData(config.addButtonVisibility)
    val addButtonVisibilityData: LiveData<Int> = _addButtonVisibilityData

    fun getProducts() = viewModelScope.launch {
        try {
            val products = getProductsUseCase()
            _productsData.value = products
        } catch (e: Exception) {
            Log.d("ProductsViewModel", e.toString())
        }
    }
}<file_sep>/AtmConsultoria/app/src/main/java/com/example/atmconsultoria/DetalheClienteActivity.kt
package com.example.atmconsultoria

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_detalhe_cliente.*
import kotlinx.android.synthetic.main.activity_main.*

class DetalheClienteActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_detalhe_cliente)


        buton_voltar.setOnClickListener {
            val intent = Intent (this, MainActivity::class.java)
            startActivity(intent)
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/activityintents/ReplyFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.activityintents

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.oldschool.UserNavigationActivity
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.codelab.util.startActivity
import br.com.programadordeelite.gdc.databinding.FragmentReplyBinding

class ReplyFragment : Fragment(R.layout.fragment_reply) {
    companion object {
        const val SEND = "SEND"
    }
    private lateinit var binding: FragmentReplyBinding
    private var sent: String? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentReplyBinding.bind(view)

        binding.buttonReply.setOnClickListener {
            val args = Bundle()
            args.putString(SendFragment.REPLY,binding.inputReply.text.toString())
            navTo(R.id.action_replyFragment_to_sendFragment, args)

            //startActivity(UserNavigationActivity::class.java)
        }

        // obtem a mensagem enviada pelo fragment
        arguments?.let {
            sent = it.getString(SEND, null)
        }

        // exibe a mensagem obtida
        sent?.let {
            binding.textMessage.text = it
        }
    }

    override fun onResume() {
        super.onResume()
        (activity as AppCompatActivity).supportActionBar?.hide()
    }

    override fun onStop() {
        super.onStop()
        (activity as AppCompatActivity).supportActionBar?.show()
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/RecyclerViewPagingFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider

import androidx.lifecycle.lifecycleScope
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentRecyclerViewPagingBinding

import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
import androidx.paging.LoadState
import androidx.recyclerview.widget.DividerItemDecoration
import kotlinx.coroutines.flow.collect


// https://developer.android.com/topic/libraries/architecture/paging/v3-overview
// https://developer.android.com/codelabs/android-paging?index=..%2F..%2Findex#4
class RecyclerViewPagingFragment : Fragment(R.layout.fragment_recycler_view_paging) {

    private lateinit var binding: FragmentRecyclerViewPagingBinding
    private lateinit var viewModel: SearchRepositoriesViewModel
    private val adapter = ReposAdapter()

    private var searchJob: Job? = null

    private fun search(query: String) {
        // Make sure we cancel the previous job before creating a new one
        searchJob?.cancel()
        searchJob = lifecycleScope.launch {
            viewModel.searchRepo(query).collect {
                adapter.submitData(it)
            }
        }
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentRecyclerViewPagingBinding.bind(view)

        // get the view model
        viewModel = ViewModelProvider(this, Injection.provideViewModelFactory()).get(SearchRepositoriesViewModel::class.java)

        // add dividers between RecyclerView's row items
        val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL)
        binding.list.addItemDecoration(decoration)

        initAdapter()
        val query = savedInstanceState?.getString(LAST_SEARCH_QUERY) ?: DEFAULT_QUERY
        search(query)
        initSearch(query)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putString(LAST_SEARCH_QUERY, binding.searchRepo.text.trim().toString())
    }

    private fun initAdapter() {
        binding.list.adapter = adapter
    }

    private fun initSearch(query: String) {
        binding.searchRepo.setText(query)

        binding.searchRepo.setOnEditorActionListener { _, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_GO) {
                updateRepoListFromInput()
                true
            } else {
                false
            }
        }
        binding.searchRepo.setOnKeyListener { _, keyCode, event ->
            if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
                updateRepoListFromInput()
                true
            } else {
                false
            }
        }

        // Scroll to top when the list is refreshed from network.
        lifecycleScope.launch {
            adapter.loadStateFlow
                // Only emit when REFRESH LoadState for RemoteMediator changes.
                .distinctUntilChangedBy { it.refresh }
                // Only react to cases where Remote REFRESH completes i.e., NotLoading.
                .filter { it.refresh is LoadState.NotLoading }
                .collect { binding.list.scrollToPosition(0) }
        }
    }

    private fun updateRepoListFromInput() {
        binding.searchRepo.text.trim().let {
            if (it.isNotEmpty()) {
                search(it.toString())
            }
        }
    }

    private fun showEmptyList(show: Boolean) {
        if (show) {
            binding.emptyList.visibility = View.VISIBLE
            binding.list.visibility = View.GONE
        } else {
            binding.emptyList.visibility = View.GONE
            binding.list.visibility = View.VISIBLE
        }
    }


    companion object {
        private const val LAST_SEARCH_QUERY: String = "last_search_query"
        private const val DEFAULT_QUERY = "Android"
    }
}



<file_sep>/AppContatos/app/src/main/java/com/example/appcontatos/Contato.kt
package com.example.appcontatos

data class Contato (
    val nome: String,
    val telefone: String,
    val email: String,
    val id: Int? = null
        )

fun teste() {

    val c = Contato("nome", "telefone", "email")
    val c2 = c.copy("nome2")


}

<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/ViewModelFactory.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider

/**
 * Factory for ViewModels
 */
class ViewModelFactory(private val repository: GithubRepository) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(SearchRepositoriesViewModel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return SearchRepositoriesViewModel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/SearchRepositoriesViewModel.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import kotlinx.coroutines.flow.Flow

/**
 * ViewModel for the [SearchRepositoriesActivity] screen.
 * The ViewModel works with the [GithubRepository] to get the data.
 */
class SearchRepositoriesViewModel(private val repository: GithubRepository) : ViewModel() {

    private var currentQueryValue: String? = null
    private var currentSearchResult: Flow<PagingData<Repo>>? = null

    fun searchRepo(queryString: String): Flow<PagingData<Repo>> {

        // se ja existir algo no cache para a mesma busca, apenas retorne o resultado
        val lastResult = currentSearchResult
        if (queryString == currentQueryValue && lastResult != null)  return lastResult

        currentQueryValue = queryString
        val newResult: Flow<PagingData<Repo>> = repository.getSearchResultStream(queryString).cachedIn(viewModelScope)
        currentSearchResult = newResult // cache/salve na memory
        return newResult
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/Injection.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import androidx.lifecycle.ViewModelProvider

/**
 * Class that handles object creation.
 * Like this, objects can be passed as parameters in the constructors and then replaced for
 * testing, where needed.
 */
object Injection {

    /**
     * Creates an instance of [GithubRepository] based on the [GithubService] and a
     * [GithubLocalCache]
     */
    private fun provideGithubRepository(): GithubRepository {
        return GithubRepository(GithubService.create())
    }

    /**
     * Provides the [ViewModelProvider.Factory] that is then used to get a reference to
     * [ViewModel] objects.
     */
    fun provideViewModelFactory(): ViewModelProvider.Factory {
        return ViewModelFactory(provideGithubRepository())
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/toast/ToastSnakeFragment.kt
package br.com.programadordeelite.gdc.codelab.core.toast

import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.toast
import br.com.programadordeelite.gdc.databinding.FragmentToastSnakeBinding
import com.google.android.material.snackbar.Snackbar

class ToastSnakeFragment : Fragment(R.layout.fragment_toast_snake) {

    private lateinit var binding: FragmentToastSnakeBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED

        binding = FragmentToastSnakeBinding.bind(view)

        binding.toast.setOnClickListener {
            val msg = "Minha mensagem para você!"
            Toast
                .makeText(requireContext(), msg, Toast.LENGTH_SHORT)
                .show()
        }

        // Material design guideline:
        // https://material.io/archive/guidelines/components/snackbars-toasts.html#snackbars-toasts-usage
        binding.snake.setOnClickListener {
            Snackbar.make(view, "Oi Snake", Snackbar.LENGTH_SHORT).show()
        }

        binding.snakeAction.setOnClickListener {
            Snackbar
                .make(view, "Snake with Action", Snackbar.LENGTH_SHORT)
                .setAction(R.string.ok) { toast("I am a snake!") }
                .show()
        }
    }
}
<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/paging/ReposAdapter.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview.paging

import android.view.ViewGroup
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil

/**
 * Adapter for the list of repositories.
 */
class ReposAdapter : PagingDataAdapter<Repo, RepoViewHolder>(REPO_COMPARATOR) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RepoViewHolder {
        return RepoViewHolder.create(parent)
    }

    override fun onBindViewHolder(holder: RepoViewHolder, position: Int) {
        val repoItem = getItem(position)
        if (repoItem != null) {
            holder.bind(repoItem)
        }
    }

    companion object {
        private val REPO_COMPARATOR = object : DiffUtil.ItemCallback<Repo>() {
            override fun areItemsTheSame(oldItem: Repo, newItem: Repo): Boolean =
                oldItem.fullName == newItem.fullName

            override fun areContentsTheSame(oldItem: Repo, newItem: Repo): Boolean =
                oldItem == newItem
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/debugging/calc/Calculator.kt
package br.com.programadordeelite.gdc.codelab.debugging.calc

class Calculator {
    enum class Operator { ADD, SUB, DIV, MUL }

    fun add(firstOperand: Double, secondOperand: Double): Double = firstOperand + secondOperand

    fun sub(firstOperand: Double, secondOperand: Double): Double = firstOperand - secondOperand

    fun div(firstOperand: Double, secondOperand: Double): Double = firstOperand / secondOperand

    fun mul(firstOperand: Double, secondOperand: Double): Double = firstOperand * secondOperand
}<file_sep>/aad-main/app/src/androidTest/java/com/progradordeelite/gdc/EspressoUiTest.kt
package com.progradordeelite.gdc

import android.content.Intent
import androidx.test.core.app.launchActivity
import androidx.test.espresso.Espresso
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import br.com.programadordeelite.gdc.MainActivity
import br.com.programadordeelite.gdc.R
//import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResult
//import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultBaseUtils.matchesCheckNames
//import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
//import org.hamcrest.Matchers.`is`
//import org.hamcrest.Matchers.allOf
import org.junit.Assert.*
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class EspressoUiTest {

    init {
        val configurator = AccessibilityChecks.enable()
//        configurator.setThrowExceptionFor(AccessibilityCheckResult.AccessibilityCheckResultType.ERROR)
//        configurator.setRunChecksFromRootView(true)
//        configurator.setSuppressingResultMatcher(
//            allOf(
//                matchesCheckNames(`is`("TextContrastViewCheck")),
//                matchesViews(withId(R.id.btnAdd))
//            )
//        )
    }

    @Test
    fun testIncrement(){
        // launch desired activity - OLD WAY NO CASO DE VC ENCONTRAR ISSO POR AI
        IntentsTestRule(MainActivity::class.java).launchActivity(Intent())
        Espresso.onView(withId(R.id.codelab_accessibility)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.btnAdd)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Apertou 1 vez!")))
    }

    @Test
    fun testIncrementNew(){
        val scenario = launchActivity<MainActivity>()
        Espresso.onView(withId(R.id.codelab_accessibility)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.btnAdd)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Apertou 1 vez!")))
        Espresso.onView(withId(R.id.btnAdd)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Apertou 2 vez!")))
        scenario.onActivity { activity ->
            println("se quiser chamar algum metodo da activity, faz aqui!") // do some stuff with the Activity
            // exemplo: activity.onBackPressed()
        }
        scenario.close() // hightly recomended otherwise activity will remain open
    }

    @get:Rule
    val rule = activityScenarioRule<MainActivity>()

    @Test
    fun testIncrementNewWithRuleEvenBetterSinceItClosesScenarioAutomatically(){
        val scenario = rule.scenario
        scenario.onActivity { activity ->
            println("se quiser chamar algum metodo da activity, faz aqui!") // do some stuff with the Activity
            // exemplo: activity.onBackPressed()
        }
        Espresso.onView(withId(R.id.codelab_accessibility)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Aperta lá no botão!")))
        Espresso.onView(withId(R.id.btnAdd)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Apertou 1 vez!")))
        Espresso.onView(withId(R.id.btnAdd)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Apertou 2 vez!")))
        Espresso.onView(withId(R.id.btnAdd)).perform(ViewActions.click())
        Espresso.onView(withId(R.id.textAdd)).check(matches(withText("Apertou 3 vez!")))
    }

    @Test
    fun useAppContext() {
        // Context of the app under test.
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("br.com.programadordeelite.gdc", appContext.packageName)
    }
}<file_sep>/AulaMvvM/app/src/main/java/com/example/aulamvvm/repositories/MainRepository.kt
package com.example.aulamvvm.repositories

import com.example.aulamvvm.rest.RetrofitService

class MainRepository constructor(private val retrofitService: RetrofitService) {

    fun getAllLives() = retrofitService.getAllLives()
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/activityintents/SendFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.activityintents

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.databinding.FragmentSendBinding

class SendFragment : Fragment(R.layout.fragment_send) {

    companion object {
        const val REPLY = "REPLY"
    }

    private lateinit var binding: FragmentSendBinding
    private var reply: String? = null

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentSendBinding.bind(view)

        binding.buttonSend.setOnClickListener {
            val args = Bundle()
            args.putString(ReplyFragment.SEND,binding.inputSend.text.toString())
            navTo(R.id.action_sendFragment_to_replyFragment, args)
        }

        // obtem a mensagem enviada pelo fragment
        arguments?.let {
            reply = it.getString(REPLY, null)
        }

        // exibe a mensagem obtida
        reply?.let {
            binding.textMessage.text = it
        }
    }

    override fun onResume() {
        super.onResume()
        (activity as AppCompatActivity).supportActionBar?.hide()
    }

    override fun onStop() {
        super.onStop()
        (activity as AppCompatActivity).supportActionBar?.show()
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/themes/BatteryFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.themes

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentBatteryBinding

class BatteryFragment : Fragment(R.layout.fragment_battery) {
    private lateinit var binding: FragmentBatteryBinding

    private var imageLevel = 0

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentBatteryBinding.bind(view)

        binding.minusButton.setOnClickListener {
            --imageLevel
            if (imageLevel < 0) imageLevel = 0
            // alterar ícones dinâmicamente SUPER SIMPLES
            // exibir score de um jogo, quantidade ou barra de vidas
            // trocar îcones dependendo da estação do ano etc.
            binding.batteryLevelImage.setImageLevel(imageLevel)
        }

        binding.plusButton.setOnClickListener {
            ++imageLevel
            if (imageLevel > 3) imageLevel = 3
            binding.batteryLevelImage.setImageLevel(imageLevel)
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/roomwithview/NewWordFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.roomwithview

import android.os.Bundle
import android.text.TextUtils
import android.view.View
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentNewWordBinding

// +-----------------------------------------------------------------+
// | TELA QUE CADASTRARÁ NOVAS PALAVRAS NO NOSSO BANCO DE DADOS      |
// +-----------------------------------------------------------------+
class NewWordFragment : Fragment(R.layout.fragment_new_word) {
    private lateinit var binding: FragmentNewWordBinding

    companion object {
        const val BUNDLE_KEY_WORD = "word"
        const val BUNDLE_REQUEST_KEY = "requestKey"
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding = FragmentNewWordBinding.bind(view)

        binding.buttonSave.setOnClickListener {
            // BOM SABER QUE EXISTE ESSA CLASSE UTILITÁRIA PARA MANIPULAR OU VALIDAR STRINGS
            if (TextUtils.isEmpty(binding.editWord.text)) {
                parentFragmentManager.setFragmentResult(BUNDLE_REQUEST_KEY, bundleOf(BUNDLE_KEY_WORD to "vazio"))
            } else {
                val word = binding.editWord.text.toString()
                parentFragmentManager.setFragmentResult(BUNDLE_REQUEST_KEY, bundleOf(BUNDLE_KEY_WORD to word))
            }
            // NAVEGA PARA A TELA ANTERIOR - FUNCÃO ANALOGICA AO BOTÃO DE BACK
            findNavController().popBackStack()
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/recyclerview/RecyclerViewFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.recyclerview

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AnimationUtils
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.startAnimation
import br.com.programadordeelite.gdc.databinding.FragmentRecyclerViewBinding

class RecyclerViewFragment : Fragment(R.layout.fragment_recycler_view) {

    private lateinit var binding: FragmentRecyclerViewBinding

    // 0 Defina seu modelo
    private var words = mutableListOf("Ricardo", "Julia", "Pedro", "Alfred")

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentRecyclerViewBinding.bind(view)

        // +-----------------------------------------------------------------+
        // | Cool explosion animation                                        |
        // +-----------------------------------------------------------------+
        val anim = AnimationUtils.loadAnimation(requireContext(), R.anim.circle_explosion_anim).apply {
            duration = 700
            interpolator = AccelerateDecelerateInterpolator()
        }

        binding = FragmentRecyclerViewBinding.bind(view)
        // 3 atribua o adapter ao seu recyclerView
        binding.wordRecycler.adapter = WordListAdapter(requireActivity(), words)
        binding.addWordButton.setOnClickListener {
            binding.root.setBackgroundColor(0) // make sure this is set to re-trigger the anim again
            words.add("+ New word " + words.size)
            (binding.wordRecycler.adapter as WordListAdapter).notifyItemChanged(words.size)
            binding.wordRecycler.smoothScrollToPosition(words.size)
            // +-----------------------------------------------------------------+
            // | Cool explosion animation                                        |
            // +-----------------------------------------------------------------+
            binding.animCircle.isVisible = true
            binding.animCircle.startAnimation(anim) {
                // onEnd call back - do what ever you want here...
                // example: change the background color
                binding.root.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.colorPrimary))
            }
        }
    }

    // 1 Crie seu viewAdapter
    class WordListAdapter(context: Context, val words: MutableList<String>) : RecyclerView.Adapter<WordListAdapter.WordViewHolder>() {

        private val inflater: LayoutInflater = LayoutInflater.from(context)

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WordViewHolder {
            val item = inflater.inflate(R.layout.wordlist_item, parent, false)
            return WordViewHolder(item, this)
        }

        // Aqui é onde acontece a "adaptação" do modelo para o layout .xml
        override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
            holder.wordItemView.text = words[position]
        }

        override fun getItemCount(): Int {
            return words.size
        }

//        // 2 Defina um viewHolder e implemente o onclick de cada item
        inner class WordViewHolder(item: View, private val adapter: WordListAdapter) : RecyclerView.ViewHolder(item), View.OnClickListener {

            val wordItemView: TextView = item.findViewById(R.id.word)

            init {
                wordItemView.setOnClickListener(this)
            }

            override fun onClick(view: View?) {
                words[layoutPosition] = "Clicked! " + words[layoutPosition]
                adapter.notifyDataSetChanged()
            }
        }
    }
}<file_sep>/CURSO ANDROID UDEMY/KotlinRecylcerView/app/src/main/java/com/example/kotlinrecylcerview/models/Live.kt
package com.example.kotlinrecylcerview.models

import java.net.URL

data class Live(
    var title: String,
    var autor: String,
    var tumbnailURL: String,
    var link: String
)
<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/menu/DatePickerFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.menu

import android.app.DatePickerDialog
import android.app.Dialog
import android.os.Bundle
import android.widget.DatePicker
import androidx.fragment.app.DialogFragment
import java.util.*

class DatePickerFragment(val callback: (result: String) -> Unit) : DialogFragment(), DatePickerDialog.OnDateSetListener{

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val c: Calendar = Calendar.getInstance()
        val year: Int = c.get(Calendar.YEAR)
        val month: Int = c.get(Calendar.MONTH)
        val day: Int = c.get(Calendar.DAY_OF_MONTH)
        return DatePickerDialog(requireContext(), this, year, month, day)
    }

    override fun onDateSet(picker: DatePicker?, year: Int, month: Int, day: Int) {
        val monthString = (month + 1).toString()
        val dayString = day.toString()
        val yearString = year.toString()
        callback("$dayString / $monthString / $yearString")
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/usernavigation/tab/TabPagerAdapter2.kt
package br.com.programadordeelite.gdc.codelab.userinterface.usernavigation.tab

import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.adapter.FragmentViewHolder

// See doc: https://developer.android.com/training/animation/vp2-migration
class TabPagerAdapter2(private val numOfTabs: Int, val host: TabHostFragment) : FragmentStateAdapter(host) {

    override fun getItemCount(): Int = numOfTabs

    override fun createFragment(position: Int): Fragment {
        return when (position) {
            0 -> TabOneFragment(host.getTabViewModel())
            1 -> TabTwoFragment(host.getTabViewModel())
            2 -> TabThreeFragment(host.getTabViewModel())
            else -> TabOneFragment(host.getTabViewModel())
        }
    }
}<file_sep>/AulaMvvM/settings.gradle
rootProject.name = "AulaMvvM"
include ':app'
<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/customview/CustomViewFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.customview

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.snake
import br.com.programadordeelite.gdc.databinding.FragmentCustomViewBinding
import br.com.programadordeelite.gdc.databinding.FragmentReplyBinding

class CustomViewFragment : Fragment(R.layout.fragment_custom_view) {

    private lateinit var binding: FragmentCustomViewBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentCustomViewBinding.bind(view)

        binding.pwd.passwordForgottenButton?.setOnClickListener {
            snake(it, "Esqueci minha senha!")
        }

        binding.pwdOutlined.passwordForgottenButton?.setOnClickListener {
            snake(it, "Esqueci minha senha!")
        }
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/core/workmanager/BlurFragment.kt
package br.com.programadordeelite.gdc.codelab.core.workmanager

import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.work.WorkInfo
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentBlurBinding
import com.bumptech.glide.Glide

class BlurFragment : Fragment(R.layout.fragment_blur) {

    private lateinit var viewModel: BlurViewModel
    private lateinit var binding: FragmentBlurBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentBlurBinding.bind(view)

        // ATUALIZADO: Obtenho o viewmodel
        // viewModel = ViewModelProviders.of(this).get(BlurViewModel::class.java)
        viewModel = ViewModelProvider(this).get(BlurViewModel::class.java)

        // pego a uri da imagem selecionada que passei como argumento na tela anterior
        val imageUriExtra = arguments?.getString(KEY_IMAGE_URI)

        viewModel.setImageUri(imageUriExtra)
        viewModel.imageUri?.let { imageUri ->
            Glide.with(this).load(imageUri).into(binding.imageView)
        }

        binding.goButton.setOnClickListener { viewModel.applyBlur(blurLevel) }

        // Setup view output image file button
        binding.seeFileButton.setOnClickListener {
            viewModel.outputUri?.let { currentUri ->
                val actionView = Intent(Intent.ACTION_VIEW, currentUri)
                actionView.resolveActivity(requireActivity().packageManager)?.run {
                    startActivity(actionView)
                }
            }
        }

        // Hookup the Cancel button
        binding.cancelButton.setOnClickListener { viewModel.cancelWork() }

        viewModel.outputWorkInfos.observe(requireActivity(), workInfosObserver())
    }

    private fun workInfosObserver(): Observer<List<WorkInfo>> {
        return Observer { listOfWorkInfo ->

            // se nao tiver info, continuar sem fazer nada
            if (listOfWorkInfo.isNullOrEmpty()) {
                return@Observer
            }

            // We only care about the one output status.
            // Every continuation has only one worker tagged TAG_OUTPUT
            val workInfo = listOfWorkInfo[0]

            if (workInfo.state.isFinished) {
                showWorkFinished() // exibir botão

                // Normally this processing, which is not directly related to drawing views on
                // screen would be in the ViewModel. For simplicity we are keeping it here.
                val outputImageUri = workInfo.outputData.getString(KEY_IMAGE_URI)

                // se existir um arquivo com blur, exibir botão "See File"
                if (!outputImageUri.isNullOrEmpty()) {
                    viewModel.setOutputUri(outputImageUri as String)
                    binding.seeFileButton.visibility = View.VISIBLE
                }
            } else {
                showWorkInProgress() // do contrário exibir loading
            }
        }
    }

    // UI control
    private fun showWorkInProgress() {
        with(binding) {
            progressBar.visibility = View.VISIBLE
            cancelButton.visibility = View.VISIBLE
            goButton.visibility = View.GONE
            seeFileButton.visibility = View.GONE
        }
    }

    private fun showWorkFinished() {
        with(binding) {
            progressBar.visibility = View.GONE
            cancelButton.visibility = View.GONE
            goButton.visibility = View.VISIBLE
        }
    }

    private val blurLevel: Int
        get() =
            when (binding.radioBlurGroup.checkedRadioButtonId) {
                R.id.radio_blur_lv_1 -> 1
                R.id.radio_blur_lv_2 -> 2
                R.id.radio_blur_lv_3 -> 3
                else -> 1
            }
}<file_sep>/CURSO ANDROID UDEMY/KotlinRecylcerView/settings.gradle
rootProject.name = "KotlinRecylcerView"
include ':app'
<file_sep>/AppContatos/settings.gradle
rootProject.name = "AppContatos"
include ':app'
<file_sep>/AulaMvvM/app/src/main/java/com/example/aulamvvm/viewmodel/main/MainViewModel.kt
package com.example.aulamvvm.viewmodel.main

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.aulamvvm.models.Live
import com.example.aulamvvm.repositories.MainRepository
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response


class MainViewModel constructor(private val repository: MainRepository) : ViewModel() {

    val liveList = MutableLiveData<List<Live>>()
    val errorMessage = MutableLiveData<String>()


    fun getAllLives() {

        val request = repository.getAllLives()
        request.enqueue(object : Callback<List<Live>> {
            override fun onResponse(call: Call<List<Live>>, response: Response<List<Live>>) {

                //QNDO HOUVER UMA RESPOSTA
                Log.i("Taina", "onResponse")
                liveList.postValue(response.body())



            }

            override fun onFailure(call: Call<List<Live>>, t: Throwable) {
                //qndo houver uma falha
                errorMessage.postValue(t.message)

            }


        })


    }


}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/datamanagement/appsettings/AppSettingsFragment.kt
package br.com.programadordeelite.gdc.codelab.datamanagement.appsettings

import android.content.SharedPreferences
import android.os.Bundle
import android.view.*
import android.widget.Toast
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.codelab.util.navTo
import br.com.programadordeelite.gdc.codelab.util.toast
import br.com.programadordeelite.gdc.databinding.FragmentAppSettingsBinding


class AppSettingsFragment : Fragment(R.layout.fragment_app_settings) {

    lateinit var binding: FragmentAppSettingsBinding

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentAppSettingsBinding.bind(view)
        setHasOptionsMenu(true) // IMPORTANTE
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.menu_settings, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_settings -> {
                navTo(R.id.settingsFragment)
                return true
            }
            else -> Unit
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onResume() {
        super.onResume()
        val sharedPref = androidx.preference.PreferenceManager.getDefaultSharedPreferences(requireContext())
        val assinatura = sharedPref.getString(KEY_PREF_SIGNATURE, "!") ?: ""
        if(assinatura.isNotEmpty()) toast(assinatura)
        val resposta = sharedPref.getString(KEY_PREF_REPLY, "!") ?: ""
        if(resposta.isNotEmpty()) toast(resposta)
        val sincronizacao = sharedPref.getBoolean(KEY_PREF_SYNC, false)
        if(sincronizacao) toast("sincronizacao ativada")
        val anexos = sharedPref.getBoolean(KEY_PREF_ATTACHMENT, false)
        if(anexos) toast("anexos ativados")
    }
}<file_sep>/aad-main/settings.gradle
include ':app'
rootProject.name = "gdc"<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/interactiveui/InteractiveUiFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.interactiveui

import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.fragment.app.Fragment
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentInteractiveUiBinding

class InteractiveUiFragment : Fragment(R.layout.fragment_interactive_ui) {
    private lateinit var binding: FragmentInteractiveUiBinding
    private var count = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requireActivity().requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentInteractiveUiBinding.bind(view)
        binding.showCount.text = count.toString()
        binding.buttonToast.setOnClickListener { showToast() }
        binding.buttonCount.setOnClickListener { countUp(); showCounter() }
    }

    private fun showToast() = Toast.makeText(requireContext(), R.string.toast_message, Toast.LENGTH_SHORT).show()
    private fun countUp() = count++
    private fun showCounter() {
        binding.showCount.text = count.toString()
    }
}<file_sep>/aad-main/app/src/main/java/br/com/programadordeelite/gdc/codelab/userinterface/accessibility/AccessibilityFragment.kt
package br.com.programadordeelite.gdc.codelab.userinterface.accessibility

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import br.com.programadordeelite.gdc.R
import br.com.programadordeelite.gdc.databinding.FragmentAccessibilityBinding
import br.com.programadordeelite.gdc.databinding.FragmentInteractiveUiBinding

class AccessibilityFragment : Fragment(R.layout.fragment_accessibility) {
    private lateinit var binding: FragmentAccessibilityBinding
    private var count = 0

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding = FragmentAccessibilityBinding.bind(view)

        binding.btnAdd.setOnClickListener {
            count++
            binding.textAdd.text = "Apertou $count vez!"
        }
    }
}