Follow my simple steps to solve your issue,
Step 1:
Check once CustomApplication
name mentioned or not in AndroidManifest.xml
,
<application
android:name=".CustomApplication"
otherwise you get this issue
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.AddressActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.myapplication.CustomApplication
Step 2:
Check your module level build.gradle
file
apply this changes
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
check dependencies -- For Kotlin use kapt instead of annotationProcessor
implementation "androidx.room:room-runtime:2.2.5"
kapt "androidx.room:room-compiler:2.2.5"
otherwise you get this issue
java.lang.RuntimeException: cannot find implementation for com.example.myapplication.Database. Database_Impl does not exist
Step 3:
check your AddressDao
interface, add this function
@Delete
suspend fun deleteAddress(address: Address)
Step 4:
in AddressAdapter
class, add this listener,
interface ItemListener {
fun onItemClicked(address: Address, position: Int)
}
add listener variable and setListener function
private lateinit var listener: ItemListener
interface ItemListener {
fun onItemClicked(address: Address, position: Int)
}
fun setListener(listener: ItemListener) {
this.listener = listener;
}
then update your code in tvDelete.setOnClickListener method
viewHolder.tvDelete.setOnClickListener(View.OnClickListener { view ->
mItemManger.removeShownLayouts(viewHolder.swipelayout)
addresses.removeAt(position)
listener.onItemClicked(fl, position)
notifyDataSetChanged()
// notifyItemRemoved(position)
// notifyItemRangeChanged(position, addresses.size)
mItemManger.closeAllItems()
Toast.makeText(
view.context,
"Deleted " + viewHolder.tv.getText().toString(),
Toast.LENGTH_SHORT
).show()
})
Step 5:
In AddressActivity
class, do this changes
Implement listener here,
class AddressActivity : AppCompatActivity(), AddressAdapter.ItemListener {
then override method
override fun onItemClicked(address: Address, position: Int) {
}
then set listener for adapter
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = adapter
adapter.setListener(this)
then update code in override method
override fun onItemClicked(address: Address, position: Int) {
lifecycleScope.launch {
val application = application as CustomApplication
application.database.AddressDao().deleteAddress(address)
}
}
here I used coroutine otherwise you can use AsycTask also
for coroutine add this dependencies in your module build.gradle
file
implementation "android.arch.lifecycle:extensions:1.1.1"
kapt "android.arch.lifecycle:compiler:1.1.1"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
if you directly called deleteAddress method in UI class, you get this issue
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
so use such methods in background thread,
If you really want to execute in main UI thread, do this changes in your code
in AddressDao
interface,
@Delete
fun deleteAddress(address: Address)
in CustomApplication
class, add allowMainThreadQueries()
class CustomApplication : Application() {
lateinit var database: Database
private set
lateinit var addressDao: AddressDao
private set
override fun onCreate() {
super.onCreate()
this.database = Room.databaseBuilder<Database>(
applicationContext,
Database::class.java, "database"
).allowMainThreadQueries().build()
addressDao = database.AddressDao()
}
}