Both these works
class PosterViewHolder(parentView: ViewGroup) :
SmartViewHolder<MovieModel>(parentView, R.layout.poster_item)
class PosterViewHolder(parentView: ViewGroup) :
SmartViewHolder<MovieModel>(
LayoutInflater.from(parentView.context)
.inflate(R.layout.poster_item, parentView, false)
)
class PosterViewHolder(parentView: ViewGroup) :
SmartViewHolder<MovieModel>(
LayoutInflater.from(parentView.context)
.inflate(R.layout.poster_item, parentView, false)
)
With smart-recycler-adapter-viewevent extension library
dependencies {
// ViewEvent click listeners, selection, swipe dismiss and drag & drop
implementation 'io.github.manneohlund:smart-recycler-adapter-viewevent:X.Y.Z'
}
.add(OnClickEventListener { event: ViewEvent.OnClick ->
// Handle event
})
.addViewEventListener(onViewEventListener { view, viewEventId, position ->
// Handle event
})
or
.addViewEventListener(object : OnViewEventListener {
override fun onViewEvent(view: View, viewEventId: ViewEventId, position: Position) {
// Handle event
}
})
.add(OnCustomViewEventListener { event ->
// Handle event
})
open class SimpleCustomViewEventListenerViewHolder(parentView: ViewGroup) :
SmartViewHolder<Int>(parentView, R.layout.simple_item),
CustomViewEventListenerHolder,
SmartAdapterHolder {
override lateinit var customViewEventListener: (ViewEvent) -> Unit
override var smartRecyclerAdapter: SmartRecyclerAdapter? = null
init {
itemView.setOnClickListener { view ->
customViewEventListener.invoke(
ViewEvent.OnClick(smartRecyclerAdapter!!, this, adapterPosition, view)
)
}
}
}
// SmartRecyclerAdapter
.addViewEventListener(onViewEventListener { view, viewEventId, position ->
// Handle event
})
// ViewHolder
open class SimpleItemViewHolder(parentView: ViewGroup) : SmartViewHolder<Int>(
LayoutInflater.from(parentView.context).inflate(R.layout.simple_item, parentView, false)
), ViewEventListenerHolder {
override lateinit var viewEventListener: OnViewEventListener
init {
itemView.setOnClickListener { view ->
viewEventListener.onViewEvent(view, R.id.action_play_movie, adapterPosition)
}
}
}
As of smart-recycler-adapter:v5.0.0
static nested adapter mapping have been removed from SmartRecyclerAdapter
and is added in this extension library smart-recycler-adapter-nestedadapter
.
Default binder in nestedadapter is SmartNestedAdapterBinder
implements SmartViewHolderBinder
for basic view holder mapping functionality.
SmartRecyclerAdapter
will hold the SmartNestedAdapterBinder
references and call the default implemented interfaces OnCreateViewHolderListener
, OnBindViewHolderListener
, OnViewRecycledListener
on ViewHolder lifecycle stages.
SmartViewHolder
subclasses must implement SmartNestedRecyclerViewHolder
in order for SmartNestedAdapterBinder
to get the target recyclerView.
How does it work? 👇
Sample uses kotlin synthetic view property import!
class NestedRecyclerViewHolder(parentView: ViewGroup) :
SmartViewHolder<MovieCategory>(parentView, R.layout.nested_recycler_view),
SmartNestedRecyclerViewHolder {
override val recyclerView: RecyclerView = itemView.nestedRecyclerView
init {
itemView.nestedRecyclerView.apply {
layoutManager = LinearLayoutManager(context, HORIZONTAL, false)
isNestedScrollingEnabled = false
setHasFixedSize(true)
}
}
override fun bind(item: MovieCategory) {
itemView.title.text = item.title
}
}
SmartNestedAdapterBinder
will only target NestedRecyclerViewHolder
.
Supply a SmartAdapterBuilder
or SmartEndlessScrollAdapterBuilder
that will be build a new nested adapter for each NestedRecyclerViewHolder
.
SmartRecyclerAdapter
.items(items)
.add(
SmartNestedAdapterBinder(
viewHolderType = NestedRecyclerViewHolder::class,
smartRecyclerAdapterBuilder = SmartRecyclerAdapter.empty()
.map(MovieModel::class, ThumbViewHolder::class)
.add(OnClickEventListener { event: ViewEvent.OnClick ->
// Handle nested adapter item click event
})
)
)
.add(OnClickEventListener(NestedRecyclerViewHolder::class, R.id.more) {
// Handle parent adapter click event
})
.into(recyclerView)
New in SmartRecyclerAdapter
v2.0.0 is support for statically resolved nested recycler adapter.
Now you can easily build complex nested adapters without hustle and have full control of the adapter in your view controlling Fragment
or Activity
.
Use the new create()
method instead of the into(recyclerView)
to create just the SmartRecyclerAdapter
then set the adapter to the recycler view in your ViewHolder
.
Just implement the SmartAdapterHolder
interface in your ViewHolder
and SmartRecyclerAdapter
will handle the mapping.
val myWatchListSmartMovieAdapter: SmartRecyclerAdapter = SmartRecyclerAdapter
.items(myWatchListItems)
.map(MovieModel::class, ThumbViewHolder::class)
.addViewEventListener(onItemClickListener { view, viewEventId, position -> playMovie() })
.create()
SmartRecyclerAdapter
.items(items)
.map(MoviePosterModel::class, PosterViewHolder::class)
.map(MyWatchListModel::class, MyWatchListViewHolder::class)
.map(MyWatchListViewHolder::class, myWatchListSmartMovieAdapter)
.into(recyclerView)
class MyWatchListViewHolder :
SmartViewHolder<MyWatchListModel>,
SmartAdapterHolder {
override var smartRecyclerAdapter: SmartRecyclerAdapter? = null
set(value) {
field = value
recyclerView.layoutManager = LinearLayoutManager(recyclerView.context, HORIZONTAL, false)
recyclerView.adapter = value
}
override fun bind(myWatchListModel: MyWatchListModel) {
// bind model data to views
}
override fun unbind() {
// optional unbinding of view data model
}
}
.add(AutoDragAndDropBinder(longPressDragEnabled = true) { event: ViewEvent.OnItemMoved ->
// Handle drag event
})
.addExtensionBuilder(DragAndDropExtensionBuilder(AutoDragAndDropExtension()).apply {
longPressDragEnabled = true
onItemMovedListener = { oldViewHolder, targetViewHolder ->
// Handle drag event
}
})
.add(SwipeRemoveItemBinder(ItemTouchHelper.LEFT) {
// Remove item from SmartRecyclerAdapter data set
smartRecyclerAdapter.removeItem(it.viewHolder.adapterPosition)
})
.addExtensionBuilder(SwipeExtensionBuilder(SwipeRemoveItemExtension()).apply {
swipeFlags = ItemTouchHelper.LEFT
onItemSwipedListener = { viewHolder, direction ->
showToast(viewHolder, direction)
// Remove item from SmartRecyclerAdapter data set
smartRecyclerAdapter.removeItem(viewHolder.adapterPosition)
}
})
With smart-recycler-adapter-diffutil extension library
dependencies {
implementation 'io.github.manneohlund:smart-recycler-adapter-diffutil:X.Y.Z'
}
No DiffUtilExtensionBuilder
needed anymore.
SmartRecyclerAdapter
.items(items)
.map(Integer::class, SimpleItemViewHolder::class)
.add(SimpleDiffUtilExtension(predicate))
.into(recyclerView)
val adapter = SmartRecyclerAdapter
.items(items)
.map(Integer::class, SimpleItemViewHolder::class)
.into(recyclerView)
diffUtilExtension = DiffUtilExtensionBuilder().apply {
smartRecyclerAdapter = adapter
diffPredicate = predicate
}.build()
Variable parameter overloading with many different addViewEventListener
calls.
.addViewEventListener(
MovieViewHolder.class,
R.id.event_on_click,
(view, viewEventId, position) -> playMovie())
class MovieViewHolder
extends SmartAutoEventViewHolder<MyWatchListModel>
implements SmartAdapterHolder {}
Create an OnItemClickListener
for MovieViewHolder.
SmartAutoEvent
implementations has been removed so no need for ex MovieViewHolder
to extend SmartAutoEventViewHolder
.
interface OnMovieItemClickListener extends OnItemClickListener {
@NonNull
@Override
default Class<? extends SmartViewHolder> getViewHolderType() {
return MovieViewHolder.class;
}
}
Add listener to the SmartAdapterBuilder.
.addViewEventListener((OnMovieItemClickListener) (view, viewEventId, position) -> playMovie())
In Kotlin the interface properties are overridden instead of default methods as in java.
SmartViewHolderType
is a typealias of KClass<out SmartViewHolder<*>>
.
interface OnMovieItemClickListener : OnItemClickListener {
override val viewHolderType: SmartViewHolderType
get() = MovieViewHolder::class
}
.addViewEventListener(object : OnMovieItemClickListener {
override fun onViewEvent(view: View, viewEventId: ViewEventId, position: Position) {
playMovie()
}
})
Kotlin has no SAM constructor for interface as java so lambda resolving is not working yet.
However you can do lambda call to eg OnItemClickListener
extensions like this:
inline fun onMovieItemClickListener(crossinline viewEvent: (
view: View,
viewEventId: ViewEventId,
position: Position) -> Unit) = object : OnItemClickListener {
override fun onViewEvent(view: View, viewEventId: ViewEventId, position: Position) {
viewEvent(view, viewEventId, position)
}
}
.addViewEventListener(onMovieItemClickListener { view, viewEventId, position -> playMovie() })