RecyclerView
可以用来代替ListView
来展现大量的数据。Google在RecyclerView
中提升了性能,和更多好用的API。
简单介绍RecyclerView
使用RecyclerView
不仅需要设置adapter,还需要设计值layout manager。
- 要创建adapter,需要继承并实现
RecyclerView.Adapter
和RecyclerView.ViewHolder
。RecyclerView
专门对view holder这部分的API做了一些优化。
/**
* Created by uncle_charlie on 7/4/2016.
*/
class CategoryRecyelerAdapter(var context: Context, var categoryList: ArrayList<CategoryInfo>)
: RecyclerView.Adapter<CategoryRecyelerAdapter.CategoryViewHolder>() {
override fun onBindViewHolder(holder: CategoryViewHolder?, position: Int) {
val categoryInfo = categoryList.get(position)
Picasso.with(context).load(categoryInfo.imageUrl)
.resize(80, 80)
.into(holder?.categoryImageView)
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): CategoryViewHolder? {
val layoutView = LayoutInflater.from(context).inflate(R.layout.category_grid_item, null)
var viewHolder = CategoryViewHolder(layoutView)
return viewHolder
}
override fun getItemCount(): Int {
return categoryList.count()
}
inner class CategoryViewHolder(var categoryView: View) : RecyclerView.ViewHolder(categoryView) {
var categoryImageView: ImageView? = null;
var categoryTextView: TextView? = null;
init {
categoryImageView = categoryView.findViewById(R.id.product_imageview) as ImageView
categoryTextView = categoryView.findViewById(R.id.product_textview) as TextView
}
}
}
CategoryViewHolder
继承RecyclerView.ViewHolder
。构造函数需要一个View
类型的参数。使用这个view来获得view holder里hold的view,比如这里的image view和text view。onCreateViewHolder()
创建view holder。val layoutView = LayoutInflater.from(context).inflate(...)
,解析RecyclerView
的每一个item的layout。并把这个解析之后的view传入前面说的view holder。onBindViewHolder()
,这里就是给view holder里的view赋值,比如这里用Picasso
给image view设置图片:Picasso.with(context)...into(holder?.categoryImageView)
。getItemCount()
数据源里有多少数据。
Item的点击
但是RecyclerView
里完全没有OnItemClickListener
这个存在。不过,我们有这个:RecyclerView.OnItemTouchListener
但是RecyclerView.OnItemTouchListener
只能响应一次tap事件。当然,有了这个tap,后面就可以扩展了。
/**
* Created by uncle_charlie on 7/4/2016.
*/
class RecyclerItemClickListener(var context: Context, listener: OnItemClickListener)
: RecyclerView.OnItemTouchListener {
private var mListener: OnItemClickListener? = null
private var gestureListener: GestureDetector? = null
interface OnItemClickListener {
fun onItemClick(view: View, position: Int)
}
init {
this.mListener = listener
gestureListener = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent?): Boolean {
return true
}
})
}
override fun onTouchEvent(rv: RecyclerView?, e: MotionEvent?) {
throw UnsupportedOperationException()
}
override fun onInterceptTouchEvent(rv: RecyclerView?, e: MotionEvent?): Boolean {
var childView = rv?.findChildViewUnder(e!!.x, e!!.y)
if (childView != null && mListener != null && gestureListener!!.onTouchEvent(e)) {
mListener?.onItemClick(childView, rv!!.getChildAdapterPosition(childView))
return true
}
return false
}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
throw UnsupportedOperationException()
}
}
如何使用:
recyclerView.addOnItemTouchListener(RecyclerItemClickListener(activity,
object : RecyclerItemClickListener.OnItemClickListener {
override fun onItemClick(view: View, position: Int) {
categoryPresenter?.onItemClicked(position)
}
}))
参考: