在使用Android 3年后,我正在Kotlin编写我的第一个应用程序。 只是对如何在Kotlin中使用itemClickListener和RecyclerView感到困惑。
我尝试了特征(编辑:现在界面)方法,非常类似于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)
}
}
然后只需设置适配器的点击监听器:
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
}
答案 0 :(得分:19)
我的方法有点不同。您可以为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) {
}
}
我正与library的同事一起提供此类扩展。
答案 1 :(得分:19)
My solution is like a combination of the previous ones with a super clean call from the activity.
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])
}
}
}
}
ContactActivity:
override fun setupRecyclerAdapter() {
recyclerView.adapter = contactAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
contactAdapter.onItemClick = { contact ->
// do something with your item
Log.d("TAG", contact.email)
}
}
答案 2 :(得分:7)
抱歉,延迟了,从this链接获得了一个很棒的答案,它是Java语言。 做一些功课并将其转换为Kotlin。
现在它可以正常工作了。这是代码,
创建一个名为RecyclerItemClickListenr的类,
class RecyclerItemClickListenr(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {
private val mGestureDetector: GestureDetector
interface OnItemClickListener {
fun onItemClick(view: View, position: Int)
fun onItemLongClick(view: View?, position: Int)
}
init {
mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent): Boolean {
return true
}
override fun onLongPress(e: MotionEvent) {
val childView = recyclerView.findChildViewUnder(e.x, e.y)
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView))
}
}
})
}
override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
val childView = view.findChildViewUnder(e.x, e.y)
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView))
}
return false
}
override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}}
并以“活动/片段”身份访问
recyclerView.addOnItemTouchListener(RecyclerItemClickListenr(this, recyclerView, object : RecyclerItemClickListenr.OnItemClickListener {
override fun onItemClick(view: View, position: Int) {
//do your work here..
}
override fun onItemLongClick(view: View?, position: Int) {
TODO("do nothing")
}
}))
答案 3 :(得分:6)
如果有人正在寻找更多简单的答案,我尝试了以下内容 - 这与 AfzalivE 的解决方案非常相似:
在我的Adapter类中,我传递了clickListener
作为参数。在onBindViewHolder
,我已使用setOnClickListener
来致电clickListener
并处理点击事件。
<强> MyAdapter.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
然后我将我的对象作为参数传递,而不需要再次在列表中搜索它并直接在我的Activity
类上处理它,在我设置适配器的那一刻:
<强> MyActivity.kt 强>:
myRecyclerView?.adapter = MyAdapter(mObjects) {
Log.e("Activity", "Clicked on item ${it.itemName}")
}
<强> 更新 强>
如果您需要获取被点击项目的位置,只需在回调中将其定义为参数,然后稍后再将其发回。请注意下面的val clickListener: (MyObject, Int) -> Unit
:
<强> MyAdapter.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) }
}
在 MyActivity.kt 上,您必须更改设置适配器的方式,以便获得该位置。像这样:
myRecyclerView?.adapter = MyAdapter(mObjects) { itemDto: MyObject, position: Int ->
Log.e("MyActivity", "Clicked on item ${itemDto.someItemPropertyLikeName} at position $position")
}
答案 4 :(得分:5)
基于denwehrle略有不同
要在片段上使用,请在OnCreateView内
adapter.onItemClick = {it ->
//do something
}
添加适配器类:
var onItemClick: ((Contact)->Unit) ?= null
...
inner class contactViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val myItemView: TextView = itemView.findViewById(R.id.textView)
init{
itemView.setOnClickListener {
onItemClick?.invoke(contact[adapterPosition])
}
}
}
答案 5 :(得分:3)
我认为最优雅的解决方案是将此责任交给recyclerView,而不是查看甚至调整它。
为此我们需要:
class RecyclerItemClickListener(
private val mRecycler: RecyclerView,
private val clickListener: ((position: Int, view: View) -> Unit)? = null,
private val longClickListener: ((position: Int, view: View) -> Unit)? = null
) : RecyclerView.OnChildAttachStateChangeListener {
override fun onChildViewDetachedFromWindow(view: View) {
view.setOnClickListener(null)
view.setOnLongClickListener(null)
}
override fun onChildViewAttachedToWindow(view: View) {
view.setOnClickListener { v -> setOnChildAttachedToWindow(v) }
}
private fun setOnChildAttachedToWindow(v: View?) {
if (v != null) {
val position = mRecycler.getChildLayoutPosition(v)
if (position >= 0) {
clickListener?.invoke(position, v)
longClickListener?.invoke(position, v)
}
}
}
}
import android.support.v7.widget.RecyclerView
import com.decathlon.manager.internal.common.RecyclerItemClickListener
@JvmOverloads
fun RecyclerView.affectOnItemClicks(onClick: ((position: Int, view: View) -> Unit)? = null, onLongClick: ((position: Int, view: View) -> Unit)? = null) {
this.addOnChildAttachStateChangeListener(RecyclerItemClickListener(this, onClick, onLongClick))
}
import kotlinx.android.synthetic.main.{your_layout_name}.*
class FragmentName : Fragment() {
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
recycler.affectOnItemClick { position, view -> /*todo*/ }
}
}
答案 6 :(得分:2)
适配器构造函数声明
class YourAdapter(private val mListener: (ItemObject) -> Unit) : RecyclerView.Adapter<ViewHolder>()
<强>适配器:: onBindViewHolder 强>
holder.itemView.setOnClickListener {
mListener.invoke(item) // <- item instance of ItemObject
}
如何使用
mTypesWasteAdapter = YourAdapter({ it.something()})
基本上,您将在lambda参数中收到ItemObject为it
。
答案 7 :(得分:2)
您可以尝试以下方式:
public class MainActivity : ActionBarActivity() {
protected override fun onCreate(savedInstanceState: Bundle?) {
[...]
val adapter = DrawAdapter(::onItemClick)
[...]
}
}
fun onItemClick(view: View, position: Int) {
//Do work
}
和SAM转换就像在Java 8中一样,所以只需使用lambda:
public class MainActivity : ActionBarActivity() {
protected override fun onCreate(savedInstanceState: Bundle?) {
[...]
val adapter = DrawAdapter({view, position -> /*Do work*/ })
[...]
}
}
答案 8 :(得分:1)
您不需要向ViewHolder或类似的东西编写扩展功能。
最佳实践;使用高阶函数
class MainRecyclerAdapter(val news: JSONArray, private val itemClickListener: (Int) -> Unit) : RecyclerView.Adapter<MainRecyclerAdapter.ViewHolder>() {}
只需添加一个高阶函数。例如itemClickListener,然后转到ViewHolder类。将此函数作为参数写入绑定函数,并将其设置为itemView这样:
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
fun bind(newsItem: JSONObject,itemClickListener:(Int)->Unit) {
//Some Stuff here..
itemView.setOnClickListener { itemClickListener(adapterPosition) }
}
}
在BindViewHolder上使用此方法
override fun onBindViewHolder(holder: MainRecyclerAdapter.ViewHolder, position: Int) {
holder.bind(news.getJSONObject(position),itemClickListener)
}
现在您可以在任何活动或片段中编写onClick函数。只需提供参数即可。
val itemOnClick: (Int) -> Unit = { position ->
newsRecyclerView.adapter!!.notifyDataSetChanged()
Toast.makeText(this.context,"$position. item clicked.",Toast.LENGTH_SHORT).show()
}
newsRecyclerView.adapter = MainRecyclerAdapter(news,itemClickListener = itemOnClick)
答案 9 :(得分:1)
3个简单步骤:
1。传入适配器的参数,如下所示:
class ListAdapter(private val mListener: (ListItemDataClass) -> Unit)
2。在onBindViewHolder
函数中,像这样
override fun onBindViewHolder(holder: YourViewHolder, position: Int) {
val item = getItem(position)
holder.itemView.setOnClickListener {
item?.let { it1 -> mListener.invoke(it1) }
}
}
3。并在您的活动中像这样
val adapter = ListAdapter {
Toast.makeText(this, it.title, Toast.LENGTH_SHORT).show()
}
答案 10 :(得分:1)
我使用高阶函数和let
作用域函数的简单解决方案仅在设置了itemAction
的情况下设置侦听器
// Adapter
private var itemAction: ((Item) -> Unit)? = null
fun setItemAction(action: (Item) -> Unit) {
this.itemAction = action
}
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun setItem(item: Item) {
// ...
itemAction?.let {
itemView.setOnClickListener { it(item) }
}
}
}
以及活动/片段
adapter.setItemAction { // <- it is Item
// do something with it
}
答案 11 :(得分:1)
最后,这是一个不错的解决方案:
MyRecyclerAdapter.kt
class MyRecyclerAdapter(val context: Context, val items : ArrayList<Item>, val clickListener: (Int) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): RecyclerView.ViewHolder {
return MyViewHolder(LayoutInflater.from(context).inflate(R.layout.my_item, parent, false))
}
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as MyViewHolder).clickableView.setOnClickListener {
clickListener(position)
}
}
}
class MyViewHolder (view: View) : RecyclerView.ViewHolder(view) {
val clickableView = view.clickable_view
}
MainActivity.kt
fun appClickListener(position: Int) {
// You got the position of ArrayList
}
my_recyclerview.adapter = MyRecyclerAdapter(this, myList, clickListener = {
appClickListener(it)
})
答案 12 :(得分:1)
RecyclerItemClickListener
package com.mypackage.custom
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
@Suppress("DEPRECATION")
class RecyclerItemClickListener(context: Context, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener {
private var mGestureDetector: GestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent): Boolean {
return true
}
})
interface OnItemClickListener {
fun onItemClick(view: View, position: Int)
}
override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean {
val childView = view.findChildViewUnder(e.x, e.y)
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildPosition(childView))
return true
}
return false
}
override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
}
活动:
recyclerView!!.addOnItemTouchListener(
RecyclerItemClickListener(this!!, object : RecyclerItemClickListener.OnItemClickListener {
override fun onItemClick(view: View, position: Int) {
//Write your code here
}
})
对于片段:
recyclerView!!.addOnItemTouchListener(
RecyclerItemClickListener(this!!.activity!!, object : RecyclerItemClickListener.OnItemClickListener {
override fun onItemClick(view: View, position: Int) {
//Write your code here
}
})
答案 13 :(得分:1)
在RecyclerView中,您可以点击ViewHolder
类中的膨胀视图,并从onBindViewHolder
回调方法调用它,例如:
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val view = view
val tv_message = view.tv_message
val tv_address = view.tv_address
fun bind(listViewItem: ListViewItem) {
view.setOnClickListener(View.OnClickListener {
Toast.makeText(
view.context,
"Name: " + listViewItem.name + "/n Address: " + listViewItem.address,
Toast.LENGTH_LONG).show()
})
}
}
}
您可以从适配器onBindViewHolder()
方法调用:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val listViewItem: ListViewItem = mListViewItems[position]
holder.tv_message.text = listViewItem.name
holder.tv_address.text = listViewItem.address
holder.bind(mListViewItems[position]);
}
答案 14 :(得分:0)
哦,有人可能会这样喜欢
我们都将编辑图像和垃圾桶图像放入recyclerview中,并希望在单击它们时发生某些情况。这是我们的Kotlin示例
这是在适配器中膨胀的卡片视图中
<RelativeLayout
android:id="@+id/editCLICK"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="370dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:paddingTop="12dp">
<ImageView
android:id="@+id/ivEdit"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@color/color_Transparent"
android:src="@drawable/ic_edit"
android:tint="@color/color_lightBlue" />
</RelativeLayout>
然后在适配器中进行一些绑定
override fun onBindViewHolder(holder: ParentViewHolder, position: Int) {
val items = parentList[position]
holder.item.text = items.dept
holder.editCLICK.setOnClickListener {
val i = Intent(context, EnterParentActivity::class.java)
i.putExtra("FROM", "U")
i.putExtra("MainActId",items.idD)
i.putExtra("PFK",items.fkD)
i.putExtra("ET",items.dept)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(i)
}
}
inner class ParentViewHolder(view: View):RecyclerView.ViewHolder(view){
var item: TextView = view.findViewById(R.id.tvDept) as TextView
var editCLICK: RelativeLayout = view.findViewById(R.id.editCLICK) as RelativeLayout
}
简单,快速,可靠的享受
答案 15 :(得分:0)
这是我的MainActivity.kt类,它使用recyclerview填充位置数据。它具有一个可以实现的简单的项目单击侦听器界面。
class MainActivity : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var viewAdapter: RecyclerView.Adapter<*>
private lateinit var viewManager: RecyclerView.LayoutManager
private var locationArrayList = arrayListOf<Location>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//create locations
var ny = Location("New York")
var la = Location("Los Angeles")
locationArrayList.addAll(listOf(ny, la))
viewManager = LinearLayoutManager(this)
viewAdapter = LocationsAdapter(locationArrayList)
recyclerView = findViewById<RecyclerView>(R.id.recyclerView).apply {
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
setHasFixedSize(true)
// use a linear layout manager
layoutManager = viewManager
// specify an viewAdapter
adapter = viewAdapter
}
//recycler view click listener implement
recyclerView.addOnItemClickListener(object: OnItemClickListener {
override fun onItemClicked(position: Int, view: View) {
// Your logic
Toast.makeText(this@MainActivity, locationArrayList[position].locationName, Toast.LENGTH_SHORT).show()
}
})
}
//on item click interface
interface OnItemClickListener {
fun onItemClicked(position: Int, view: View)
}
fun RecyclerView.addOnItemClickListener(onClickListener: OnItemClickListener) {
this.addOnChildAttachStateChangeListener(object: RecyclerView.OnChildAttachStateChangeListener {
override fun onChildViewDetachedFromWindow(view: View?) {
view?.setOnClickListener(null)
}
override fun onChildViewAttachedToWindow(view: View?) {
view?.setOnClickListener({
val holder = getChildViewHolder(view)
onClickListener.onItemClicked(holder.adapterPosition, view)
})
}
})
}
//end of interface
}
答案 16 :(得分:0)
如果有人对旧方法的实现感兴趣。
我张贴了完整的示例,这也减少了您的适配器代码。它使用了获取回调的旧模式。
项目级别gradle
buildscript {
ext.kotlin_version = '1.3.10'
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"//newly added
classpath 'com.google.gms:google-services:4.1.0' // google-services plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
应用程序级别Gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'org.jetbrains.kotlin.android.extensions'//it is used for @Percelize
android {
compileSdkVersion 28
dataBinding {
enabled = true
}
androidExtensions {
experimental = true
}
defaultConfig {
applicationId 'broadpeak.firebase.learning'
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
}
/*kapt {
generateStubs = true
}*/
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.google.firebase:firebase-core:16.0.5'
implementation 'com.google.firebase:firebase-firestore:17.1.3'
implementation 'com.google.firebase:firebase-auth:16.0.5'
implementation 'com.google.firebase:firebase-messaging:17.3.4'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.firebaseui:firebase-ui-auth:4.1.0'
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
////kapt "com.android.databinding:compiler:$android_plugin_version"\ // not required above 3.2.0
///kapt "com.android.databinding:compiler:3.1.4"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
// ADD THIS AT THE BOTTOM
apply plugin: 'com.google.gms.google-services'
SubjectListActivity.class
class SubjectListActivity : BaseActivity() {
var subjects = mutableListOf<SubjectBO>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.question_list_activity)
recycler_view.itemAnimator = DefaultItemAnimator()
recycler_view.setHasFixedSize(true)
recycler_view.layoutManager = LinearLayoutManager(this@SubjectListActivity)
db.collection("tagCollection").get().addOnSuccessListener { querySnapshot ->
if (querySnapshot.isEmpty()) {
Log.d(TAG, "onSuccess: LIST EMPTY")
} else {
// Convert the whole Query Snapshot to a list
// of objects directly! No need to fetch each document.
subjects = querySnapshot.toObjects(SubjectBO::class.java)
if(subjects.size > 0){
recycler_view.adapter = SubjectAdapter(subjects, object : OnRecyclerItemClickListener {
override fun onItemClicked(view: View?, position: Int) {
var intent = Intent(this@SubjectListActivity,McqActivity::class.java)
intent.putExtra("keyTagBO",subjects.get(position))
startActivity(intent)
}
});
}
}
}.addOnFailureListener { exception ->
exception.printStackTrace()
}
}
SubjectAdapter.class
class SubjectAdapter(items: List<SubjectBO>, onRecyclerItemClickListener: OnRecyclerItemClickListener)
: BaseAdapter<SubjectBO, SubjectViewHolder>(items, onRecyclerItemClickListener) {
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): SubjectViewHolder {
return SubjectViewHolder(parent, R.layout.item_subject, onRecyclerItemClickListener)
}
}
SubjectViewHolder.class
class SubjectViewHolder(parent: ViewGroup, itemLayoutId: Int, onRecyclerItemClickListener:
OnRecyclerItemClickListener) : BaseViewHolder<SubjectBO>(parent, itemLayoutId, onRecyclerItemClickListener) {
override fun bindData(data: SubjectBO) {
itemView.tvTitle.setText(data.tagName)
}
}
BaseAdapter.class
abstract class BaseAdapter<T, U : BaseViewHolder<T>>
(var items: List<T>, var onRecyclerItemClickListener: OnRecyclerItemClickListener)
: RecyclerView.Adapter<U>() {
override fun getItemCount(): Int {
return items.size
}
override fun onBindViewHolder(holder: U, pos: Int) {
holder.bindData(items.get(pos))
}
}
BaseViewHolder.class
abstract class BaseViewHolder<T : BaseModel>(parent: ViewGroup, @LayoutRes itemLayoutId: Int,
var onRecyclerItemClickListener: OnRecyclerItemClickListener) :
RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(itemLayoutId, parent,
false)), View.OnClickListener {
override fun onClick(v: View?) {
onRecyclerItemClickListener.onItemClicked(v, adapterPosition)
}
abstract fun bindData(data: T)
init {
itemView.setOnClickListener(this)
}
}
OnRecyclerItemClickListener.class
interface OnRecyclerItemClickListener{
fun onItemClicked(view: View?, position: Int)
}
答案 17 :(得分:0)
在onBindViewHolder上添加ClickListener代码
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.vieww.textView.setText(arr.get(position))
holder.vieww.setOnClickListener {(holder.vieww.textView.setTextColor(Color.GREEN))} // click event
}
答案 18 :(得分:0)
您可以使用界面轻松实现此目标
class ExercisesAdapter constructor(val mItemClickListener:ItemClickListener) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
interface ItemClickListener{
fun onItemClick(position: Int)
fun onLongClick(position: Int)
}
inner class MyViewHolder(view:View): RecyclerView.ViewHolder(view){
init {
view.setOnClickListener{
mItemClickListener.onItemClick(adapterPosition)
}
view.setOnLongClickListener{
mItemClickListener.onLongClick(adapterPosition)
return@setOnLongClickListener true
}
}
}
}
来自您的 MainActivity
public class MainActivity : ActionBarActivity(), ExercisesAdapter.ItemClickListener {
protected override fun onCreate(savedInstanceState: Bundle?) {
// set content view etc go above this line
mAdapter = ExercisesAdapter(this)
}
override fun onItemClick(position: Int) {
Toast.makeText(this@MainActivity, "TEST: " + position, Toast.LENGTH_SHORT).show()
}
override fun onLongClick(position: Int) {
//do long click here
}
}
答案 19 :(得分:0)
//第1步创建一个类似于
的界面interface RecyclerViewClickListener {
fun onItemClick(position: String)
fun onLongClick(position: Int)
}
第2步,在Adapter类内部,传递一个参数作为
之类的接口class ModelAdapter(var item_list: ArrayList<UploadDocument>,var mItemClickListener:RecyclerViewClickListener) : RecyclerView.Adapter<ModelAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ModelAdapter.ViewHolder {
// create a new view
val view = LayoutInflater.from(parent.context).inflate(R.layout.upload_document_row_item, null)
// create ViewHolder
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ModelAdapter.ViewHolder, position: Int) {
holder.txtRegistrationDoc?.setText(item_list[position].getdocName())
holder.txtCertificate?.setText(item_list[position].getcertificateName())
holder.txtFileSize?.setText(item_list[position].getfileSize())
holder.txtCreatedOn?.setText(item_list[position].getcreatedOn())
holder.txtModifiedOn?.setText(item_list[position].getModifiedDate())
//holder.chkSelected.isChecked = item_list[position].isSelected()
holder.chkSelected.tag = item_list[position].getdocName()
holder. chkSelected!!.setOnCheckedChangeListener { buttonView, isChecked ->
if(isChecked)
{
System.out.println("position>>>"+buttonView.tag.toString())
mItemClickListener.onItemClick(buttonView.tag.toString())
}
}
//(context as UploadDocumentActivity::class.java).onClickCalled("your argument here")
/* holder.btn_delete.setOnClickListener(object : View.OnClickListener() {
override fun onClick(v: View) {
deleteItemFromList(v, position)
}
})*/
}
override fun getItemCount(): Int {
return item_list.size
}
/*// confirmation dialog box to delete an unit
private fun deleteItemFromList(v: View, position: Int) {
val builder = AlertDialog.Builder(v.getContext())
//builder.setTitle("Dlete ");
builder.setMessage("Delete Item ?")
.setCancelable(false)
.setPositiveButton("CONFIRM",
DialogInterface.OnClickListener { dialog, id ->
item_list.remove(position)
notifyDataSetChanged()
})
.setNegativeButton("CANCEL", DialogInterface.OnClickListener { dialog, id -> })
builder.show()
}*/
class ViewHolder(
itemLayoutView: View) : RecyclerView.ViewHolder(itemLayoutView) {
var item_name: TextView
var txtRegistrationDoc: TextViewNormal?=null
var txtCertificate: TextViewNormal?=null
var txtFileSize: TextViewNormal?=null
var txtCreatedOn: TextViewNormal?=null
var txtModifiedOn: TextViewNormal?=null
var chkSelected: CheckBox
init {
item_name = itemLayoutView.findViewById(R.id.txt_Name)
txtRegistrationDoc = itemLayoutView.findViewById(R.id.txtRegistrationDoc)
txtCertificate = itemLayoutView.findViewById(R.id.txtCertificate)
txtFileSize = itemLayoutView.findViewById(R.id.txtFileSize)
txtCreatedOn = itemLayoutView.findViewById(R.id.txtCreatedOn)
txtModifiedOn = itemLayoutView.findViewById(R.id.txtModifiedOn)
//btn_delete = itemLayoutView.findViewById(R.id.btn_delete_unit)
chkSelected = itemLayoutView.findViewById(R.id.chk_selected)
}
}
}
//第3步,在您的活动/队中
recyclerView?.adapter = ModelAdapter(documentList,object : `in`.mobilepedia.com.gicgwaliarincubationcentre.RecyclerViewClickListener
{
override fun onItemClick(position: String) {
System.out.println("Position>>>>>"+position)
}
override fun onLongClick(position: Int) {
}
})
答案 20 :(得分:0)
您可以通过两种方式访问kotlin中的recyclerview,首先您可以在适配器中直接声明OnClickListener并在其中进行重定向。第二种方法是您可以将onclick重定向到片段/活动,其中您已设置了recycler的适配器
1
if ( substr($root_folder,0,1) == '/' ) {
$root_folder = substr($root_folder,1);
}
$zip->addFile($file, $root_folder . $file);
您可以使用的第二种方法是将您的适配器重定向到片段/活动,然后从那里重定向您的活动,而不是从适配器重定向
class CartAdapter(context: Context) : RecyclerView.Adapter<CartAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_cart, parent, false));
}
override fun getItemCount(): Int {
return 10;
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.itemView.rtbProductRating.setOnClickListener{
var iNavigation= Intent(context,MainActivity::class.java)
iNavigation.flags= Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT
context.startActivity(iNavigation)
// directly redirect your activity from adapter
}
}
class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView)
}
答案 21 :(得分:0)
我想出了一种解决方案,可以使用伴随对象和界面在单击行时打开一个活动。该活动是从主要活动中打开的,因为我必须在离开前保存列表状态。
适配器
class MyAdapter(
val dataList: List<objects.ListObject>, val listener: ItemClickListener
) : RecyclerView.Adapter<MyAdapter.ListViewHolder>()
{
companion object {
var mClickListener: ItemClickListener? = null
}
interface ItemClickListener
{
fun clickRow(position: Int)
}
override fun onBindViewHolder(holder: MyAdapter.ListViewHolder, position: Int)
{
holder.bindData(
...
)
mClickListener = listener
holder.itemView.setOnClickListener { view ->
mClickListener?.clickRow(position)
}
}
...
}
主要活动
val context = this
private lateinit var mMyAdapter: MyAdapter
fun initList()
{
mMyAdapter =
MyAdapter(dataList, object : MyAdapter.ItemClickListener
{
override fun clickRow(position: Int)
{
openActivityListItems(position)
}
}
)
}
fun openActivityListItems(position : Int)
{
recyclerViewState = mListView.getLayoutManager()?.onSaveInstanceState()
val intent = Intent(context, ListItems::class.java)
intent.putExtra("Parameter1", dataList[position].Parameter1)
intent.putExtra("Parameter2", dataList[position].Parameter2)
context.startActivity(intent)
}
答案 22 :(得分:0)
科特林
使您的适配器构造函数像这样
Alter FUNCTION Check_Weekend_And_Update_With_WeekDays
(
@date date,
@flag varchar(10) --flag to add or removed dates to get the weekdays
)
RETURNS datetime
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar date
--1 (Sunday) or 7 (Saturday)
IF DATEPART(W, @date) in (1,7)
BEGIN
IF(DATEPART(W, @date)=1) --IF sunday
BEGIN
IF(@flag='add')
BEGIN
set @date=DATEADD(DAY, 1, cast(@date as datetime))
END
ELSE
BEGIN
set @date=DATEADD(DAY, -2, cast(@date as datetime))
END
END
ELSE
BEGIN
IF(@flag='add') --If Saturday
BEGIN
set @date=DATEADD(DAY, 2, cast(@date as datetime))
END
ELSE
BEGIN
set @date=DATEADD(DAY, -1, cast(@date as datetime))
END
END
END
set @ResultVar=@date
-- Return the result of the function
RETURN @ResultVar
END
GO
在您的 onBindViewHolder 中,
// this method will return the break string without breaking word
$string = "A brown fox jump over the lazy dog";
$len_required= 10;
// user strip_tags($string) if string contain html character
if(strlen($string) > 10)
{
$break_str = explode( "\n", wordwrap( $string , $len_required));
$new_str =$break_str[0] . '...';
}
// other method is use substr
在您的片段中,实现如下所示
class ViewAdapter(
private val context: Context,
private val mListener: (DataClass) -> Unit
) :
RecyclerView.Adapter<WeekRecyclerViewAdapter.ViewHolder>() {
// Your adapter code goes here
}
答案 23 :(得分:0)
这是一种不使用接口的简单方法,只需在您的适配器中在viewholder类内创建一个init块即可。
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
init {
itemView.setOnClickListener{
//your code here---
}
}
}