android 为什么我的delete方法在传了Dao接口声明的delete方法后没有删除数据?

7z5jn7bk  于 2023-04-04  发布在  Android
关注(0)|答案(1)|浏览(104)

所以,当我以Recyclerview的形式显示保存的数据后,我试图通过调用Dao接口中声明的delete方法,在recyclerview类中声明的imageView上单击listener后删除特定位置的数据。我遵循MVVM模式。但是当我单击imageView时,没有任何动作发生。
recyclerview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_margin="20dp"
    android:background="@drawable/rounded_cardview"
    android:layout_width="match_parent"
    android:layout_height="100dp">

    <TextView
        android:layout_gravity="center"
        android:id="@+id/textView"
        style="@style/word_title"
        android:textColor="#FFFF"
        android:paddingStart="20dp"
        android:textStyle="bold"
        android:layout_marginStart="30dp"
        android:text="@string/word1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <TextView
        android:layout_gravity="center"
        android:text="@string/word2"
        android:textColor="#FFFF"
        android:textStyle="bold"
        android:id="@+id/text1"
        style="@style/word_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageDelete"
        android:src="@drawable/baseline_delete_24"
        android:layout_gravity="center"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="20dp" />
</LinearLayout>

second.xml

<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=".SecondActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/rounded_button"
        tools:listitem="@layout/recyclerview"
        android:padding="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:contentDescription="@string/add_word"/>

</androidx.constraintlayout.widget.ConstraintLayout>

第二个活动.kt

class SecondActivity:AppCompatActivity() {

    lateinit var binding: SecondBinding
    val cardViewmodel:  CardViewmodel by viewModels{
        WordViewModelFactory((application as CardsApplication).repository)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
         binding = SecondBinding.inflate(layoutInflater)
         setContentView(binding.root)

        val adapter = CardListAdapter()
        binding.recyclerview1.adapter = adapter
        binding.recyclerview1.layoutManager = LinearLayoutManager(this)

        cardViewmodel.allWords.observe(this) { cardPairs ->

            for (cardpair in cardPairs) {
                 adapter.submitList(cardPairs)
            }

        }

        val inflator = getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val view = inflator.inflate(R.layout.recyclerview,null)

        val imageDelete = view.findViewById<ImageView>(R.id.imageDelete)

        imageDelete.setOnClickListener {

            // Get the position of the clicked item
            val position = binding.recyclerview1.getChildAdapterPosition(view)

            // Get the CardPair object from the adapter using the position
            val cardPair = adapter.currentList[position]

            // Call the delete() method on your CardViewmodel to delete the CardPair from the database
            cardViewmodel.deleteCards(cardPair)

            // Notify the adapter that the data has changed
            adapter.notifyItemRemoved(position)

        }
    }
}

Cardviewmodel.kt

class CardViewmodel(private val repository:CardPairRepository) : ViewModel() {

    // Using LiveData and caching what allWords returns has several benefits:
    // - We can put an observer on the data (instead of polling for changes) and only update the
    //   the UI when the data actually changes.
    // - Repository is completely separated from the UI through the ViewModel.
    val allWords: LiveData<List<CardPair>> = repository.allWords.asLiveData()

    /**
     * Launching a new coroutine to insert the data in a non-blocking way
     */
    fun insertCards(pair: CardPair) = viewModelScope.launch {
        repository.insert(pair)
    }

    fun deleteCards(pair: CardPair) = viewModelScope.launch {
        repository.deleteCard(pair)
    }
}

class WordViewModelFactory(private val repository:CardPairRepository) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(CardViewmodel::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return CardViewmodel(repository) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
}

CardListAdapter.kt

class CardListAdapter : ListAdapter<CardPair,CardListAdapter.WordViewHolder>(WordsComparator()) {

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

    override fun onBindViewHolder(holder: WordViewHolder, position: Int) {
        val current = getItem(position)
        val current1 = getItem(position)
        holder.bind(current.front,current1.back)
    }

    class WordViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val wordItemView: TextView = itemView.findViewById(R.id.textView)
        private val deftext: TextView = itemView.findViewById(R.id.text1)

        fun bind(text: String?,text1: String?) {
            wordItemView.text = text
            deftext.text=text1
        }

        companion object {
            fun create(parent: ViewGroup): WordViewHolder {
                val view: View = LayoutInflater.from(parent.context)
                    .inflate(R.layout.recyclerview, parent, false)
                return WordViewHolder(view)
            }
        }
    }

    class WordsComparator : DiffUtil.ItemCallback<CardPair>() {
        override fun areItemsTheSame(oldItem:CardPair, newItem:CardPair): Boolean {
            return oldItem === newItem
        }

        override fun areContentsTheSame(oldItem:CardPair, newItem:CardPair): Boolean {
            return oldItem.front == newItem.front && oldItem.back==newItem.back
        }
    }
}

存储库类的构成如下

class CardPairRepository(private val cardPairDao: CardPairDao) {

    // Room executes all queries on a separate thread.
    // Observed Flow will notify the observer when the data has changed.
    val allWords: Flow<List<CardPair>> = cardPairDao.getAlphabetizedWords()

    // By default Room runs suspend queries off the main thread, therefore, we don't need to
    // implement anything else to ensure we're not doing long running database work
    // off the main thread.
    @Suppress("RedundantSuspendModifier")
    @WorkerThread
    suspend fun insert(pair: CardPair) {
        cardPairDao.insertWord(pair)
    }

    @WorkerThread
    suspend fun deleteCard(pair: CardPair){
        cardPairDao.deleteWord(pair)
    }
}

用于设置房间数据库的数据类

@Entity(tableName = "word_table")
data class CardPair(
    @PrimaryKey @ColumnInfo(name = "front") val front: String,
    @ColumnInfo(name = "back") val back: String
)

接口CardPairDao.kt

@Dao
interface CardPairDao {

    @Query("SELECT * FROM word_table ORDER BY front ASC, back ASC")
    fun getAlphabetizedWords(): Flow<List<CardPair>>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insertWord(pair: CardPair)

    @Delete
    suspend fun deleteWord(pair: CardPair)

}

房间数据库类显示在CardRoomDatabase.kt下面

@Database(entities = [CardPair::class], version = 2, exportSchema = true)
abstract class CardRoomDatabase : RoomDatabase() {

    abstract fun cardPairDao(): CardPairDao

    private class WordDatabaseCallback(
        private val scope: CoroutineScope
    ) : Callback() {

        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            INSTANCE?.let { database ->
                scope.launch {
                    var wordDao = database.cardPairDao()

                    wordDao.getAlphabetizedWords()

                }
            }
        }
    }
    companion object {
        @Volatile
        private var INSTANCE:CardRoomDatabase? = null

        fun getDatabase(
            context: Context,
            scope: CoroutineScope
        ):CardRoomDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    CardRoomDatabase::class.java,
                    "word_database"
                )
                    .addCallback(WordDatabaseCallback(scope))
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                // return instance
                instance
            }
        }
}

}

qhhrdooz

qhhrdooz1#

根据您提供的代码,看起来您正在布局中的ImageView上设置单击侦听器,而该布局不是RecyclerView布局的一部分。
要修复此问题,可以在RecyclerView适配器的onBindViewHolder方法中设置ImageView上的单击侦听器

相关问题