Skip to content

Instantly share code, notes, and snippets.

@stevdza-san
Last active March 31, 2024 10:09
Show Gist options
  • Save stevdza-san/ed7eb9b1904e60c4e5be405660757096 to your computer and use it in GitHub Desktop.
Save stevdza-san/ed7eb9b1904e60c4e5be405660757096 to your computer and use it in GitHub Desktop.
@TypeConverter
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
buildToolsVersion "30.0.0"
defaultConfig {
applicationId "com.example.roomdemo"
minSdkVersion 26
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
// Navigation Component
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
// Room components
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
implementation "androidx.room:room-ktx:2.2.5"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation("io.coil-kt:coil:1.0.0-rc3")
}
class Converters {
@TypeConverter
fun fromBitmap(bitmap: Bitmap): ByteArray {
val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
return outputStream.toByteArray()
}
@TypeConverter
fun toBitmap(byteArray: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
}
}
class MainActivity : AppCompatActivity() {
private val adapter by lazy { MyAdapter() }
private lateinit var myViewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myViewModel = ViewModelProvider(this).get(MyViewModel::class.java)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
lifecycleScope.launch {
val person = Person("John", "Doe", getBitmap())
myViewModel.insertPerson(person)
}
myViewModel.readPerson.observe(this, {
adapter.setData(it)
})
}
private suspend fun getBitmap(): Bitmap {
val loading = ImageLoader(this)
val request = ImageRequest.Builder(this)
.data("https://avatars3.githubusercontent.com/u/14994036?s=400&u=2832879700f03d4b37ae1c09645352a352b9d2d0&v=4")
.build()
val result = (loading.execute(request) as SuccessResult).drawable
return (result as BitmapDrawable).bitmap
}
}
class MyAdapter: RecyclerView.Adapter<MyAdapter.MyViewHolder>(){
private var person = emptyList<Person>()
inner class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_layout, parent, false))
}
override fun getItemCount(): Int {
return person.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.itemView.firstName_txt.text = person[position].firstName
holder.itemView.lastName_txt.text = person[position].lastName
holder.itemView.imageView.load(person[position].profilePhoto)
}
fun setData(person: List<Person>){
this.person = person
notifyDataSetChanged()
}
}
@Dao
interface MyDao {
@Query("SELECT * FROM my_table ORDER BY id ASC")
fun readPerson(): LiveData<List<Person>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertPerson(person: Person)
}
@Database(entities = [Person::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class MyDatabase : RoomDatabase() {
abstract fun myDao(): MyDao
companion object {
@Volatile
private var INSTANCE: MyDatabase? = null
fun getDatabase(context: Context): MyDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE
?: buildDatabase(context).also { INSTANCE = it }
}
private fun buildDatabase(context: Context) =
Room.databaseBuilder(
context.applicationContext,
MyDatabase::class.java, "my_database"
).build()
}
}
class MyRepository(private val myDao: MyDao) {
val readPerson: LiveData<List<Person>> = myDao.readPerson()
suspend fun insertPerson(person: Person){
myDao.insertPerson(person)
}
}
class MyViewModel(application: Application): AndroidViewModel(application) {
private val dao = MyDatabase.getDatabase(application).myDao()
private val repository = MyRepository(dao)
val readPerson: LiveData<List<Person>> = repository.readPerson
fun insertPerson(person: Person){
viewModelScope.launch(Dispatchers.IO) {
repository.insertPerson(person)
}
}
}
@Entity(tableName = "my_table")
data class Person(
val firstName: String,
val lastName: String,
val profilePhoto: Bitmap
){
@PrimaryKey(autoGenerate = true)
var id: Int = 0
}
<?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="wrap_content">
<TextView
android:id="@+id/firstName_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="20dp"
android:text="First Name"
android:textSize="20sp"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/lastName_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Last Name"
app:layout_constraintStart_toStartOf="@+id/firstName_txt"
app:layout_constraintTop_toBottomOf="@+id/firstName_txt" />
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment