kotlin / android:将recyclerview中的每个按钮设置为开始其自己的活动

时间:2019-01-05 19:22:22

标签: android android-activity kotlin android-recyclerview onclicklistener

我想进行一项活动,选择要在游戏中玩的关卡。为此,我创建了一个带有按钮的recyclerview。这些按钮中的每个按钮都应启动其相应的级别。使用下面的代码(来自适配器),它们都指向MainActivity。有一种简单的方法可以改变这种情况吗?

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.levelButton?.text = items.get(position)
        holder.itemView.levelButton.setOnClickListener{
            var gotoLevel= Intent(context,MainActivity::class.java)
            context.startActivity(gotoLevel)
    }
}

如果这太明显了,我要道歉。我是几天前才开始编写代码的,现在仍处于该阶段,您甚至不知道适合您问题的Google搜索条件。

3 个答案:

答案 0 :(得分:0)

您有不同的选择来实现这一目标-理想情况下,我们已将逻辑与适配器分离,并且您的活动应处理用户单击行之一后要处理的动作。

据我所知,您已经定义了一个 ViewHolder 来引用您的视图-对吗?您可以像这样添加项目点击界面:

class ViewHolder(view : View) : RecyclerView.ViewHolder(view) {

    val levelButton : TextView = view.tv_levelButton

    interface OnUserAction {

        fun onItemClick(item : Item)
    }
}

并为了在用户每次单击某个单元格时触发它-与其在每个视图更新中进行设置,都应该在 onCreateViewHolder 上仅执行一次:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val holder = ViewHolder(inflater.inflate(R.layout.your_layout, parent, false))

    holder.onClick {
        position, _ -> action.onItemClick(items.get(position))
    }

    return holder
}

您在上面看到的 action 字段是在适配器构造函数上发送的接口:

class ItemsAdapter(val items: List<Item>, private val action: ViewHolder.OnUserAction)...

为此,为了调用特定的动作,您只需在活动/片段上实现创建的接口- OnUserAction

override fun onItemClick(item: Item) {
    var gotoLevel = getLevel(item)
    context.startActivity(gotoLevel)
}

编辑: 为了使事情变得简单,我创建了一个OnClick扩展功能:

fun <T : RecyclerView.ViewHolder> T.onClick(event: (position: Int, type: Int) -> Unit): T {
itemView.setOnClickListener {
    event.invoke(adapterPosition, itemViewType)
}
return this

}

答案 1 :(得分:0)

您应该从超类( RecyclerView.Adapter )获得上下文。并使用它从 View

setOnClickListener 方法创建一个Intent
class YourHolder(view: View) : RecyclerView.ViewHolder(view) {
    private var buttonView = view.buttonView
    // Variable for the Context
    private lateinit var context : Context
    fun bindHolder(itemData: ItemData) {
        // Init context
        context = super.itemView.context
        // OnClick Button Handler
        buttonView .setOnClickListener{
            // Move to AnotherActivity
            val intent = Intent(this.context, AnotherActivity::class.java)
            intent.putExtra("key", ItemData.value)
            startActivity(this.context, intent, null)
        }
    }
}

答案 2 :(得分:0)

最简单的方法是更新您的数据模型以包含要启动的活动的类。现在,您似乎只有一个字符串列表。因此,将其更改为具有字符串和要启动的类的自定义对象。

class Item(val levelButtonText: String, val activityClass: Class<*>)

然后,您的绑定将硬编码的MainActivity :: class.java替换为当前项目类:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = items.get(position)
    holder.levelButton?.text = item.levelButtonText
    holder.itemView.levelButton.setOnClickListener{
        var gotoLevel= Intent(context, item.activityClass)
        context.startActivity(gotoLevel)
}

然后,无论您在哪里为适配器创建项目列表,都用Item替换一个字符串,该字符串设置要启动的Activity的类。

希望有帮助!