Código dos Vídeos SQLite e RecyclerView
Android Kotlin

Código dos Vídeos SQLite e RecyclerView





Nesse tutorial sobre Código dos Vídeos SQLite e RecyclerView vou apresentar os códigos utilizados para fazer os vídeos assim fica mais fácil para implementar.

Curta os vídeos no YouTube e siga o nosso canal para assim ajudar no crescimento do site. Obrigado.

Veja então os vídeos:

Como foi feito nos vídeos vou assim postar aqui nesta página os códigos utilizados para fazer o aplicativo.

Código dos Vídeos SQLite e RecyclerView – Vídeo 1

Primeiramente vamos adicionar ao Gradle/app as bibliotecas que vamos utilizar em nosso aplicativo.

gradle/app

dependencies {
    ...
    // RecyclerView
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    // Material Design
    implementation 'com.google.android.material:material:1.2.0-alpha01'
}

Logo após ter inserido as bibliotecas que vamos utilizar em nosso aplicativo vamos criar o model que vamos utilizar.

model/Person

data class Person(
    var id: Int = 0,
    var name: String = "",
    var gender: String = "",
    var birth: String = ""
)

Agora chegou a hora de fazer o nosso SQLite para poder trabalhar com a base de dados e vai ser assim como o código a seguir.





db/DatabaseHandler

class DatabaseHandler(ctx: Context): SQLiteOpenHelper(ctx,DB_NAME,null,DB_VERSION){

    override fun onCreate(p0: SQLiteDatabase?) {
        val CREATE_TABLE = "CREATE TABLE $TABLE_NAME ($ID INTEGER PRIMARY KEY, $NAME TEXT, $GENDER TEXT, $BIRTH TEXT);"
        p0?.execSQL(CREATE_TABLE)
    }

    override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
        val DROP_TABLE = "DROP TABLE IF EXISTS $TABLE_NAME;"
        p0?.execSQL(DROP_TABLE)
        onCreate(p0)
    }

    fun addPerson(person: Person){
        val p0 = writableDatabase
        val values = ContentValues().apply {
            put(NAME, person.name)
            put(GENDER, person.gender)
            put(BIRTH, person.birth)
        }
        p0.insert(TABLE_NAME,null,values)
    }

    fun getPerson(id: Int): Person{
        val p0 = readableDatabase
        val selectQuery = "SELECT * FROM $TABLE_NAME WHERE $ID = $id;"
        val cursor = p0.rawQuery(selectQuery,null)
        cursor?.moveToFirst()
        val person = populatePerson(cursor)
        cursor.close()
        return person
    }

    fun getPersonList(): ArrayList<Person>{
        val personList = ArrayList<Person>()
        val p0 = readableDatabase
        val selectQuery = "SELECT * FROM $TABLE_NAME ORDER BY $NAME;"
        val cursor = p0.rawQuery(selectQuery, null)
        if(cursor != null){
            if(cursor.moveToFirst()){
                do{
                    val person = populatePerson(cursor)
                    personList.add(person)
                }while(cursor.moveToNext())
            }
        }
        cursor.close()
        return personList
    }

    fun updatePerson(person: Person){
        val p0 = writableDatabase
        val values = ContentValues().apply {
            put(NAME, person.name)
            put(GENDER, person.gender)
            put(BIRTH, person.birth)
        }
        p0.update(TABLE_NAME,values, "$ID=?", arrayOf(person.id.toString()))
    }

    fun delPerson(id: Int){
        val p0 = writableDatabase
        p0.delete(TABLE_NAME,"$ID=?", arrayOf(id.toString()))
    }

    fun searchPerson(str: String): ArrayList<Person>{
        val personList = ArrayList<Person>()
        val p0 = readableDatabase
        val selectQuery = "SELECT * FROM $TABLE_NAME WHERE $NAME LIKE '%$str%' OR $BIRTH LIKE '%$str%' OR $GENDER LIKE '%$str%' ORDER BY $NAME;"
        val cursor = p0.rawQuery(selectQuery, null)
        if(cursor != null){
            if(cursor.moveToFirst()){
                do{
                    val person = populatePerson(cursor)
                    personList.add(person)
                }while(cursor.moveToNext())
            }
        }
        cursor.close()
        return personList
    }

    fun populatePerson(cursor: Cursor): Person {
        val person = Person()
        person.id = cursor.getInt(cursor.getColumnIndex(ID))
        person.name = cursor.getString(cursor.getColumnIndex(NAME))
        person.gender = cursor.getString(cursor.getColumnIndex(GENDER))
        person.birth = cursor.getString(cursor.getColumnIndex(BIRTH))
        return person
    }

    companion object {
        private val DB_VERSION = 5
        private val DB_NAME = "CadUware"
        private val TABLE_NAME = "Person"
        private val ID = "Id"
        private val NAME = "Name"
        private val GENDER = "Gender"
        private val BIRTH = "Birth"
    }
}

Então vamos criar as funções que vão devolver a idade da pessoa e vão checar se a data é válida.

function/PeriodClass

