Skip to content

Instantly share code, notes, and snippets.

@mahdi-malv
Last active July 6, 2018 17:44
Show Gist options
  • Save mahdi-malv/81aacb04ecd5826e95519b5519e395bf to your computer and use it in GitHub Desktop.
Save mahdi-malv/81aacb04ecd5826e95519b5519e395bf to your computer and use it in GitHub Desktop.
RecyclerView Easy Adapting [refer to MainActivity.kt to see usage]
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class ListClick implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public ListClick(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildAdapterPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
/**
* to Add support for extension methods you must use Java 8 or above
* to do that Add this block to `build.gradle(Module: your module like app)` inside android block
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
* This feature makes onLongClick optional
*/
default void onLongClick(View view, int position) {}
}
}
import android.content.Context
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
/**
* Test of fast recyclerView adapter
* usage:
* ListConfig<String>(context).load(List<String>).holder{//holder init//}.layout(R.layout.li).bindViewHolder{//bindViewHolder//}.layoutManager(list)
*/
class ListConfig<Item>(var c: Context) {
lateinit var set: List<Item>
var resId = 0
lateinit var bindViewHolder: (VH, Int, Item) -> Unit
lateinit var list: RecyclerView
fun with(list: RecyclerView): ListConfig<Item> {
this.list = list
return this
}
fun load(set: List<Item>): ListConfig<Item> {
//we have list
this.set = set
return this
}
fun layout(resId: Int): ListConfig<Item> {
//we have resId
this.resId = resId
return this
}
fun bindViewHolder(bindFun: (VH, Int, Item) -> Unit): ListConfig<Item> {
this.bindViewHolder = bindFun
//set it onRecyclerView
list.layoutManager = LinearLayoutManager(c)
list.setHasFixedSize(true)
list.adapter = Adapter(set, resId, bindViewHolder)
return this
}
fun layoutManager(lm: RecyclerView.LayoutManager): ListConfig<Item> {
//set it onRecyclerView
list.layoutManager = lm
list.adapter = Adapter(set, resId, bindViewHolder)
return this
}
fun onItemClick(click: (View?, Int)->Unit, longClick: (View?, Int)-> Unit) {
list.addOnItemTouchListener(ListClick(c, list,
object : ListClick.ClickListener{
override fun onClick(view: View?, position: Int) = click(view, position)
override fun onLongClick(view: View?, position: Int) = longClick(view, position)
}))
}
fun onItemClick(click: (View?, Int)->Unit) =
list.addOnItemTouchListener(ListClick(c, list, ListClick.ClickListener { view, position -> click(view, position) }))
inner class Adapter(val set: List<Item>, private val layout: Int,
private val bindFun: (VH, Int, Item) -> Unit) :
RecyclerView.Adapter<VH>() {
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int) =
VH(LayoutInflater.from(c).inflate(layout, parent, false))
override fun getItemCount() = set.size
override fun onBindViewHolder(holder: VH, position: Int) =
bindFun(holder, position, set[position])
}
inner class VH(item: View) : RecyclerView.ViewHolder(item)
}
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar
import android.view.View
import android.widget.TextView
import android.widget.Toast
import ir.malv.list.ListConfig
import ir.malv.test07_01_2018.R
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar) as Toolbar)
title = "East adapting"
init()
}
private fun init() {
val set = listOf("Item1", "Item2" /*, ...*/)
ListConfig<String>(this) // Context as param and ViewHolder model as Generic param
.with(list) // recyclerView
.load(set) // list of Models (here it's a string)
.layout(R.layout.li_1) // list item xml
.bindViewHolder(this::listOnBind) // onBindViewHolder and ViewHolder itself
.layoutManager(GridLayoutManager(this, 2)) // Optional LayoutManager (Linear by default)
.onItemClick(this::listOnClick) // Click Listener
}
private fun listOnBind(holder: RecyclerView.ViewHolder, p: Int, s: String) {
(holder.itemView.findViewById(R.id.text) as TextView).text = s
//since the ViewHolder is empty you should create views here and use them
}
private fun listOnClick(v: View?, position: Int) {
//Do something with the clicked View and it's position
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment