Создание кнопки удаления для RecyclerView в Kotlin

#android #kotlin

#Android #kotlin

Вопрос:

Это мое первое приложение в Kotlin, но я не думаю, что хорошо понимаю логику. Я пытаюсь создать кнопку удаления для каждого отдельного элемента в списке с помощью Recycler View:

мой MusicianRecyclerAdapter:

 package com.example.genremusicians

import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.genremusicians.Models.MusicianInfo
import kotlinx.android.synthetic.main.item_musician_list.view.*

class MusicianRecyclerAdapter (private val context: Context, private val musicians:List<MusicianInfo>) : RecyclerView.Adapter<MusicianRecyclerAdapter.ViewHolder>() {

    private val  layoutInflater = LayoutInflater.from(context)
    inner class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
        val deleteButton = itemView.deleteButton
        val textGenre = itemView.findViewById<TextView>(R.id.textViewTitle)
        val textMusician = itemView.findViewById<TextView>(R.id.textViewText)
        var musicianPosition = 0
        init {
            itemView.setOnClickListener{
                val intent = Intent(context,MainActivity::class.java)
                intent.putExtra(EXTRA_MUSICIAN_POSITION,musicianPosition)
                context.startActivity(intent)
            }
        }
        init {
            deleteButton.setOnClickListener{
                val intent = Intent(context,MainActivity::class.java)
                intent.removeExtra(EXTRA_MUSICIAN_POSITION)
                context.startActivity(intent)
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = layoutInflater.inflate(R.layout.item_musician_list,parent, false)
        return ViewHolder(itemView)
    }

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        var musician = musicians[position]
        holder.textGenre.text = musician.genre?.title
        holder.textMusician.text = musician.name
        holder.musicianPosition = position
    }
}
  

и это моя основная активность

 package com.example.genremusicians

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.ArrayAdapter
import com.example.genregenres.Models.DataManager
import com.example.genremusicians.Models.GenreInfo
import com.example.genremusicians.Models.MusicianInfo
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    private var musicianPosition = POSITION_NOT_SET
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var adapterGenres = ArrayAdapter<GenreInfo>(
            this,
            android.R.layout.simple_spinner_item,
            DataManager.genres.values.toList()
        )

        adapterGenres.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line)
        spinnerGenre.adapter = adapterGenres

        musicianPosition = savedInstanceState?.getInt(EXTRA_MUSICIAN_POSITION, POSITION_NOT_SET)
            ?: intent.getIntExtra(EXTRA_MUSICIAN_POSITION, POSITION_NOT_SET)


        if (musicianPosition != POSITION_NOT_SET) {
            displayMusician()
        } else {
            createMusician()
        }

    }

    private fun createMusician() {
        DataManager.musicians.add(MusicianInfo())
        musicianPosition = DataManager.musicians.lastIndex
    }

    override fun onRestart() {
        super.onRestart()
    }

    override fun onPause() {
        super.onPause()
        saveMusician()
    }

    private fun saveMusician() {
        val musician = DataManager.musicians[musicianPosition]
        musician.name = editTextName.text.toString()
        musician.album = editTextAlbum.text.toString()
        musician.genre = spinnerGenre.selectedItem as GenreInfo
    }

    override fun onStop() {
        super.onStop()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt(EXTRA_MUSICIAN_POSITION, musicianPosition)
    }

    private fun displayMusician() {
        val musician = DataManager.musicians[musicianPosition]
        editTextName.setText(musician.name)
        editTextAlbum.setText(musician.album)
        val genrePosition = DataManager.genres.values.indexOf(musician.genre)
        spinnerGenre.setSelection(genrePosition)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.action_settings -> true
            R.id.action_next -> {
                MoveNext()
            }
            else -> super.onOptionsItemSelected(item)
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
        if (musicianPosition >= DataManager.musicians.lastIndex) {
            var item = menu?.findItem(R.id.action_next)
            if (item != null) {
                item.icon = getDrawable(R.drawable.ic_baseline_block_24)
                item.isEnabled = false
            }
        }
        return super.onPrepareOptionsMenu(menu)
    }

    override fun invalidateOptionsMenu() {
        super.invalidateOptionsMenu()
    }

    private fun MoveNext() {
        musicianPosition  
        displayMusician()
        invalidateOptionsMenu()
    }
}
  

У меня есть мои данные из файла, который я создал, чтобы начать обучение, но я не понимаю, что я делаю неправильно, создавая кнопку удаления, и как я должен это сделать. Спасибо всем

Комментарии:

1. почему бы вам не поместить кнопку в XML-файл CardView, а затем получить к нему доступ с помощью метода onBindViewHolder(), например: holder.itemview.myDeleteButton.setOnClickListener{}

Ответ №1:

Чтобы настроить событие on click для удаления, вы должны использовать приведенный ниже код и в вашем адаптере:

 private var onClickListener : OnClickListener? = null

fun setOnClickListener(onClickListener: OnClickListener){
    this.onClickListener = onClickListener
}

interface OnClickListener {
    fun onClick(position: Int){
    }
}
  

Затем вы можете создать функцию для удаления элементов в recyclerview, это удалит элемент в указанной позиции в списке, а также уведомит recyclerview о том, что элемент был удален, чтобы он обновился:

 private fun removeItem(position: Int){
    list.removeAt(position)
    notifyItemRemoved(position)
}
  

Это позволит вам вызывать функцию onClick при создании экземпляра интерфейса. У вас должна быть кнопка удаления в XML-файле вашего представления элементов, для которой затем вы можете установить OnClickListener для кнопки в onBindViewHolder следующим образом :

 holder.itemView.btn_delete.setOnClickListener {
                if(onClickListener != null){
                    onClickListener!!.onClick(position)
                    removeItem(position)
                }
            }
  

Комментарии:

1. спасибо за ваш полный ответ, основная проблема, с которой я столкнулся, заключалась в том, что я не объявлял изменяемый список, это было похоже на: private val musicians:List<MusicianInfo> ). после того, как он реализовал то, что вы сказали, было потрясающе, большое вам спасибо

2. Рад помочь, был бы очень признателен, если бы вы отметили мой ответ как правильный 🙂

3. Мне очень жаль, я думал, что сделал, еще раз спасибо и еще раз извините