class PeriodClass {
    @RequiresApi(Build.VERSION_CODES.O)
    fun period(str: String): Period? {
        val now = LocalDate.now()
        val year = str.split("/")
        var date: LocalDate? = null
        try{
            date = LocalDate.of(year[2].toInt(),year[1].toInt(),year[0].toInt())
        }catch (e: Exception){
            Log.i("Erro data: ", e.toString())
            return null
        }
        val period = Period.between(date,now)
        Log.i("Period: ", period.toString())
        return period
    }
    @RequiresApi(Build.VERSION_CODES.O)
    fun checkPeriod(str: String): Boolean {
        return period(str) != null && period(str)!!.days >=0
    }
}

Logo depois de criar as funções que vão checar as datas vamos agora criar os arquivos referentes as strings e as cores que vão ser utilizadas em nosso aplicativo dentro do diretório res.





res/values/strings

<resources>
    <string name="app_name">Sqlite Video Script</string>
    <string name="searchTitle">Procurar</string>

    <string name="addPerson">Adicionar Pessoa</string>
    <string name="editPerson">Editar Pessoa</string>

    <string name="name">Nome</string>
    <string name="gender">Gênero</string>
    <string name="birth">Nascimento</string>
    <string name="age">Idade</string>

    <string name="male">M</string>
    <string name="female">F</string>

    <string name="save">Salvar</string>
    <string name="cancel">Cancelar</string>
    <string name="delete">Deletar</string>
    <string name="errorData">Dados não correspondem.</string>
</resources>

res/values/colors

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>

    <color name="black">#000</color>
    <color name="blue">#000EC9</color>
    <color name="gray">#d3d3d3</color>
    <color name="green">#107900</color>
    <color name="pink">#F200FF</color>
    <color name="white">#FFF</color>

</resources>

Vamos criar agora um background para assim utilizar em nosso content_person.

res/drawable/background_content

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape>
        <solid android:color="@color/white"/>
        <padding android:left="5dp"
                    android:right="5dp"
                    android:bottom="5dp"
                    android:top="5dp"/>
        <corners android:radius="10dp"/>
    </shape>
</item>
</selector>

Logo após criar o background chegou a hora de criar o nosso arquivo que será replicado no RecyclerView com o nome de content_person.

res/layout/content_person

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/gray">
    <LinearLayout
        android:id="@+id/layContentPerson"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="@drawable/background_content"
        android:layout_marginTop="10dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/name"/>
        <TextView
            android:id="@+id/tvContentName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Nome de Teste"
            android:textSize="20sp"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:layout_weight="1">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/birth"/>
                <TextView
                    android:id="@+id/tvContentBirth"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="20sp"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:layout_weight="2">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/age"/>
                <TextView
                    android:id="@+id/tvContentAge"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="20sp"/>
            </LinearLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:layout_weight="2">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/gender"/>
                <TextView
                    android:id="@+id/tvContentGender"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="20sp"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/endLine"
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:orientation="vertical"
        android:visibility="gone"/>
</LinearLayout>




Código dos Vídeos SQLite e RecyclerView – Vídeo 2

No próximo passo vamos então criar o adapter que será utilizado na RecyclerView.

adapter/PersonListAdapter

class PersonListAdapter(personList: ArrayList<Person>, internal var ctx: Context, private val callback: (Int) -> Unit):
    RecyclerView.Adapter<PersonListAdapter.ViewHolder>(){

    private var personList = ArrayList<Person>()
    init {
        this.personList = personList
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(ctx).inflate(R.layout.content_person,parent, false)
        return ViewHolder(view)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val person = personList[position]

        holder.name.text = person.name
        holder.birth.text = person.birth
        holder.gender.text = person.gender
        holder.age.text = PeriodClass().period(person.birth)!!.years.toString()

        if(person.gender == ctx.getString(R.string.male)) holder.gender.setTextColor(ctx.getColor(R.color.blue))
        else holder.gender.setTextColor(ctx.getColor(R.color.pink))
        if(holder.age.text.toString().toInt() >= 18) holder.age.setTextColor(ctx.getColor(R.color.green))

        holder.lay.setOnClickListener {
            callback(person.id)
        }

        if(position == personList.size-1) holder.endLine.visibility = View.VISIBLE
    }

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

    inner class ViewHolder(view: View): RecyclerView.ViewHolder(view){
        var lay: LinearLayout = view.layContentPerson
        var name: TextView = view.tvContentName
        var birth: TextView = view.tvContentBirth
        var age: TextView = view.tvContentAge
        var gender: TextView = view.tvContentGender
        var endLine: LinearLayout = view.endLine
    }
}

Depois de ter criado o adapter vamos assim criar da seguinte forma o layout e activity que irá inserir e editar os itens.

