我写我的第一个应用程序在静态编程语言后,与Android的3年经验。只是困惑于如何利用itemClickListener与静态编程语言回收视图。
我已经尝试了trait(edit: now界面)方法,非常Java
public class MainActivity : ActionBarActivity() {
protected override fun onCreate(savedInstanceState: Bundle?) {
// set content view etc go above this line
class itemClickListener : ItemClickListener {
override fun onItemClick(view: View, position: Int) {
Toast.makeText(this@MainActivity, "TEST: " + position, Toast.LENGTH_SHORT).show()
}
}
val adapter = DrawerAdapter(itemClickListener())
mRecyclerView.setAdapter(adapter)
}
trait ItemClickListener {
fun onItemClick(view: View, position: Int)
}
}
这似乎很多余,所以我尝试了内部类方法:
inner class ItemClickListener {
fun onItemClick(view: View, position: Int) {
startActivityFromFragmentForResult<SelectExerciseActivity>(SELECT_EXERCISES)
}
}
然后设置适配器的click listener,如下所示:
val adapter = WorkoutsAdapter(ItemClickListener())
但我仍然不满意,因为我认为可能有更好、更干净的方法。我试图实现这样的目标:RecyclerView onClick
有什么建议吗?
最终得到了认可答案的一个变体
定义了活动中的功能:
val itemOnClick: (View, Int, Int) -> Unit = { view, position, type ->
Log.d(TAG, "test")
}
将函数本身传递给适配器,如下所示:
class ExercisesAdapter(val itemClickListener: (View, Int, Int) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
// other stuff up here
val vhExercise = ExerciseVH(view) // view holder
// on to the view holder through the extension function
vhExercise.onClick(itemClickListener)
}
}
在下面批准的答案中按循环扩展功能。
fun <T : RecyclerView.ViewHolder> T.onClick(event: (view: View, position: Int, type: Int) -> Unit): T {
itemView.setOnClickListener {
event.invoke(it, getAdapterPosition(), getItemViewType())
}
return this
}
如果有人想要一个更简单的答案,我尝试了以下方法——这与AfzalivE的解决方案非常相似:
在我的Adapter类中,我将clickListener
作为参数传递。在onBindViewHolder
上,我使用了setOnClickListener
来调用clickListener
并处理单击事件。
我的适配器。kt:
class MyAdapter constructor(objects: ArrayList<MyObject>, val clickListener: (MyObject) -> Unit) : RecyclerView.Adapter<MyAdapter.Holder>() {
private var mObjects : ArrayList<MyObject> = ArrayList<MyObject>()
init {
mObjects = objects
}
override fun onBindViewHolder(holder: Holder?, position: Int) {
var item : MyObject = objects[position]
// Calling the clickListener sent by the constructor
holder?.containerView?.setOnClickListener { clickListener(item) }
}
// More code (ViewHolder definitions and stuff)...
}
注意:我需要列表项的容器(根视图)中的引用,在本例中是containerView
然后,我将我的对象作为参数传递,而无需再次在列表中搜索它,并在我的活动
类中直接处理它,就在我设置适配器的那一刻:
MyActivity.kt:
myRecyclerView?.adapter = MyAdapter(mObjects) {
Log.e("Activity", "Clicked on item ${it.itemName}")
}
使现代化
如果需要获取单击项的位置,只需在回调中将其定义为参数,然后稍后将其发送回。注意val clickListener:(MyObject,Int)-
我的适配器。kt
class MyAdapter constructor(objects: ArrayList<MyObject>, val clickListener: (MyObject, Int) -> Unit) : RecyclerView.Adapter<MyAdapter.Holder>() {
// Rest of the code...
然后在
onBindViewHolder()
调用回调方法时传递位置:
override fun onBindViewHolder(holder: Holder?, position: Int) {
var item : MyObject = objects[position]
// Calling the clickListener sent by the constructor
holder?.containerView?.setOnClickListener { clickListener(item, position) }
}
还有我的活动。kt,你必须改变你设置适配器的方式,这样你才能得到位置。这样地:
myRecyclerView?.adapter = MyAdapter(mObjects) { itemDto: MyObject, position: Int ->
Log.e("MyActivity", "Clicked on item ${itemDto.someItemPropertyLikeName} at position $position")
}
我有一点不同的方法。您可以为ViewHolder创建扩展
fun <T : RecyclerView.ViewHolder> T.listen(event: (position: Int, type: Int) -> Unit): T {
itemView.setOnClickListener {
event.invoke(getAdapterPosition(), getItemViewType())
}
return this
}
然后像这样在适配器中使用它
class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
val items: MutableList<String> = arrayListOf()
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): MyViewHolder? {
val inflater = LayoutInflater.from(parent!!.getContext())
val view = inflater.inflate(R.layout.item_view, parent, false)
return MyViewHolder(view).listen { pos, type ->
val item = items.get(pos)
//TODO do other stuff here
}
}
override fun onBindViewHolder(holder: MyViewHolder?, position: Int) {
}
override fun getItemCount(): Int {
return items.size()
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
}
}
我正在与我的同事在图书馆提供这样的扩展。
我的解决方案就像是将之前的方案与活动中的超级清洁通话相结合。
ContactAdapter:
class ContactAdapter @Inject constructor() : RecyclerView.Adapter<ContactAdapter.ViewHolder>() {
var onItemClick: ((Contact) -> Unit)? = null
var contacts: List<Contact> = emptyList()
...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val contact = contacts[position]
holder.email.text = contact.email
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val email: TextView = itemView.email
init {
itemView.setOnClickListener {
onItemClick?.invoke(contacts[adapterPosition])
}
}
}
}
联系活动:
override fun setupRecyclerAdapter() {
recyclerView.adapter = contactAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
contactAdapter.onItemClick = { contact ->
// do something with your item
Log.d("TAG", contact.email)
}
}
我试图理解继承与委派的斗争,以及如何实现这两者。我的问题是为什么我要用Kotlin的方式用by关键字实现委派?我觉得太过分了。 让我给你举个例子。我们有一个可以点餐的应用程序。这款应用名为DeliveryQueen。 下面是Java示例: Kotlin示例#1没有明确使用by关键字:
在为android开发时,我有时会遇到类似这样的事情: 我不明白关键字有什么意义。
我有一个按钮和编辑文本。当用户在编辑文本中完成输入并按下按钮时,我想关闭我的软键盘。 或它的任何指南或参考链接。
下面的代码在无法通过条件颜色时编译。深色和彩色。浅色,因为这两个类是抽象的。 我错过什么了吗?
我们可以编写包含或不包含的代码,如下所示。 或 的实际用途是什么?。这是内存效率更高还是可读性更强?
我试图理解静态编程语言对泛型的理解,尤其是和关键字。我写了这篇简单的文章,希望能说明我的困惑点。 这是看起来可行的方法; 在这里,IDE给出了一个提示,说明for循环正在迭代的项目类型是。这很好。 上面方法的另一个版本乍一看似乎不太对劲(因为它是一个“消费者”)。但是我想做的就是阅读一个形状列表,这就是中