View.OnClickListener для внутреннего класса в Adapter не работает - PullRequest
1 голос
/ 18 мая 2019

У меня есть простой адаптер с классом внутреннего держателя.

Я пытаюсь реализовать прослушивание щелчков элементов таким способом, и он не работает:

class ThemeAdapter(private val callback: (position: Int) -> Unit) : RecyclerView.Adapter<ThemeAdapter.ThemeHolder>() {

    private lateinit var themeList: Array<String>

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

    fun setThemes(themes: Array<String>) {
        themeList = themes
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ThemeHolder {
        val inflater = LayoutInflater.from(viewGroup.context)
        return ThemeHolder(inflater.inflate(R.layout.cell_library_themes, viewGroup, false))
    }

    override fun onBindViewHolder(holder: ThemeHolder, position: Int) {
        holder.bind(themeList[position])
    }

    inner class ThemeHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
        private var theme: TextView = itemView.spinner_library_dropdown

        fun bind(themeName: String) {
            theme.text = themeName
        }

        override fun onClick(v: View?) {
            Timber.e("OnClick!")
            callback.invoke(adapterPosition) 
        }
    }
}

В бревне ничего нет.

Это легко исправить:

fun bind(themeName: String) {
            theme.text = themeName
            itemView.setOnClickListener {
                Timber.e("OnClick!")
                callback.invoke(adapterPosition)
            }
        }

И я понимаю, почему работает второй код, но кто-то может мне объяснить, почему мой первый код не работает? Какая разница?

Ответы [ 2 ]

0 голосов
/ 18 мая 2019

Просто привяжите ваш ViewHolder, который реализует View.OnClickListener, к вашему ViewHolder.itemView

fun bind(themeName: String) {
    itemView.setOnClickListener(this)
    theme.text = themeName
}

Вы только что реализовали необходимый метод из интерфейса View.OnClickListener, но вы его нигде не используете (этопросто неиспользуемый метод в вашем фрагменте кода).Android не знает, что это View, потому что он реализует свой интерфейс.

Код, который работал для вас на Java, будет выглядеть так:

itemView.setOnClickListener(new View.OnClickListener() {
    Timber.e("OnClick!");
    callback.invoke(adapterPosition);
});

И другие, которые не работают

itemView.setOnClickListener(null); // therefore it doesn't work for you
// cause your itemView doesn't have any listener
0 голосов
/ 18 мая 2019

попробуйте это: в вашем классе адаптеров

lateinit var mClickHandler: MyAdapterOnClickHandler

interface MyAdapterOnClickHandler {
    fun onClick(view: View, position: Int)
}

fun setOnClickHandler(myAdapterOnClickHandler: MyAdapterOnCLickHandler){
    mClickHandler = myAdapterOnClickHandler
}

в вашем видоискателе:

init {
    itemView.setOnClickListener(this)
}

override fun onClick(v: View?) {
    mClickHandler.onClick(itemView, adapterPosition)
}

ваша деятельность или фрагмент должен реализовывать MyAdapter.MyAdapterOnClickHandler в вашей активности:

//in onCreate 
adapter = MyAdapter(this)
adapter.setOnClickListener(this)

// then override the onclick
override fun onCLick(view: View, position: Int) {
   Log.d(LOGTAG, "clicked! $position")
}
...