Android Kotlin Accessing Images in Room Database with Glide library.
Many times we need to show images by using a glide library so today we will use a room database for showing images.
So let's start with the dependency part I added some dependency in the build.Gradle(:app) file.
//glide
implementation 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
implementation "androidx.activity:activity-ktx:1.3.1"
// Room components
implementation "androidx.room:room-ktx:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
androidTestImplementation "androidx.room:room-testing:2.3.0"
// Lifecycle components
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"
// Kotlin components
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1"
api "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
//cardview
implementation "androidx.cardview:cardview:1.0.0"
//RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.1'
I also added some plugins to the build.gradle(:app)
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}
Now we need to add internet permission in the Manifest file.
<uses-permission android:name="android.permission.INTERNET" />
So let's start with the design part.
activity_room.xml
<?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=".RoomActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_design"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:listitem="@layout/item_recycler" />
</androidx.constraintlayout.widget.ConstraintLayout>
For the recycler view items, I created one more XML file.
item_recycler.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="5dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true">
<!--margin start is used for starting margin in grid layout we don't need margin end-->
<LinearLayout
android:id="@+id/ll_design"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<ImageView
android:id="@+id/iv_shopping"
android:layout_width="80dp"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tv_product"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="Bags"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="$ 30" />
</LinearLayout>
</androidx.cardview.widget.CardView>
For the room database, we need to create an entity class.
User. kt
package com.example.ecommerceapplication.roomdb
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class User(
@ColumnInfo(name = "product_name")val product_name:String,
@ColumnInfo(name = "price_name")val price_name:String,
@ColumnInfo(name = "photo_product")val photo_product:String,
){
@PrimaryKey(autoGenerate = true)var uid: Int? = null
}
After creating an entity class we need to create DAO class.
UserDao.kt
package com.example.ecommerceapplication.roomdb
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAllUsers(): List<User>
@Insert
fun insert(vararg user: User)
@Delete
fun delete(user:User)
@Query("DELETE FROM user")
fun deleteAll()
}
After creating DAO class we need to create a database class.
UserDatabase.kt
package com.example.ecommerceapplication.roomdb
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1)
abstract class UserDatabase : RoomDatabase() {
abstract fun UserDao(): UserDao //all your DAO will be added here companion object {
// Here we are creating singleton so it will give same object every time instead of creating new.
companion object{
@Volatile
private var INSTANCE: UserDatabase? = null
private val DB_NAME: String="RoomDatabase" //Name of your database
fun getDatabase(context: Context): UserDatabase? {
if (INSTANCE == null) {
synchronized(UserDatabase::class.java) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(
context.getApplicationContext(),
UserDatabase::class.java, DB_NAME
).build()
}
}
}
return INSTANCE
}
}
}
Now I am creating a recycler adapter class for our recycler view.
RecyclerAdapter.kt
package com.example.ecommerceapplication.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.ecommerceapplication.R
import com.example.ecommerceapplication.roomdb.User
class RecyclerAdapter() :
RecyclerView.Adapter<RecyclerAdapter.ViewHolder>() {
var listitem = mutableListOf<User>()
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): ViewHolder {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.item_recycler, viewGroup, false)
return ViewHolder(view)
}
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
var data = listitem.get(i)
Glide.with(viewHolder.img_android.context)
.load(data.photo_product)
.into(viewHolder.img_android)
viewHolder.txt_product.text= data.product_name
viewHolder.txt_price.text= data.price_name
}
override fun getItemCount(): Int {
return listitem.size
}
fun Updatedata(listData:List<User>){
listitem.clear()
listitem.addAll(listData)
notifyDataSetChanged()
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var img_android: ImageView
var txt_price:TextView
var txt_product:TextView
init {
img_android = view.findViewById<ImageView>(R.id.iv_shopping)
txt_product = view.findViewById<TextView>(R.id.tv_product)
txt_price = view.findViewById<TextView>(R.id.tv_price)
}
}
}
Now we need to code in the activity class.
RoomActivity.kt
package com.example.ecommerceapplication
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.ecommerceapplication.roomdb.User
import com.example.ecommerceapplication.roomdb.UserDatabase
import com.example.ecommerceapplication.ui.adapter.RecyclerAdapter
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class RoomActivity : AppCompatActivity() {
lateinit var db: UserDatabase
var recyclerView: RecyclerView? = null
var Manager: GridLayoutManager? = null
var adapter: RecyclerAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_room)
recyclerView = findViewById<View>(R.id.rv_design) as RecyclerView
Manager = GridLayoutManager(this, 2)
recyclerView!!.layoutManager = Manager
adapter = RecyclerAdapter()
recyclerView!!.adapter = adapter
db = UserDatabase.getDatabase(this)!!
val user1 =
User("Pink Bag", "$20", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0sGeKNQngI4Ou_4xoLkM8V_SEHnBZwYMshg&usqp=CAU")
val user2 =
User("Bag Black", "$30", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTlTwVdQhinpCJoJSq7ErtO8XSLZXKWX4FrNw&usqp=CAU")
val user3 =
User("Red Bag", "$10", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ4Q8UbOq6OZzvZBdtURmc3JC-7aQGqXnyWCg&usqp=CAU")
val user4 =
User("Bag Pink", "$15", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSJgLEJqFbZbUGqV23KY7XTXcxLpxBZhYs-2w&usqp=CAU")
val user5 =
User("New Bag", "$17", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRfTQwInYeHWNR-3Kwb1337U1GWItol1sI5Vw&usqp=CAU")
val user6 =
User("My Bag", "$24", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwQ0syEOfQ8TnEUczI1Xmy8Tc4lwsSkGDyRA&usqp=CAU")
val user7 =
User("Bag b", "$23", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRDUgVcWDOUxkEb0fOrxenG2o_ujljbUaS3aQ&usqp=CAU")
val user8 =
User("Bags", "$20", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTgvk9zW-IGR1kFjdtWGp6CG6oZtlStGJnDHw&usqp=CAU")
val user9 =
User("shopping Bag", "$14", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR2YwDgCT83wfikBrI9mMhX4YItHxVNy5t26w&usqp=CAU")
val user10 =
User("bags", "$43", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTu-PsgBuoFAaL_DuAbwjNN3YZ8U0YQy8NGeA&usqp=CAU")
val user11 =
User("my bags", "$23", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSb791D7qVA3F9QL25FtCCHqC-GDR6uIRE7Ew&usqp=CAU")
val user12 =
User("New Bags ", "$31", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRNhGtr7RE2Y3INqiKbn6qz-CC4lUSeVsUyew&usqp=CAU")
GlobalScope.launch {
db.UserDao().deleteAll()
db.UserDao().insert(user1, user2, user3, user4,user5,user6,user7,user8,user9,user10,user11,user12)
displayUsers()
}
}
private suspend fun displayUsers() {
val users: List<User> = db.UserDao().getAllUsers()
runOnUiThread() {
adapter?.Updatedata(users)
}
}
}
The source code is here.
That's it. Happy Coding.