res/layout/activity_person

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PersonActivity">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/addPerson"
        android:textSize="30sp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/layInput"/>

    <LinearLayout
        android:id="@+id/layInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_margin="16dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/layBtn">
        <com.google.android.material.textfield.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/name">
            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/etName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        </com.google.android.material.textfield.TextInputLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <com.google.android.material.textfield.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="@string/birth"
                android:layout_weight="1">
                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/etBirth"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="date"/>
            </com.google.android.material.textfield.TextInputLayout>
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:layout_weight="1">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/gender"/>
                <Spinner
                    android:id="@+id/spnGender"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/layBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent">
        <Button
            android:id="@+id/btnDel"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/delete"/>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btnSave"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/save"
                android:layout_weight="1"/>
            <Button
                android:id="@+id/btnCancel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/cancel"
                android:layout_weight="1"/>
        </LinearLayout>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>




PersonActivity

class PersonActivity : AppCompatActivity() {

    var databaseHandler = DatabaseHandler(this)
    var person: Person? = null

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_person)

        val arraySpinner = listOf<String>(getString(R.string.male),getString(R.string.female))
        val arraySpinnerAdapter = ArrayAdapter<String>(this, R.layout.support_simple_spinner_dropdown_item, arraySpinner)
        spnGender.adapter = arraySpinnerAdapter

        if(intent.getStringExtra("mode") == "Edit"){
            person = databaseHandler.getPerson(intent.getIntExtra("id",0))
            tvTitle.text = getString(R.string.editPerson)
            etName.setText(person!!.name)
            etBirth.setText(person!!.birth)
            spnGender.setSelection(arraySpinnerAdapter.getPosition(person!!.gender))
            btnDel.setOnClickListener{
                databaseHandler.delPerson(person!!.id)
                finish()
            }
        }
        else{
            btnDel.visibility = View.GONE
        }
        btnSave.setOnClickListener {
            if(testData()){
                if(intent.getStringExtra("mode") == "Edit"){
                    person = populatePerson(person)
                    databaseHandler.updatePerson(person!!)
                }
                else{
                    person = populatePerson(null)
                    databaseHandler.addPerson(person!!)
                }
                finish()
            }
            else{
                Toast.makeText(this, R.string.errorData, Toast.LENGTH_SHORT).show()
            }
        }
        btnCancel.setOnClickListener {
            finish()
        }
    }
    @RequiresApi(Build.VERSION_CODES.O)
    private fun testData(): Boolean{
        return etName.text.toString() != "" && etBirth.text.toString().length == 10 && PeriodClass().checkPeriod(etBirth.text.toString())
    }
    private fun populatePerson(p0: Person?): Person{
        val person = Person()
        if(p0 != null) person.id = p0!!.id
        person.name = etName.text.toString()
        person.birth = etBirth.text.toString()
        person.gender = spnGender.selectedItem.toString()
        return person
    }
}

Então com nosso activity que irá inserir e editar os itens de nossa lista vamos agora criar o menu superior que fará a pesquisa nos itens.

res/menu/search_view

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/searchPerson"
        android:icon="@android:drawable/ic_menu_search"
        android:title="@string/searchTitle"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="collapseActionView|ifRoom" />
</menu>




Código dos Vídeos SQLite e RecyclerView – Vídeo 3

Bom pessoal, chegamos ao final então vamos programar a última activity que será a MainActivity e seu respectivo layout.

res/layout/activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/gray"
    tools:context=".MainActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabPerson"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@drawable/ic_add"
        app:backgroundTint="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity

class MainActivity : AppCompatActivity() {

    var personList = ArrayList<Person>()
    var personListAdapter: PersonListAdapter? = null
    var linearLayoutManager: LinearLayoutManager? = null
    var databaseHandler = DatabaseHandler(this)
    var search: Boolean = false
    var searchStr: String = ""

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

        fabPerson.setOnClickListener {
            val intent = Intent(this, PersonActivity::class.java)
            startActivity(intent)
        }
    }
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.search_view, menu)
        val searchPerson = menu.findItem(R.id.searchPerson)
        val searchView = searchPerson.actionView as SearchView
        searchView.queryHint = getString(R.string.searchTitle)
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                return false
            }
            override fun onQueryTextChange(p0: String?): Boolean {
                if(p0.toString().isNotEmpty()) {
                    search = true
                    searchStr = p0!!
                }
                else{
                    search = false
                    searchStr = ""
                }
                initView()
                return false
            }
        })
        return super.onCreateOptionsMenu(menu)
    }

    override fun onResume(){
        super.onResume()
        initView()
    }
    private fun initView(){
        personList = if(!search) databaseHandler.getPersonList()
        else databaseHandler.searchPerson(searchStr)
        personListAdapter = PersonListAdapter(personList, this, this::editPerson)
        linearLayoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = linearLayoutManager
        recyclerView.adapter = personListAdapter
    }
    private fun editPerson(id: Int){
        val intent = Intent(this, PersonActivity::class.java)
        intent.putExtra("mode", "Edit")
        intent.putExtra("id", id)
        startActivity(intent)
    }
}

Curta os vídeos no YouTube e siga o nosso canal para assim ajudar no crescimento do site. Obrigado.

Enfim espero poder ter ajudado com este tutorial para você assim fazer o aplicativo de uma maneira mais fácil.





Rodrigo Leutz
Desenvolvedor Web e Android ( Kotlin e Java )
http://www.test.com/