Skip to content

Commit

Permalink
Merge pull request #17 from Rere-kt/feature/touch-helper
Browse files Browse the repository at this point in the history
Feature/touch helper
  • Loading branch information
dionep authored Feb 5, 2021
2 parents 82bd34a + 0a2d2be commit 875087d
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 38 deletions.
38 changes: 32 additions & 6 deletions rekukler/src/main/java/com/rerekt/rekukler/MultibindingsAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import java.util.Collections

open class MultiBindingAdapter(
vararg binders: ViewBinder<*, *>
Expand Down Expand Up @@ -32,13 +33,24 @@ open class MultiBindingAdapter(
override fun getItemCount() = items.size

private fun updateList(newList: List<Any>) {
DiffUtil.calculateDiff(object: DiffUtil.Callback() {
DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize() = items.size
override fun getNewListSize() = newList.size
override fun areItemsTheSame(old: Int, new: Int) =
kotlin.runCatching { bindersSet.find { it.isForItem(items[old]) }?.areItemsSame?.invoke(items[old], newList[new]) ?: false }.getOrElse { false }
kotlin.runCatching {
bindersSet.find { it.isForItem(items[old]) }?.areItemsSame?.invoke(
items[old],
newList[new]
) ?: false
}.getOrElse { false }

override fun areContentsTheSame(old: Int, new: Int) =
kotlin.runCatching { bindersSet.find { it.isForItem(items[old]) }?.areContentsSame?.invoke(items[old], newList[new]) ?: false }.getOrElse { false }
kotlin.runCatching {
bindersSet.find { it.isForItem(items[old]) }?.areContentsSame?.invoke(
items[old],
newList[new]
) ?: false
}.getOrElse { false }
}).dispatchUpdatesTo(this)
}

Expand All @@ -49,8 +61,22 @@ open class MultiBindingAdapter(
private fun getBinder(position: Int): ViewBinder<*, *> {
val item = items[position]
return checkNotNull(
value = bindersSet.find { it.isForItem(item) },
lazyMessage = { "Unnable to find ViewBinder for ${item::class}" }
)
value = bindersSet.find { it.isForItem(item) },
lazyMessage = { "Unnable to find ViewBinder for ${item::class}" }
)
}

fun moveItems(fromPosition: Int, toPosition: Int): Boolean {
if (fromPosition < toPosition) {
for (i in fromPosition until toPosition) {
Collections.swap(items.toList(), i, i + 1)
}
} else {
for (i in fromPosition downTo toPosition + 1) {
Collections.swap(items.toList(), i, i - 1)
}
}
notifyItemMoved(fromPosition, toPosition)
return true
}
}
17 changes: 1 addition & 16 deletions rekukler/src/main/java/com/rerekt/rekukler/RecyclerUtils.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.rerekt.rekukler

import java.util.*

//Function for clip the borders
internal fun clip(size: Int, start: Int, end: Int, delta: Float): Float {
val newStart = start + delta
Expand All @@ -15,17 +13,4 @@ internal fun clip(size: Int, start: Int, end: Int, delta: Float): Float {
outOfBorderEnd > 0 -> delta - outOfBorderEnd
else -> delta
}
}

fun <T>List<T>.swapListItems(fromPosition: Int, toPosition: Int): List<T> =
apply {
if (fromPosition < toPosition) {
for (i in fromPosition until toPosition) {
Collections.swap(this, i, i + 1)
}
} else {
for (i in fromPosition downTo toPosition + 1) {
Collections.swap(this, i, i - 1)
}
}
}
}
11 changes: 6 additions & 5 deletions rekukler/src/main/java/com/rerekt/rekukler/RecyclerViewDSL.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class RecyclerViewConfig(
onSwiped: (RecyclerView.ViewHolder, direction: Int) -> Unit = { _, _ -> },
onClearView: () -> Unit = {},
isCanBeOutOfBounds: Boolean = false,
onMove: (RecyclerView.ViewHolder, RecyclerView.ViewHolder) -> Boolean = { _, _ -> true }
onMove: ((RecyclerView.ViewHolder, RecyclerView.ViewHolder) -> Boolean)? = null
) = ItemTouchHelper(
object : ItemTouchHelper.Callback() {
override fun getMovementFlags(
Expand All @@ -87,6 +87,7 @@ class RecyclerViewConfig(
viewHolder: RecyclerView.ViewHolder
) = onClearView.invoke()
override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) {
viewHolder.itemView.outlineProvider = null
if (isCanBeOutOfBounds) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
} else {
Expand All @@ -96,10 +97,10 @@ class RecyclerViewConfig(
}
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean = onMove.invoke(viewHolder, target)
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean = onMove?.invoke(viewHolder, target) ?: (recyclerView.adapter as? MultiBindingAdapter)?.moveItems(viewHolder.adapterPosition, target.adapterPosition) ?: false
}
).apply { itemTouchHelper = this }

Expand Down
14 changes: 3 additions & 11 deletions sample/src/main/java/com/rerekt/sample/ui/ListFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.View
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.rerekt.rekukler.*
import com.rerekt.sample.R
import com.rerekt.sample.databinding.FragmentMainBinding
Expand Down Expand Up @@ -35,7 +34,7 @@ class ListFragment: Fragment(R.layout.fragment_main) {
private fun fillAdapterItems() {
articlesAdapter.items = buildList {
addAll(
(0..10).map {
(0..20).map {
Article(
id = it,
title = "Title#$it",
Expand All @@ -51,8 +50,7 @@ class ListFragment: Fragment(R.layout.fragment_main) {
binding.rvArticles.apply {
configure(articlesAdapter) {
linearLayout {
reverseLayout = false
orientation = LinearLayoutManager.VERTICAL
orientation = LinearLayout.VERTICAL
}
itemDecoration(
MarginDividerItemDecoration(
Expand All @@ -63,13 +61,7 @@ class ListFragment: Fragment(R.layout.fragment_main) {
dividerLineColorRes = R.color.black
)
)
itemTouchHelper { draggedHolder, target ->
getItems<Article>()
?.toList()
?.swapListItems(draggedHolder.layoutPosition, target.layoutPosition)
?.let { updateList(it) }
true
}
itemTouchHelper()
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions sample/src/main/java/com/rerekt/sample/ui/global/list/articles.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.rerekt.sample.ui.global.list

import androidx.core.content.ContextCompat
import com.rerekt.rekukler.viewBinder
import com.rerekt.sample.R
import com.rerekt.sample.databinding.ListItemBinding
Expand All @@ -20,6 +21,15 @@ fun articlesBinder(
areContentsSame = { old, new -> old == new },
) {
bindView { data ->
llContainer.setBackgroundColor(
ContextCompat.getColor(
itemView.context,
if (position % 2 == 0)
android.R.color.holo_red_dark
else
android.R.color.holo_green_dark
)
)
tvTitle.text = data.title
tvDescription.text = data.description
tvPosition.text = getString(R.string.position, position)
Expand Down
1 change: 1 addition & 0 deletions sample/src/main/res/layout/list_item.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/ll_container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
Expand Down

0 comments on commit 875087d

Please sign in to comment.