From a8923dc6595785ee82e827ff5702440cbf3e3598 Mon Sep 17 00:00:00 2001 From: Belin Wu Date: Fri, 25 Jan 2019 14:04:44 +0800 Subject: [PATCH 1/3] Support async differ, etc - Recode to two library modules: core and paging. - Let `ModularAdapter` generalized. - Intro `AsyncDiffer` and its implementations: `NonAsyncDiffer`, `ListAsyncDiffer` and `PagedAsyncDiffer`. --- build.gradle | 5 +- {library => core}/.gitignore | 0 {library => core}/build.gradle | 43 +++--- {library => core}/proguard-rules.pro | 0 .../modapter/ExampleInstrumentedTest.java | 0 .../src/main/AndroidManifest.xml | 2 +- .../com/samelody/modapter/AbstractItem.java | 0 .../samelody/modapter/AdapterDelegate.java | 69 ++++++---- .../com/samelody/modapter/AdapterItem.java | 0 .../com/samelody/modapter/ItemManager.java | 50 ++++--- .../com/samelody/modapter/ItemMetadata.java | 0 .../com/samelody/modapter/ItemViewHolder.java | 0 .../com/samelody/modapter/ModularAdapter.java | 125 ++++++++++++++++++ .../samelody/modapter/differ/AsyncDiffer.java | 22 +++ .../modapter/differ/ListAsyncDiffer.java | 58 ++++++++ .../modapter/differ/NonAsyncDiffer.java | 48 +++++++ .../src/main/res/values/strings.xml | 0 .../samelody/modapter/ExampleUnitTest.java | 0 .../com/samelody/modapter/ModularAdapter.java | 68 ---------- paging/.gitignore | 2 + paging/build.gradle | 53 ++++++++ paging/proguard-rules.pro | 21 +++ .../modapter/ExampleInstrumentedTest.java | 26 ++++ paging/src/main/AndroidManifest.xml | 2 + .../modapter/differ/PagedAsyncDiffer.java | 66 +++++++++ .../com/samelody/modapter/package-info.java | 1 + paging/src/main/res/values/strings.xml | 3 + .../samelody/modapter/ExampleUnitTest.java | 17 +++ sample/build.gradle | 7 +- .../samples/modapter/MainActivity.java | 26 ++-- settings.gradle | 2 +- 31 files changed, 562 insertions(+), 154 deletions(-) rename {library => core}/.gitignore (100%) rename {library => core}/build.gradle (89%) rename {library => core}/proguard-rules.pro (100%) rename {library => core}/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java (100%) rename {library => core}/src/main/AndroidManifest.xml (61%) rename {library => core}/src/main/java/com/samelody/modapter/AbstractItem.java (100%) rename {library => core}/src/main/java/com/samelody/modapter/AdapterDelegate.java (76%) mode change 100755 => 100644 rename {library => core}/src/main/java/com/samelody/modapter/AdapterItem.java (100%) rename {library => core}/src/main/java/com/samelody/modapter/ItemManager.java (60%) rename {library => core}/src/main/java/com/samelody/modapter/ItemMetadata.java (100%) rename {library => core}/src/main/java/com/samelody/modapter/ItemViewHolder.java (100%) mode change 100755 => 100644 create mode 100644 core/src/main/java/com/samelody/modapter/ModularAdapter.java create mode 100644 core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java create mode 100644 core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java create mode 100644 core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java rename {library => core}/src/main/res/values/strings.xml (100%) rename {library => core}/src/test/java/com/samelody/modapter/ExampleUnitTest.java (100%) delete mode 100644 library/src/main/java/com/samelody/modapter/ModularAdapter.java create mode 100644 paging/.gitignore create mode 100644 paging/build.gradle create mode 100644 paging/proguard-rules.pro create mode 100644 paging/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java create mode 100644 paging/src/main/AndroidManifest.xml create mode 100644 paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java create mode 100644 paging/src/main/java/com/samelody/modapter/package-info.java create mode 100644 paging/src/main/res/values/strings.xml create mode 100644 paging/src/test/java/com/samelody/modapter/ExampleUnitTest.java diff --git a/build.gradle b/build.gradle index e67f240..302e278 100644 --- a/build.gradle +++ b/build.gradle @@ -4,16 +4,13 @@ buildscript { def deps = [:] ext.deps = deps - deps.libVersionCode = 1 - deps.libVersionName = "0.1.0" - deps.demoVersionCode = 1 - deps.demoVersionName = "0.1.0" deps.compileSdk = 28 deps.targetSdk = 28 deps.minSdk = 15 deps.appcompat = "com.android.support:appcompat-v7:28.0.0" deps.recyclerview = "com.android.support:recyclerview-v7:28.0.0" + deps.paging = "android.arch.paging:runtime:1.0.1" deps.constraintlayout = "com.android.support.constraint:constraint-layout:1.1.3" deps.junit = "junit:junit:4.12" deps.test = "com.android.support.test:runner:1.0.2" diff --git a/library/.gitignore b/core/.gitignore similarity index 100% rename from library/.gitignore rename to core/.gitignore diff --git a/library/build.gradle b/core/build.gradle similarity index 89% rename from library/build.gradle rename to core/build.gradle index ab178e7..6bbf8ed 100644 --- a/library/build.gradle +++ b/core/build.gradle @@ -1,12 +1,32 @@ apply plugin: 'com.android.library' +ext.pubspec = [:] + +pubspec.packaging = 'aar' +pubspec.groupId = 'com.samelody.modapter' +pubspec.artifactId = 'modapter-core' +pubspec.repo = 'maven' +pubspec.name = 'Modapter' +pubspec.description = 'Modular adapter for Android RecyclerView.' +pubspec.version = "0.2.0-alpha1" +pubspec.versionCode = 2 +pubspec.url = 'https://github.com/samelody/modapter' +pubspec.gitUrl = 'https://github.com/samelody/modapter.git' +pubspec.issueUrl = 'https://github.com/samelody/modapter/issues' +pubspec.developerId = 'belinwu' +pubspec.developerName = 'Belin Wu' +pubspec.developerEmail = 'belinwu@qq.com' +pubspec.licenseName = 'Apache License 2.0' +pubspec.licenseUrl = 'https://raw.githubusercontent.com/samelody/modapter/master/LICENSE' +pubspec.licenses = ["Apache-2.0"] + android { compileSdkVersion deps.compileSdk defaultConfig { minSdkVersion deps.minSdk targetSdkVersion deps.targetSdk - versionCode deps.libVersionCode - versionName deps.libVersionName + versionCode pubspec.versionCode + versionName pubspec.version testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -29,23 +49,4 @@ dependencies { androidTestImplementation deps.espresso } -ext.pubspec = [:] - -pubspec.packaging = 'aar' -pubspec.groupId = 'com.samelody.modapter' -pubspec.artifactId = 'modapter' -pubspec.repo = 'maven' -pubspec.name = 'Modapter' -pubspec.description = 'Modular adapter for Android RecyclerView.' -pubspec.version = deps.libVersionName -pubspec.url = 'https://github.com/samelody/modapter' -pubspec.gitUrl = 'https://github.com/samelody/modapter.git' -pubspec.issueUrl = 'https://github.com/samelody/modapter/issues' -pubspec.developerId = 'belinwu' -pubspec.developerName = 'Belin Wu' -pubspec.developerEmail = 'belinwu@qq.com' -pubspec.licenseName = 'Apache License 2.0' -pubspec.licenseUrl = 'https://raw.githubusercontent.com/samelody/modapter/master/LICENSE' -pubspec.licenses = ["Apache-2.0"] - apply from: "https://raw.githubusercontent.com/samelody/pubman/master/pub.gradle" \ No newline at end of file diff --git a/library/proguard-rules.pro b/core/proguard-rules.pro similarity index 100% rename from library/proguard-rules.pro rename to core/proguard-rules.pro diff --git a/library/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java b/core/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java similarity index 100% rename from library/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java rename to core/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java diff --git a/library/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml similarity index 61% rename from library/src/main/AndroidManifest.xml rename to core/src/main/AndroidManifest.xml index eba1a0e..592e9cf 100644 --- a/library/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ + package="com.samelody.modapter.core" /> diff --git a/library/src/main/java/com/samelody/modapter/AbstractItem.java b/core/src/main/java/com/samelody/modapter/AbstractItem.java similarity index 100% rename from library/src/main/java/com/samelody/modapter/AbstractItem.java rename to core/src/main/java/com/samelody/modapter/AbstractItem.java diff --git a/library/src/main/java/com/samelody/modapter/AdapterDelegate.java b/core/src/main/java/com/samelody/modapter/AdapterDelegate.java old mode 100755 new mode 100644 similarity index 76% rename from library/src/main/java/com/samelody/modapter/AdapterDelegate.java rename to core/src/main/java/com/samelody/modapter/AdapterDelegate.java index cf3f5fc..8263bc7 --- a/library/src/main/java/com/samelody/modapter/AdapterDelegate.java +++ b/core/src/main/java/com/samelody/modapter/AdapterDelegate.java @@ -8,19 +8,19 @@ import android.view.View; import android.view.ViewGroup; +import com.samelody.modapter.differ.AsyncDiffer; +import com.samelody.modapter.differ.NonAsyncDiffer; + import java.lang.reflect.InvocationTargetException; -import java.util.Collections; import java.util.List; -import static java.util.Collections.emptyList; - /** * The delegated implementation of modular adapter. * * @author Belin Wu */ -public final class AdapterDelegate implements ItemManager { +public final class AdapterDelegate implements ItemManager { /** * The item metadata registry. @@ -28,10 +28,24 @@ public final class AdapterDelegate implements ItemManager { private SparseArray registry = new SparseArray<>(); /** - * The list of items. + * A async differ. */ - @NonNull - private List list = emptyList(); + private AsyncDiffer differ; + + public AdapterDelegate() { + this(new NonAsyncDiffer()); + } + + public AdapterDelegate(AsyncDiffer differ) { + checkDiffer(differ); + this.differ = differ; + } + + private void checkDiffer(AsyncDiffer differ) { + if (differ == null) { + throw new IllegalArgumentException("differ argument must not be null"); + } + } /** * Gets item count. @@ -39,34 +53,37 @@ public final class AdapterDelegate implements ItemManager { * @return The item count. */ public int getItemCount() { - return list.size(); + return differ.getItemCount(); } - /** - * {@inheritDoc} - */ - @Nullable - @SuppressWarnings("unchecked") @Override - public T getItem(int position) { - if (position < 0 || position >= list.size()) { - return null; - } - return (T) list.get(position); + public ItemManager setDiffer(AsyncDiffer differ) { + checkDiffer(differ); + this.differ = differ; + return this; } - /** - * {@inheritDoc} - */ + @NonNull @Override - public ItemManager setList(List list) { - this.list = list == null ? Collections.emptyList() : list; + public ItemManager submitList(List list) { + differ.submitList(list); return this; } + @Override + public List getCurrentList() { + return differ.getCurrentList(); + } + + @Nullable + @Override + public E getItem(int position) { + return differ.getItem(position); + } + @NonNull @Override - public ItemManager register(int layoutId, Class holderClass) { + public ItemManager register(int layoutId, Class holderClass) { ItemMetadata metadata = new ItemMetadata(); metadata.setLayoutId(layoutId); metadata.setHolderClass(holderClass); @@ -76,7 +93,7 @@ public ItemManager register(int layoutId, Class holder @NonNull @Override - public ItemManager register(ItemMetadata metadata) { + public ItemManager register(ItemMetadata metadata) { if (metadata != null) { registry.put(metadata.getLayoutId(), metadata); } @@ -85,7 +102,7 @@ public ItemManager register(ItemMetadata metadata) { @NonNull @Override - public ItemManager unregister(int layoutId) { + public ItemManager unregister(int layoutId) { registry.delete(layoutId); return this; } diff --git a/library/src/main/java/com/samelody/modapter/AdapterItem.java b/core/src/main/java/com/samelody/modapter/AdapterItem.java similarity index 100% rename from library/src/main/java/com/samelody/modapter/AdapterItem.java rename to core/src/main/java/com/samelody/modapter/AdapterItem.java diff --git a/library/src/main/java/com/samelody/modapter/ItemManager.java b/core/src/main/java/com/samelody/modapter/ItemManager.java similarity index 60% rename from library/src/main/java/com/samelody/modapter/ItemManager.java rename to core/src/main/java/com/samelody/modapter/ItemManager.java index 1864578..dc7db3a 100644 --- a/library/src/main/java/com/samelody/modapter/ItemManager.java +++ b/core/src/main/java/com/samelody/modapter/ItemManager.java @@ -5,34 +5,60 @@ import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView.ViewHolder; +import com.samelody.modapter.differ.AsyncDiffer; + import java.util.List; /** * A item manager implements register, unregister and other managing operations. * + * @param The type of elements in the list. * @author Belin Wu */ -public interface ItemManager { +public interface ItemManager { /** - * Sets the list of items. + * Sets the async differ. + * + * @param differ The async differ. + * @return this item manager. + */ + ItemManager setDiffer(AsyncDiffer differ); + + /** + * Submits the list of items. * * @param list The list of items. * @return this item manager. */ @NonNull - ItemManager setList(List list); + ItemManager submitList(List list); + + /** + * Gets the list currently being displayed. + * + * @return The list. + */ + List getCurrentList(); + + /** + * Gets the item at the given position. + * + * @param position The position of item. + * @return The item at the given position. + */ + @Nullable + E getItem(int position); /** * Registers the item metadata. * * @param layoutId The resource id of item layout. * @param holderClass The class of view holder. - * @param The type of view holder. * @return this item manager. */ @NonNull - ItemManager register(@LayoutRes int layoutId, Class holderClass); + ItemManager register(@LayoutRes int layoutId, Class holderClass); /** * Registers the item metadata. @@ -41,7 +67,7 @@ public interface ItemManager { * @return this item manager. */ @NonNull - ItemManager register(ItemMetadata metadata); + ItemManager register(ItemMetadata metadata); /** * Unregisters the item metadata. @@ -50,15 +76,5 @@ public interface ItemManager { * @return this item manager. */ @NonNull - ItemManager unregister(@LayoutRes int layoutId); - - /** - * Gets the item at the given position. - * - * @param position The position of item. - * @param The type of item. - * @return The item at the given position. - */ - @Nullable - T getItem(int position); + ItemManager unregister(@LayoutRes int layoutId); } diff --git a/library/src/main/java/com/samelody/modapter/ItemMetadata.java b/core/src/main/java/com/samelody/modapter/ItemMetadata.java similarity index 100% rename from library/src/main/java/com/samelody/modapter/ItemMetadata.java rename to core/src/main/java/com/samelody/modapter/ItemMetadata.java diff --git a/library/src/main/java/com/samelody/modapter/ItemViewHolder.java b/core/src/main/java/com/samelody/modapter/ItemViewHolder.java old mode 100755 new mode 100644 similarity index 100% rename from library/src/main/java/com/samelody/modapter/ItemViewHolder.java rename to core/src/main/java/com/samelody/modapter/ItemViewHolder.java diff --git a/core/src/main/java/com/samelody/modapter/ModularAdapter.java b/core/src/main/java/com/samelody/modapter/ModularAdapter.java new file mode 100644 index 0000000..f0a86d3 --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/ModularAdapter.java @@ -0,0 +1,125 @@ +package com.samelody.modapter; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.Adapter; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.view.ViewGroup; + +import com.samelody.modapter.differ.AsyncDiffer; + +import java.util.List; + +/** + * A modular list adapter for presenting List data in a {@link RecyclerView}, including computing + * diffs between Lists on a background thread by {@link AsyncDiffer}. + * + * @param The type of elements in the list. + * @author Belin Wu + */ +public class ModularAdapter + extends Adapter + implements ItemManager { + + /** + * The delegated implementation. + */ + private AdapterDelegate delegate = new AdapterDelegate<>(); + + @Override + public int getItemViewType(int position) { + return delegate.getItemViewType(position); + } + + @Override + public final int getItemCount() { + return delegate.getItemCount(); + } + + @NonNull + @Override + public final ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return delegate.onCreateViewHolder(parent, viewType); + } + + @Override + public final void onBindViewHolder(@NonNull ViewHolder holder, int position) { + delegate.onBindViewHolder(holder, position); + } + + @Override + public final void onViewRecycled(@NonNull ViewHolder holder) { + super.onViewRecycled(holder); + delegate.onViewRecycled(holder); + } + + @Override + public final void onViewAttachedToWindow(@NonNull ViewHolder holder) { + super.onViewAttachedToWindow(holder); + delegate.onViewAttachedToWindow(holder); + } + + @Override + public final void onViewDetachedFromWindow(@NonNull ViewHolder holder) { + super.onViewDetachedFromWindow(holder); + delegate.onViewDetachedFromWindow(holder); + } + + /** + * Gets item manager. + * + * @return The item manager. + */ + public ItemManager getManager() { + return delegate; + } + + // implements ItemManager interface + + @Override + public ItemManager setDiffer(AsyncDiffer differ) { + delegate.setDiffer(differ); + return delegate; + } + + @NonNull + @Override + public ItemManager submitList(List list) { + delegate.submitList(list); + return delegate; + } + + @Override + public List getCurrentList() { + return delegate.getCurrentList(); + } + + @Nullable + @Override + public E getItem(int position) { + return delegate.getItem(position); + } + + @NonNull + @Override + public ItemManager register(int layoutId, Class holderClass) { + delegate.register(layoutId, holderClass); + return delegate; + } + + @NonNull + @Override + public ItemManager register(ItemMetadata metadata) { + delegate.register(metadata); + return delegate; + } + + @NonNull + @Override + public ItemManager unregister(int layoutId) { + delegate.unregister(layoutId); + return delegate; + } +} + diff --git a/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java b/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java new file mode 100644 index 0000000..f1262f8 --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java @@ -0,0 +1,22 @@ +package com.samelody.modapter.differ; + +import android.support.annotation.Nullable; + +import java.util.List; + +/** + * The async differ. + * + * @param The type of elements in the list. + * @author Belin Wu + */ +public interface AsyncDiffer { + + void submitList(@Nullable List list); + + E getItem(int position); + + int getItemCount(); + + List getCurrentList(); +} diff --git a/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java b/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java new file mode 100644 index 0000000..9b17b16 --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java @@ -0,0 +1,58 @@ +package com.samelody.modapter.differ; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.recyclerview.extensions.AsyncDifferConfig; +import android.support.v7.recyclerview.extensions.AsyncListDiffer; +import android.support.v7.util.DiffUtil; +import android.support.v7.util.ListUpdateCallback; +import android.support.v7.widget.RecyclerView; + +import java.util.List; + +/** + * The {@link AsyncListDiffer} implementation of {@link AsyncDiffer}. + * + * @param The type of elements in the list. + * @author Belin Wu + */ +public class ListAsyncDiffer implements AsyncDiffer { + + /** + * The real async differ. + */ + private final AsyncListDiffer differ; + + public ListAsyncDiffer(@NonNull RecyclerView.Adapter adapter, + @NonNull DiffUtil.ItemCallback callback) { + differ = new AsyncListDiffer<>(adapter, callback); + } + + public ListAsyncDiffer(@NonNull ListUpdateCallback callback, + @NonNull AsyncDifferConfig config) { + differ = new AsyncListDiffer<>(callback, config); + } + + @Override + public void submitList(@Nullable List list) { + differ.submitList((List) list); + } + + @Override + public E getItem(int position) { + if (position < 0 || position >= getCurrentList().size()) { + return null; + } + return getCurrentList().get(position); + } + + @Override + public int getItemCount() { + return getCurrentList().size(); + } + + @Override + public List getCurrentList() { + return differ.getCurrentList(); + } +} diff --git a/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java b/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java new file mode 100644 index 0000000..95b677f --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java @@ -0,0 +1,48 @@ +package com.samelody.modapter.differ; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.util.Collections; +import java.util.List; + +import static java.util.Collections.emptyList; +import static java.util.Collections.unmodifiableList; + +/** + * The non implementation of {@link AsyncDiffer}. + * + * @param The type of elements in the list. + * @author Belin Wu + */ +public class NonAsyncDiffer implements AsyncDiffer { + + /** + * The list of items. + */ + @NonNull + private List list = emptyList(); + + @Override + public void submitList(@Nullable List list) { + this.list = list == null ? Collections.emptyList() : (List) list; + } + + @Override + public E getItem(int position) { + if (position < 0 || position >= list.size()) { + return null; + } + return list.get(position); + } + + @Override + public int getItemCount() { + return list.size(); + } + + @Override + public List getCurrentList() { + return unmodifiableList(list); + } +} diff --git a/library/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml similarity index 100% rename from library/src/main/res/values/strings.xml rename to core/src/main/res/values/strings.xml diff --git a/library/src/test/java/com/samelody/modapter/ExampleUnitTest.java b/core/src/test/java/com/samelody/modapter/ExampleUnitTest.java similarity index 100% rename from library/src/test/java/com/samelody/modapter/ExampleUnitTest.java rename to core/src/test/java/com/samelody/modapter/ExampleUnitTest.java diff --git a/library/src/main/java/com/samelody/modapter/ModularAdapter.java b/library/src/main/java/com/samelody/modapter/ModularAdapter.java deleted file mode 100644 index b6c4b8f..0000000 --- a/library/src/main/java/com/samelody/modapter/ModularAdapter.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.samelody.modapter; - -import android.support.annotation.NonNull; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.RecyclerView.ViewHolder; -import android.view.ViewGroup; - -/** - * A modular adapter for {@link RecyclerView}. - * - * @author Belin Wu - */ -public class ModularAdapter extends RecyclerView.Adapter { - - /** - * The delegated implementation. - */ - private AdapterDelegate delegate = new AdapterDelegate(); - - @Override - public int getItemViewType(int position) { - return delegate.getItemViewType(position); - } - - @Override - public final int getItemCount() { - return delegate.getItemCount(); - } - - @NonNull - @Override - public final ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return delegate.onCreateViewHolder(parent, viewType); - } - - @Override - public final void onBindViewHolder(@NonNull ViewHolder holder, int position) { - delegate.onBindViewHolder(holder, position); - } - - @Override - public final void onViewRecycled(@NonNull ViewHolder holder) { - super.onViewRecycled(holder); - delegate.onViewRecycled(holder); - } - - @Override - public final void onViewAttachedToWindow(@NonNull ViewHolder holder) { - super.onViewAttachedToWindow(holder); - delegate.onViewAttachedToWindow(holder); - } - - @Override - public final void onViewDetachedFromWindow(@NonNull ViewHolder holder) { - super.onViewDetachedFromWindow(holder); - delegate.onViewDetachedFromWindow(holder); - } - - /** - * Gets item manager. - * - * @return The item manager. - */ - public ItemManager getManager() { - return delegate; - } -} - diff --git a/paging/.gitignore b/paging/.gitignore new file mode 100644 index 0000000..d0b97c6 --- /dev/null +++ b/paging/.gitignore @@ -0,0 +1,2 @@ +/build +*.iml \ No newline at end of file diff --git a/paging/build.gradle b/paging/build.gradle new file mode 100644 index 0000000..7675e4f --- /dev/null +++ b/paging/build.gradle @@ -0,0 +1,53 @@ +apply plugin: 'com.android.library' + +ext.pubspec = [:] + +pubspec.packaging = 'aar' +pubspec.groupId = 'com.samelody.modapter' +pubspec.artifactId = 'modapter-paging' +pubspec.repo = 'maven' +pubspec.name = 'Modapter' +pubspec.description = 'Modular adapter for Android RecyclerView.' +pubspec.version = "0.2.0-alpha1" +pubspec.versionCode = 2 +pubspec.url = 'https://github.com/samelody/modapter' +pubspec.gitUrl = 'https://github.com/samelody/modapter.git' +pubspec.issueUrl = 'https://github.com/samelody/modapter/issues' +pubspec.developerId = 'belinwu' +pubspec.developerName = 'Belin Wu' +pubspec.developerEmail = 'belinwu@qq.com' +pubspec.licenseName = 'Apache License 2.0' +pubspec.licenseUrl = 'https://raw.githubusercontent.com/samelody/modapter/master/LICENSE' +pubspec.licenses = ["Apache-2.0"] + +android { + compileSdkVersion deps.compileSdk + defaultConfig { + minSdkVersion deps.minSdk + targetSdkVersion deps.targetSdk + versionCode pubspec.versionCode + versionName pubspec.version + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation deps.paging + implementation project(':core') + + testImplementation deps.junit + + androidTestImplementation deps.test + androidTestImplementation deps.espresso +} + +apply from: "https://raw.githubusercontent.com/samelody/pubman/master/pub.gradle" \ No newline at end of file diff --git a/paging/proguard-rules.pro b/paging/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/paging/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/paging/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java b/paging/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java new file mode 100644 index 0000000..3ce234f --- /dev/null +++ b/paging/src/androidTest/java/com/samelody/modapter/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.samelody.modapter; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.samelody.modapter.test", appContext.getPackageName()); + } +} diff --git a/paging/src/main/AndroidManifest.xml b/paging/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9232b13 --- /dev/null +++ b/paging/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java b/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java new file mode 100644 index 0000000..4ce127a --- /dev/null +++ b/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java @@ -0,0 +1,66 @@ +package com.samelody.modapter.differ; + +import android.arch.paging.AsyncPagedListDiffer; +import android.arch.paging.PagedList; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.recyclerview.extensions.AsyncDifferConfig; +import android.support.v7.util.DiffUtil; +import android.support.v7.util.ListUpdateCallback; +import android.support.v7.widget.RecyclerView; + +import java.util.List; + +/** + * The {@link AsyncPagedListDiffer} implementation of {@link AsyncDiffer}. + * + * @param The type of elements in the list. + * @author Belin Wu + */ +public class PagedAsyncDiffer implements AsyncDiffer { + + /** + * The real async differ. + */ + private final AsyncPagedListDiffer differ; + + public PagedAsyncDiffer(@NonNull RecyclerView.Adapter adapter, + @NonNull DiffUtil.ItemCallback callback) { + differ = new AsyncPagedListDiffer<>(adapter, callback); + } + + public PagedAsyncDiffer(@NonNull ListUpdateCallback listUpdateCallback, + @NonNull AsyncDifferConfig config) { + differ = new AsyncPagedListDiffer<>(listUpdateCallback, config); + } + + @Override + public void submitList(@Nullable List list) { + if (list instanceof PagedList) { + differ.submitList((PagedList) list); + return; + } + throw new IllegalArgumentException("list is not a PagedList"); + } + + @Override + public E getItem(int position) { + if (getCurrentList() == null) { + return null; + } + if (position < 0 || position >= getCurrentList().size()) { + return null; + } + return getCurrentList().get(position); + } + + @Override + public int getItemCount() { + return differ.getItemCount(); + } + + @Override + public List getCurrentList() { + return differ.getCurrentList(); + } +} diff --git a/paging/src/main/java/com/samelody/modapter/package-info.java b/paging/src/main/java/com/samelody/modapter/package-info.java new file mode 100644 index 0000000..5c1cab7 --- /dev/null +++ b/paging/src/main/java/com/samelody/modapter/package-info.java @@ -0,0 +1 @@ +package com.samelody.modapter; \ No newline at end of file diff --git a/paging/src/main/res/values/strings.xml b/paging/src/main/res/values/strings.xml new file mode 100644 index 0000000..75700a2 --- /dev/null +++ b/paging/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Modapter + diff --git a/paging/src/test/java/com/samelody/modapter/ExampleUnitTest.java b/paging/src/test/java/com/samelody/modapter/ExampleUnitTest.java new file mode 100644 index 0000000..21d949e --- /dev/null +++ b/paging/src/test/java/com/samelody/modapter/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.samelody.modapter; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/sample/build.gradle b/sample/build.gradle index 82ba85b..ca3f45b 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -6,8 +6,8 @@ android { applicationId "com.samelody.samples.modapter" minSdkVersion deps.minSdk targetSdkVersion deps.targetSdk - versionCode deps.demoVersionCode - versionName deps.demoVersionName + versionCode 2 + versionName "0.2.0-alpha1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -20,7 +20,8 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation project(':library') + implementation project(':core') + implementation project(':paging') // implementation "com.samelody.modapter:modapter:0.1.0" implementation deps.appcompat implementation deps.recyclerview diff --git a/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java b/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java index 2d0dda0..64bf513 100644 --- a/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java +++ b/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java @@ -4,39 +4,39 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; +import com.samelody.modapter.AbstractItem; +import com.samelody.modapter.ItemManager; import com.samelody.modapter.ModularAdapter; -import com.samelody.modapter.AdapterItem; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { - private RecyclerView listView; - - private ModularAdapter adapter; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - listView = findViewById(R.id.list); - adapter = new ModularAdapter(); + RecyclerView listView = findViewById(R.id.list); + ModularAdapter adapter = new ModularAdapter<>(); listView.setAdapter(adapter); - adapter.getManager() - .register(R.layout.item_gallery_image, ImageViewHolder.class) + ItemManager manager = adapter.getManager(); + manager.register(R.layout.item_gallery_image, ImageViewHolder.class) .register(R.layout.item_gallery_date, DateViewHolder.class); - adapter.getManager().unregister(R.layout.item_gallery_image); + manager.unregister(R.layout.item_gallery_image); - List list = new ArrayList<>(); + List list = new ArrayList<>(); list.add(new ImageItem()); - list.add(new DateItem()); list.add(new ImageItem()); list.add(new ImageItem()); - adapter.getManager().setList(list); + list.add(new ImageItem()); + adapter.submitList(list); adapter.notifyDataSetChanged(); + + manager.getCurrentList(); + adapter.getItem(0); } } diff --git a/settings.gradle b/settings.gradle index 52baf7e..47aac0c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':sample', ':library' +include ':sample', ':core', ':paging' From 1fa8d773469e256e4e430557fe28ecfcf17d164b Mon Sep 17 00:00:00 2001 From: Belin Wu Date: Fri, 25 Jan 2019 16:37:16 +0800 Subject: [PATCH 2/3] Reimplement `AsyncDiffer#getItem()` method - More docs. - `ModularAdapter` no longer implements `ItemManager`. - New `getItemCount()` method of `ItemManager` interface. --- .../samelody/modapter/AdapterDelegate.java | 1 + .../com/samelody/modapter/ItemManager.java | 7 +++ .../com/samelody/modapter/ItemViewHolder.java | 16 +++++- .../com/samelody/modapter/ModularAdapter.java | 54 +------------------ .../samelody/modapter/differ/AsyncDiffer.java | 21 ++++++++ .../modapter/differ/ListAsyncDiffer.java | 14 +++-- .../modapter/differ/NonAsyncDiffer.java | 28 ++++++++-- .../modapter/differ/PagedAsyncDiffer.java | 21 +++----- .../samples/modapter/MainActivity.java | 4 +- 9 files changed, 85 insertions(+), 81 deletions(-) diff --git a/core/src/main/java/com/samelody/modapter/AdapterDelegate.java b/core/src/main/java/com/samelody/modapter/AdapterDelegate.java index 8263bc7..856029c 100644 --- a/core/src/main/java/com/samelody/modapter/AdapterDelegate.java +++ b/core/src/main/java/com/samelody/modapter/AdapterDelegate.java @@ -52,6 +52,7 @@ private void checkDiffer(AsyncDiffer differ) { * * @return The item count. */ + @Override public int getItemCount() { return differ.getItemCount(); } diff --git a/core/src/main/java/com/samelody/modapter/ItemManager.java b/core/src/main/java/com/samelody/modapter/ItemManager.java index dc7db3a..c9a4893 100644 --- a/core/src/main/java/com/samelody/modapter/ItemManager.java +++ b/core/src/main/java/com/samelody/modapter/ItemManager.java @@ -50,6 +50,13 @@ public interface ItemManager { @Nullable E getItem(int position); + /** + * Gets item count of current list. + * + * @return The item count of current list. + */ + int getItemCount(); + /** * Registers the item metadata. * diff --git a/core/src/main/java/com/samelody/modapter/ItemViewHolder.java b/core/src/main/java/com/samelody/modapter/ItemViewHolder.java index b48dd89..bcb5b71 100644 --- a/core/src/main/java/com/samelody/modapter/ItemViewHolder.java +++ b/core/src/main/java/com/samelody/modapter/ItemViewHolder.java @@ -8,7 +8,7 @@ /** * A holder with bound data item for item view. * - * @param The type of item. + * @param The type of data item. * @author Belin Wu */ public abstract class ItemViewHolder extends ViewHolder { @@ -27,18 +27,32 @@ void setItem(@Nullable T item) { this.item = item; } + /** + * Called when item view has been bound. + * + * @param item The data item bound within this view holder. + */ protected void onViewBound(T item) { // empty } + /** + * Called when item view has been recycled. + */ protected void onViewRecycled() { // empty } + /** + * Called when item view has been attached to a window. + */ protected void onViewAttachedToWindow() { // empty } + /** + * Called when item view has been detached from its window. + */ protected void onViewDetachedFromWindow() { // empty } diff --git a/core/src/main/java/com/samelody/modapter/ModularAdapter.java b/core/src/main/java/com/samelody/modapter/ModularAdapter.java index f0a86d3..077898e 100644 --- a/core/src/main/java/com/samelody/modapter/ModularAdapter.java +++ b/core/src/main/java/com/samelody/modapter/ModularAdapter.java @@ -1,7 +1,6 @@ package com.samelody.modapter; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.Adapter; import android.support.v7.widget.RecyclerView.ViewHolder; @@ -9,8 +8,6 @@ import com.samelody.modapter.differ.AsyncDiffer; -import java.util.List; - /** * A modular list adapter for presenting List data in a {@link RecyclerView}, including computing * diffs between Lists on a background thread by {@link AsyncDiffer}. @@ -18,9 +15,7 @@ * @param The type of elements in the list. * @author Belin Wu */ -public class ModularAdapter - extends Adapter - implements ItemManager { +public class ModularAdapter extends Adapter { /** * The delegated implementation. @@ -74,52 +69,5 @@ public final void onViewDetachedFromWindow(@NonNull ViewHolder holder) { public ItemManager getManager() { return delegate; } - - // implements ItemManager interface - - @Override - public ItemManager setDiffer(AsyncDiffer differ) { - delegate.setDiffer(differ); - return delegate; - } - - @NonNull - @Override - public ItemManager submitList(List list) { - delegate.submitList(list); - return delegate; - } - - @Override - public List getCurrentList() { - return delegate.getCurrentList(); - } - - @Nullable - @Override - public E getItem(int position) { - return delegate.getItem(position); - } - - @NonNull - @Override - public ItemManager register(int layoutId, Class holderClass) { - delegate.register(layoutId, holderClass); - return delegate; - } - - @NonNull - @Override - public ItemManager register(ItemMetadata metadata) { - delegate.register(metadata); - return delegate; - } - - @NonNull - @Override - public ItemManager unregister(int layoutId) { - delegate.unregister(layoutId); - return delegate; - } } diff --git a/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java b/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java index f1262f8..b14e1c3 100644 --- a/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java +++ b/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java @@ -12,11 +12,32 @@ */ public interface AsyncDiffer { + /** + * Submits the new list to be displayed. + * + * @param list The new list to be displayed. + */ void submitList(@Nullable List list); + /** + * Get the item from the current list at the specified index. + * + * @param position The position of item. + * @return The item at the given position. + */ E getItem(int position); + /** + * Gets item count of current list. + * + * @return The item count of current list. + */ int getItemCount(); + /** + * Gets the list currently being displayed by the Adapter. + * + * @return The list currently being displayed. + */ List getCurrentList(); } diff --git a/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java b/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java index 9b17b16..385cd30 100644 --- a/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java +++ b/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java @@ -4,9 +4,9 @@ import android.support.annotation.Nullable; import android.support.v7.recyclerview.extensions.AsyncDifferConfig; import android.support.v7.recyclerview.extensions.AsyncListDiffer; -import android.support.v7.util.DiffUtil; +import android.support.v7.util.DiffUtil.ItemCallback; import android.support.v7.util.ListUpdateCallback; -import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.Adapter; import java.util.List; @@ -23,8 +23,8 @@ public class ListAsyncDiffer implements AsyncDiffer { */ private final AsyncListDiffer differ; - public ListAsyncDiffer(@NonNull RecyclerView.Adapter adapter, - @NonNull DiffUtil.ItemCallback callback) { + public ListAsyncDiffer(@NonNull Adapter adapter, + @NonNull ItemCallback callback) { differ = new AsyncListDiffer<>(adapter, callback); } @@ -33,6 +33,7 @@ public ListAsyncDiffer(@NonNull ListUpdateCallback callback, differ = new AsyncListDiffer<>(callback, config); } + @SuppressWarnings("unchecked") @Override public void submitList(@Nullable List list) { differ.submitList((List) list); @@ -40,10 +41,7 @@ public void submitList(@Nullable List list) { @Override public E getItem(int position) { - if (position < 0 || position >= getCurrentList().size()) { - return null; - } - return getCurrentList().get(position); + return NonAsyncDiffer.getItem(this, position); } @Override diff --git a/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java b/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java index 95b677f..1cc4bd7 100644 --- a/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java +++ b/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java @@ -23,6 +23,7 @@ public class NonAsyncDiffer implements AsyncDiffer { @NonNull private List list = emptyList(); + @SuppressWarnings("unchecked") @Override public void submitList(@Nullable List list) { this.list = list == null ? Collections.emptyList() : (List) list; @@ -30,10 +31,7 @@ public void submitList(@Nullable List list) { @Override public E getItem(int position) { - if (position < 0 || position >= list.size()) { - return null; - } - return list.get(position); + return getItem(this, position); } @Override @@ -45,4 +43,26 @@ public int getItemCount() { public List getCurrentList() { return unmodifiableList(list); } + + /** + * Gets the item with given position from given differ. + * + * @param differ The async differ. + * @param position The position of item. + * @param The type of item. + * @return The item at given position. + */ + @Nullable + public static E getItem(AsyncDiffer differ, int position) { + if (differ == null) { + return null; + } + + List list = differ.getCurrentList(); + if (list == null || position < 0 || position >= list.size()) { + return null; + } + + return list.get(position); + } } diff --git a/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java b/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java index 4ce127a..74c47ec 100644 --- a/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java +++ b/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java @@ -5,9 +5,9 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.recyclerview.extensions.AsyncDifferConfig; -import android.support.v7.util.DiffUtil; +import android.support.v7.util.DiffUtil.ItemCallback; import android.support.v7.util.ListUpdateCallback; -import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.Adapter; import java.util.List; @@ -24,16 +24,17 @@ public class PagedAsyncDiffer implements AsyncDiffer { */ private final AsyncPagedListDiffer differ; - public PagedAsyncDiffer(@NonNull RecyclerView.Adapter adapter, - @NonNull DiffUtil.ItemCallback callback) { + public PagedAsyncDiffer(@NonNull Adapter adapter, + @NonNull ItemCallback callback) { differ = new AsyncPagedListDiffer<>(adapter, callback); } - public PagedAsyncDiffer(@NonNull ListUpdateCallback listUpdateCallback, + public PagedAsyncDiffer(@NonNull ListUpdateCallback callback, @NonNull AsyncDifferConfig config) { - differ = new AsyncPagedListDiffer<>(listUpdateCallback, config); + differ = new AsyncPagedListDiffer<>(callback, config); } + @SuppressWarnings("unchecked") @Override public void submitList(@Nullable List list) { if (list instanceof PagedList) { @@ -45,13 +46,7 @@ public void submitList(@Nullable List list) { @Override public E getItem(int position) { - if (getCurrentList() == null) { - return null; - } - if (position < 0 || position >= getCurrentList().size()) { - return null; - } - return getCurrentList().get(position); + return NonAsyncDiffer.getItem(this, position); } @Override diff --git a/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java b/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java index 64bf513..8d90237 100644 --- a/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java +++ b/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java @@ -33,10 +33,10 @@ protected void onCreate(Bundle savedInstanceState) { list.add(new ImageItem()); list.add(new ImageItem()); list.add(new ImageItem()); - adapter.submitList(list); + manager.submitList(list); adapter.notifyDataSetChanged(); manager.getCurrentList(); - adapter.getItem(0); + manager.getItem(0); } } From 85813f9e1fefff30de97e9def4a6feb95d1dbf51 Mon Sep 17 00:00:00 2001 From: Belin Wu Date: Fri, 25 Jan 2019 17:39:23 +0800 Subject: [PATCH 3/3] Prepare v0.2.0 release --- README.md | 66 +++++++++++++++---- core/build.gradle | 2 +- paging/build.gradle | 2 +- sample/build.gradle | 5 +- .../samples/modapter/MainActivity.java | 12 ++-- 5 files changed, 64 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 297e26f..17f1703 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,16 @@ Modular adapter for Android RecyclerView. **DO NOT USE THIS LIBRARY IN PRODUCTION UNTIL V1.0.0 IS RELEASED.** # Installation + Add the following dependency to your `build.gradle` file: ```groovy dependencies { - implementation 'com.samelody.modapter:modapter:0.1.0' + // required, core + implementation 'com.samelody.modapter:modapter-core:0.2.0' + + // optional, support android paging library + implementation 'com.samelody.modapter:modapter-paging:0.2.0' } ``` @@ -22,11 +27,11 @@ dependencies { ```java // create a ModularAdapter object instead of creating new Subclass of RecyclerView.Adapter. -ModularAdapter adapter = new ModularAdapter(); -recyclerView.setAdapter(adapter); +ModularAdapter adapter = new ModularAdapter<>(); +listView.setAdapter(adapter); // register item metadata to manager -ItemManager manager = adapter.getManager(); +ItemManager manager = adapter.getManager(); manager.register(R.layout.item_gallery_image, ImageViewHolder.class) .register(R.layout.item_gallery_date, DateViewHolder.class); @@ -35,32 +40,67 @@ List list = new ArrayList<>(); list.add(new ImageItem()); list.add(new DateItem()); -// Setup list and notify -manager.setList(list); +// submit list +manager.submitList(list); + +// notify adapter if no async differs used adapter.notifyDataSetChanged(); ``` -# Docs +## AsyncDiffer + +The `ItemManager` not enable async diffing by default. + +You can setup `AsyncDiffer` by your choice. The setting API is + +`ItemManager#setDiffer()`. + +The implemented async differs are following: + +- `NonAsyncDiffer`: The non implementation. (default used) +- `ListAsyncDiffer`: The `AsyncListDiffer` implementation. +- `PagedAsyncDiffer`: The `AsyncPagedListDiffer` implementation. + +### Using Async Differ + +```java +// set differ +manager.setDiffer(new ListAsyncDiffer<>()); + +// submit list +manager.submitList(list); + +// not need to call adapter.notify APIs +``` ## ItemManager -All APIs are encapsulated in `ItemManager` interface returned by `ModularAdapter#getItemManager()`. +All APIs are encapsulated in `ItemManager` interface returned by `ModularAdapter#getManager()`. ```java // register via layoutId and holderClass -ItemManager register(@LayoutRes int layoutId, Class holderClass); +ItemManager register(@LayoutRes int layoutId, Class holderClass); // register via ItemMetadata -ItemManager register(ItemMetadata metadata); +ItemManager register(ItemMetadata metadata); // unregister via layoutId -ItemManager unregister(@LayoutRes int layoutId); +ItemManager unregister(@LayoutRes int layoutId); // setup the data list -ItemManager setList(List list); +ItemManager submitList(List list); // Gets the item with given position -T getItem(int position); +E getItem(int position); + +// Gets current displayed list +List getCurrentList(); + +// Gets item count +int getItemCount(); + +// setup async differ +ItemManager setDiffer(AsyncDiffer differ); ``` # License diff --git a/core/build.gradle b/core/build.gradle index 6bbf8ed..3896bcb 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -8,7 +8,7 @@ pubspec.artifactId = 'modapter-core' pubspec.repo = 'maven' pubspec.name = 'Modapter' pubspec.description = 'Modular adapter for Android RecyclerView.' -pubspec.version = "0.2.0-alpha1" +pubspec.version = "0.2.0" pubspec.versionCode = 2 pubspec.url = 'https://github.com/samelody/modapter' pubspec.gitUrl = 'https://github.com/samelody/modapter.git' diff --git a/paging/build.gradle b/paging/build.gradle index 7675e4f..84fd93d 100644 --- a/paging/build.gradle +++ b/paging/build.gradle @@ -8,7 +8,7 @@ pubspec.artifactId = 'modapter-paging' pubspec.repo = 'maven' pubspec.name = 'Modapter' pubspec.description = 'Modular adapter for Android RecyclerView.' -pubspec.version = "0.2.0-alpha1" +pubspec.version = "0.2.0" pubspec.versionCode = 2 pubspec.url = 'https://github.com/samelody/modapter' pubspec.gitUrl = 'https://github.com/samelody/modapter.git' diff --git a/sample/build.gradle b/sample/build.gradle index ca3f45b..35db2b0 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -7,7 +7,7 @@ android { minSdkVersion deps.minSdk targetSdkVersion deps.targetSdk versionCode 2 - versionName "0.2.0-alpha1" + versionName "0.2.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -22,7 +22,8 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':core') implementation project(':paging') -// implementation "com.samelody.modapter:modapter:0.1.0" +// implementation "com.samelody.modapter:modapter-core:0.2.0" +// implementation "com.samelody.modapter:modapter-paging:0.2.0" implementation deps.appcompat implementation deps.recyclerview implementation deps.constraintlayout diff --git a/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java b/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java index 8d90237..117a60d 100644 --- a/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java +++ b/sample/src/main/java/com/samelody/samples/modapter/MainActivity.java @@ -4,7 +4,7 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; -import com.samelody.modapter.AbstractItem; +import com.samelody.modapter.AdapterItem; import com.samelody.modapter.ItemManager; import com.samelody.modapter.ModularAdapter; @@ -19,20 +19,20 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); RecyclerView listView = findViewById(R.id.list); - ModularAdapter adapter = new ModularAdapter<>(); + ModularAdapter adapter = new ModularAdapter<>(); listView.setAdapter(adapter); - ItemManager manager = adapter.getManager(); + ItemManager manager = adapter.getManager(); manager.register(R.layout.item_gallery_image, ImageViewHolder.class) .register(R.layout.item_gallery_date, DateViewHolder.class); manager.unregister(R.layout.item_gallery_image); - List list = new ArrayList<>(); - list.add(new ImageItem()); - list.add(new ImageItem()); + List list = new ArrayList<>(); list.add(new ImageItem()); + list.add(new DateItem()); list.add(new ImageItem()); + list.add(new DateItem()); manager.submitList(list); adapter.notifyDataSetChanged();