From 20f26078ec9185db9285f860b4f9a49a85707a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:27:08 +0200 Subject: [PATCH 01/20] Add SmartEndlessScrollAdapterBuilder and fix multiple SmartRecyclerAdapter creation from a single SmartAdapterBuilder --- .../smartadapter/SmartAdapterBuilder.kt | 29 ++++++++++++++----- .../SmartEndlessScrollAdapterBuilder.kt | 8 +++++ .../SmartEndlessScrollRecyclerAdapter.kt | 9 ++---- .../smartadapter/SmartRecyclerAdapter.kt | 8 ++--- 4 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollAdapterBuilder.kt diff --git a/smartadapter/src/main/kotlin/smartadapter/SmartAdapterBuilder.kt b/smartadapter/src/main/kotlin/smartadapter/SmartAdapterBuilder.kt index 76052c0..a741033 100644 --- a/smartadapter/src/main/kotlin/smartadapter/SmartAdapterBuilder.kt +++ b/smartadapter/src/main/kotlin/smartadapter/SmartAdapterBuilder.kt @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import smartadapter.binders.ItemTouchBinder import smartadapter.binders.SmartRecyclerAdapterExtension +import smartadapter.internal.extension.isMutable import smartadapter.internal.extension.name import smartadapter.viewholder.SmartAdapterHolder import smartadapter.widget.ViewTypeResolver @@ -19,19 +20,31 @@ import kotlin.reflect.KClass /** * Builder for [SmartRecyclerAdapter]. */ -class SmartAdapterBuilder internal constructor(private val smartRecyclerAdapter: SmartRecyclerAdapter) { - private var layoutManager: RecyclerView.LayoutManager? = null - private var viewTypeResolver: ViewTypeResolver? = null - private val viewHolderMapper = HashMap() - private val smartRecyclerAdapterMapper = HashMap() - private val viewHolderBinders = mutableListOf() - private val smartRecyclerAdapterExtensions = mutableMapOf() +open class SmartAdapterBuilder { + internal var items: MutableList = mutableListOf() + internal var layoutManager: RecyclerView.LayoutManager? = null + internal var viewTypeResolver: ViewTypeResolver? = null + internal val viewHolderMapper = HashMap() + @Deprecated("Use nested adapter") + internal val smartRecyclerAdapterMapper = HashMap() + internal val viewHolderBinders = mutableListOf() + internal val smartRecyclerAdapterExtensions = mutableMapOf() + + internal open fun getSmartRecyclerAdapter() = SmartRecyclerAdapter(items.let { + (if (it.isMutable()) it else it.toMutableList()) + }) fun map(itemType: KClass<*>, viewHolderType: SmartViewHolderType): SmartAdapterBuilder { viewHolderMapper[itemType.name] = viewHolderType return this } + fun setItems(items: List): SmartAdapterBuilder { + this.items = (if (items.isMutable()) items else items.toMutableList()) as MutableList + return this + } + + @Deprecated("Use nested adapter") fun map(viewHolderType: SmartViewHolderType, smartRecyclerAdapter: SmartRecyclerAdapter): SmartAdapterBuilder { smartRecyclerAdapterMapper[viewHolderType] = smartRecyclerAdapter return this @@ -78,6 +91,7 @@ class SmartAdapterBuilder internal constructor(private val smartRecyclerAdapter: @Suppress("UNCHECKED_CAST") fun into(recyclerView: RecyclerView): T { + val smartRecyclerAdapter = getSmartRecyclerAdapter() smartRecyclerAdapter.setDataTypeViewHolderMapper(viewHolderMapper) smartRecyclerAdapter.setSmartRecyclerAdapterMapper(smartRecyclerAdapterMapper) smartRecyclerAdapter.viewTypeResolver = viewTypeResolver @@ -96,6 +110,7 @@ class SmartAdapterBuilder internal constructor(private val smartRecyclerAdapter: @Suppress("UNCHECKED_CAST") fun create(): T { + val smartRecyclerAdapter = getSmartRecyclerAdapter() smartRecyclerAdapter.setDataTypeViewHolderMapper(viewHolderMapper) smartRecyclerAdapter.setSmartRecyclerAdapterMapper(smartRecyclerAdapterMapper) smartRecyclerAdapter.viewTypeResolver = viewTypeResolver diff --git a/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollAdapterBuilder.kt b/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollAdapterBuilder.kt new file mode 100644 index 0000000..b288e4b --- /dev/null +++ b/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollAdapterBuilder.kt @@ -0,0 +1,8 @@ +package smartadapter + +class SmartEndlessScrollAdapterBuilder : SmartAdapterBuilder() { + + override fun getSmartRecyclerAdapter(): SmartRecyclerAdapter { + return SmartEndlessScrollRecyclerAdapter(items) + } +} diff --git a/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollRecyclerAdapter.kt b/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollRecyclerAdapter.kt index 39001e3..b7a32b7 100644 --- a/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollRecyclerAdapter.kt +++ b/smartadapter/src/main/kotlin/smartadapter/SmartEndlessScrollRecyclerAdapter.kt @@ -8,7 +8,6 @@ package smartadapter import android.view.ViewGroup import androidx.annotation.LayoutRes import io.github.manneohlund.smartrecycleradapter.R -import smartadapter.internal.extension.isMutable import smartadapter.listener.OnLoadMoreListener import smartadapter.viewholder.LoadMoreViewHolder import smartadapter.viewholder.SmartViewHolder @@ -82,16 +81,12 @@ class SmartEndlessScrollRecyclerAdapter(items: MutableList) : SmartRecycler * Builder of [SmartRecyclerAdapter] for easy implementation. * @return SmartAdapterBuilder */ - fun items(items: List<*>): SmartAdapterBuilder = - SmartAdapterBuilder(SmartEndlessScrollRecyclerAdapter(items.let { - (if (it.isMutable()) it else it.toMutableList()) as MutableList - })) + fun items(items: List): SmartAdapterBuilder = SmartEndlessScrollAdapterBuilder().setItems(items) /** * Builder of [SmartRecyclerAdapter] for easy implementation. * @return SmartAdapterBuilder */ - fun empty(): SmartAdapterBuilder = - SmartAdapterBuilder(SmartEndlessScrollRecyclerAdapter(mutableListOf())) + fun empty(): SmartAdapterBuilder = SmartEndlessScrollAdapterBuilder() } } diff --git a/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt b/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt index 180cb26..8ac17a7 100644 --- a/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt +++ b/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt @@ -314,16 +314,12 @@ open class SmartRecyclerAdapter * Builder of [SmartRecyclerAdapter] for easy implementation. * @return SmartAdapterBuilder */ - fun items(items: List<*>): SmartAdapterBuilder = - SmartAdapterBuilder(SmartRecyclerAdapter(items.let { - (if (it.isMutable()) it else it.toMutableList()) as MutableList - })) + fun items(items: List): SmartAdapterBuilder = SmartAdapterBuilder().setItems(items) /** * Builder of [SmartRecyclerAdapter] for easy implementation. * @return SmartAdapterBuilder */ - fun empty(): SmartAdapterBuilder = - SmartAdapterBuilder(SmartRecyclerAdapter(mutableListOf())) + fun empty(): SmartAdapterBuilder = SmartAdapterBuilder() } } From 0bae054da46cbf5f9968deb2a6714e9d600c2baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:36:38 +0200 Subject: [PATCH 02/20] Fix viewHolderType check to isInstanceOf instead of 1:1 check for viewHolderTypes in SmartRecyclerAdapter --- .../src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt b/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt index 8ac17a7..8d336df 100644 --- a/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt +++ b/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt @@ -8,7 +8,6 @@ package smartadapter import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import smartadapter.binders.SmartRecyclerAdapterExtension -import smartadapter.internal.extension.isMutable import smartadapter.internal.mapper.ViewHolderMapper import smartadapter.listener.OnBindViewHolderListener import smartadapter.listener.OnCreateViewHolderListener @@ -95,7 +94,7 @@ open class SmartRecyclerAdapter override fun onBindViewHolder(smartViewHolder: SmartViewHolder, position: Position) { smartViewHolder.bind(items[position]) viewHolderBinders.forEach { - if ((it.viewHolderType == SmartViewHolder::class || it.viewHolderType == smartViewHolder::class) && it is OnBindViewHolderListener) { + if ((it.viewHolderType == SmartViewHolder::class || it.viewHolderType.isInstance(smartViewHolder)) && it is OnBindViewHolderListener) { it.onBindViewHolder(this, smartViewHolder) } } @@ -116,7 +115,7 @@ open class SmartRecyclerAdapter super.onViewRecycled(smartViewHolder) smartViewHolder.unbind() viewHolderBinders.forEach { - if ((it.viewHolderType == SmartViewHolder::class || it.viewHolderType == smartViewHolder::class) && it is OnViewRecycledListener) { + if ((it.viewHolderType == SmartViewHolder::class || it.viewHolderType.isInstance(smartViewHolder)) && it is OnViewRecycledListener) { it.onViewRecycled(this, smartViewHolder) } } From 1416f79336dbe9d9749c8edff47490c0b05aeccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:37:56 +0200 Subject: [PATCH 03/20] Deprecate smartRecyclerAdapterMapper in SmartRecyclerAdapter, use smart-recycler-adapter-nestedadapter --- .../src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt | 1 + .../kotlin/smartadapter/internal/mapper/ViewHolderMapper.kt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt b/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt index 8d336df..dfa7b92 100644 --- a/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt +++ b/smartadapter/src/main/kotlin/smartadapter/SmartRecyclerAdapter.kt @@ -294,6 +294,7 @@ open class SmartRecyclerAdapter viewHolderMapper.setDataTypeViewHolderMapper(dataTypeViewHolderMapper) } + @Deprecated("Use nested adapter") internal fun setSmartRecyclerAdapterMapper(smartRecyclerAdapterMapper: HashMap) { viewHolderMapper.setSmartRecyclerAdapterMapper(smartRecyclerAdapterMapper) } diff --git a/smartadapter/src/main/kotlin/smartadapter/internal/mapper/ViewHolderMapper.kt b/smartadapter/src/main/kotlin/smartadapter/internal/mapper/ViewHolderMapper.kt index c093567..d4ed064 100644 --- a/smartadapter/src/main/kotlin/smartadapter/internal/mapper/ViewHolderMapper.kt +++ b/smartadapter/src/main/kotlin/smartadapter/internal/mapper/ViewHolderMapper.kt @@ -29,6 +29,7 @@ class ViewHolderMapper { private val viewTypeMapper = SparseArray() private val viewHolderConstructorMapper = ViewHolderConstructorMapper() private var dataTypeViewHolderMapper = HashMap() + @Deprecated("Use nested adapter") private var smartRecyclerAdapterMapper = HashMap() /** @@ -84,6 +85,7 @@ class ViewHolderMapper { throw RuntimeException(String.format("Could not invoke constructor for '%s', '%s'", smartViewHolderClass!!.toString(), e.message), e) } + // TODO Remove this val smartRecyclerAdapter = smartRecyclerAdapterMapper[viewHolder::class] if (viewHolder is SmartAdapterHolder && smartRecyclerAdapter != null) { viewHolder.smartRecyclerAdapter = smartRecyclerAdapter @@ -102,6 +104,7 @@ class ViewHolderMapper { viewHolderConstructorMapper.add(dataTypeViewHolderMapper.values) } + @Deprecated("Use nested adapter") fun setSmartRecyclerAdapterMapper(smartRecyclerAdapterMapper: HashMap) { this.smartRecyclerAdapterMapper = smartRecyclerAdapterMapper } From 3091888cc82fc2e34fe7e0a61c94577e8d159807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:40:35 +0200 Subject: [PATCH 04/20] Fix dragFlags for DragAndDropEventBinder depending on recyclerView is LinearLayoutManager in viewevent module --- .../viewevent/dragdrop/BasicDragAndDropBinder.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/BasicDragAndDropBinder.kt b/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/BasicDragAndDropBinder.kt index e1156e0..95a6414 100644 --- a/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/BasicDragAndDropBinder.kt +++ b/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/BasicDragAndDropBinder.kt @@ -8,6 +8,7 @@ package smartadapter.viewevent.dragdrop import android.annotation.SuppressLint import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import smartadapter.SmartRecyclerAdapter import smartadapter.SmartViewHolderType @@ -70,13 +71,15 @@ open class BasicDragAndDropBinder( @SuppressLint("ClickableViewAccessibility") override fun setupDragAndDrop(recyclerView: RecyclerView) { if (dragFlags == 0) { - val gridDragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT - val linearDragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN - dragFlags = if (recyclerView.layoutManager is GridLayoutManager) { - gridDragFlags + ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.START or ItemTouchHelper.END } else { - linearDragFlags + val linearLayoutManager = recyclerView.layoutManager as LinearLayoutManager + if (linearLayoutManager.orientation == LinearLayoutManager.HORIZONTAL) { + ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT + } else { + ItemTouchHelper.UP or ItemTouchHelper.DOWN + } } } } From e5637c5c54464bbd69560d8fcfcf769049c0c4a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:41:51 +0200 Subject: [PATCH 05/20] Fix potential crash in viewevent module on collections item position swap --- .../viewevent/dragdrop/AutoDragAndDropBinder.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/AutoDragAndDropBinder.kt b/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/AutoDragAndDropBinder.kt index c0bbeb1..da3182c 100644 --- a/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/AutoDragAndDropBinder.kt +++ b/extensions/viewevent/src/main/kotlin/smartadapter/viewevent/dragdrop/AutoDragAndDropBinder.kt @@ -16,6 +16,7 @@ import smartadapter.viewevent.model.ViewEvent import smartadapter.viewholder.DraggableViewHolder import smartadapter.viewholder.SmartAdapterHolder import smartadapter.viewholder.SmartViewHolder +import java.util.Collections import java.util.HashSet /** @@ -45,9 +46,10 @@ class AutoDragAndDropBinder( val oldPosition = viewHolder.adapterPosition val newPosition = target.adapterPosition with (smartRecyclerAdapter) { - val targetItem = getItems()[oldPosition] - getItems().removeAt(oldPosition) - getItems().add(newPosition, targetItem) + //val targetItem = getItems()[oldPosition] + //getItems().removeAt(oldPosition) + //getItems().add(newPosition, targetItem) + Collections.swap(getItems(), oldPosition, newPosition) notifyItemMoved(oldPosition, newPosition) } } From 69db5ca55df1440f39000884423ee81543fc51e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:44:12 +0200 Subject: [PATCH 06/20] Fix EOF new line gradle file for viewevent module --- extensions/viewevent/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/viewevent/build.gradle b/extensions/viewevent/build.gradle index fa2df00..1d00dfe 100644 --- a/extensions/viewevent/build.gradle +++ b/extensions/viewevent/build.gradle @@ -71,4 +71,4 @@ if (project.rootProject.file('local.properties').exists()) { apply from: '../../maven-local-publish.gradle' apply from: '../../maven-release-config.gradle' apply from: '../../maven-release-script.gradle' -} \ No newline at end of file +} From 7c40a8994757b42c77c43ea643f63913df36d7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 12:45:32 +0200 Subject: [PATCH 07/20] Add gitignore for Android Studio shelf functionality --- .idea/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .idea/.gitignore diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..4b92295 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/shelf/ From a2fec3d7f0782be34a402742d827cabde1b8aa32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manne=20=C3=96hlund?= Date: Thu, 8 Oct 2020 13:19:11 +0200 Subject: [PATCH 08/20] Add initital smart-recycler-adapter-nestedadapter v1.0.0-alpha01 library --- .idea/gradle.xml | 1 + .idea/modules.xml | 1 + extensions/nestedadapter/.gitignore | 83 +++++++++++ extensions/nestedadapter/CHANGELOG.md | 8 ++ extensions/nestedadapter/README.md | 134 ++++++++++++++++++ extensions/nestedadapter/build.gradle | 72 ++++++++++ extensions/nestedadapter/consumer-rules.pro | 0 extensions/nestedadapter/proguard-rules.pro | 21 +++ .../nestedadapter/ExampleInstrumentedTest.kt | 22 +++ .../src/main/AndroidManifest.xml | 1 + .../nestedadapter/SmartNestedAdapterBinder.kt | 72 ++++++++++ .../nestedadapter/SmartNestedItem.kt | 6 + .../SmartNestedRecyclerViewHolder.kt | 8 ++ .../nestedadapter/ExampleUnitTest.kt | 16 +++ settings.gradle | 1 + 15 files changed, 446 insertions(+) create mode 100644 extensions/nestedadapter/.gitignore create mode 100644 extensions/nestedadapter/CHANGELOG.md create mode 100644 extensions/nestedadapter/README.md create mode 100644 extensions/nestedadapter/build.gradle create mode 100644 extensions/nestedadapter/consumer-rules.pro create mode 100644 extensions/nestedadapter/proguard-rules.pro create mode 100644 extensions/nestedadapter/src/androidTest/java/smartadapter/nestedadapter/ExampleInstrumentedTest.kt create mode 100644 extensions/nestedadapter/src/main/AndroidManifest.xml create mode 100644 extensions/nestedadapter/src/main/kotlin/smartadapter/nestedadapter/SmartNestedAdapterBinder.kt create mode 100644 extensions/nestedadapter/src/main/kotlin/smartadapter/nestedadapter/SmartNestedItem.kt create mode 100644 extensions/nestedadapter/src/main/kotlin/smartadapter/nestedadapter/SmartNestedRecyclerViewHolder.kt create mode 100644 extensions/nestedadapter/src/test/java/smartadapter/nestedadapter/ExampleUnitTest.kt diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 9971704..3330953 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -13,6 +13,7 @@