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/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..3896bcb 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" +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..856029c --- 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,45 +28,63 @@ 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. * * @return The item count. */ + @Override 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 +94,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 +103,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 56% rename from library/src/main/java/com/samelody/modapter/ItemManager.java rename to core/src/main/java/com/samelody/modapter/ItemManager.java index 1864578..c9a4893 100644 --- a/library/src/main/java/com/samelody/modapter/ItemManager.java +++ b/core/src/main/java/com/samelody/modapter/ItemManager.java @@ -5,34 +5,67 @@ 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 async differ. + * + * @param differ The async differ. + * @return this item manager. + */ + ItemManager setDiffer(AsyncDiffer differ); /** - * Sets the list of items. + * 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); + + /** + * Gets item count of current list. + * + * @return The item count of current list. + */ + int getItemCount(); /** * 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 +74,7 @@ public interface ItemManager { * @return this item manager. */ @NonNull - ItemManager register(ItemMetadata metadata); + ItemManager register(ItemMetadata metadata); /** * Unregisters the item metadata. @@ -50,15 +83,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 69% rename from library/src/main/java/com/samelody/modapter/ItemViewHolder.java rename to core/src/main/java/com/samelody/modapter/ItemViewHolder.java index b48dd89..bcb5b71 --- a/library/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/library/src/main/java/com/samelody/modapter/ModularAdapter.java b/core/src/main/java/com/samelody/modapter/ModularAdapter.java similarity index 74% rename from library/src/main/java/com/samelody/modapter/ModularAdapter.java rename to core/src/main/java/com/samelody/modapter/ModularAdapter.java index b6c4b8f..077898e 100644 --- a/library/src/main/java/com/samelody/modapter/ModularAdapter.java +++ b/core/src/main/java/com/samelody/modapter/ModularAdapter.java @@ -2,20 +2,25 @@ import android.support.annotation.NonNull; 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; + /** - * A modular adapter for {@link RecyclerView}. + * 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 RecyclerView.Adapter { +public class ModularAdapter extends Adapter { /** * The delegated implementation. */ - private AdapterDelegate delegate = new AdapterDelegate(); + private AdapterDelegate delegate = new AdapterDelegate<>(); @Override public int getItemViewType(int position) { @@ -61,7 +66,7 @@ public final void onViewDetachedFromWindow(@NonNull ViewHolder holder) { * * @return The item manager. */ - public ItemManager getManager() { + public ItemManager getManager() { 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..b14e1c3 --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/differ/AsyncDiffer.java @@ -0,0 +1,43 @@ +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 { + + /** + * 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 new file mode 100644 index 0000000..385cd30 --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/differ/ListAsyncDiffer.java @@ -0,0 +1,56 @@ +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.ItemCallback; +import android.support.v7.util.ListUpdateCallback; +import android.support.v7.widget.RecyclerView.Adapter; + +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 Adapter adapter, + @NonNull ItemCallback callback) { + differ = new AsyncListDiffer<>(adapter, callback); + } + + public ListAsyncDiffer(@NonNull ListUpdateCallback callback, + @NonNull AsyncDifferConfig config) { + differ = new AsyncListDiffer<>(callback, config); + } + + @SuppressWarnings("unchecked") + @Override + public void submitList(@Nullable List list) { + differ.submitList((List) list); + } + + @Override + public E getItem(int position) { + return NonAsyncDiffer.getItem(this, 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..1cc4bd7 --- /dev/null +++ b/core/src/main/java/com/samelody/modapter/differ/NonAsyncDiffer.java @@ -0,0 +1,68 @@ +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(); + + @SuppressWarnings("unchecked") + @Override + public void submitList(@Nullable List list) { + this.list = list == null ? Collections.emptyList() : (List) list; + } + + @Override + public E getItem(int position) { + return getItem(this, position); + } + + @Override + public int getItemCount() { + return list.size(); + } + + @Override + 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/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/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..84fd93d --- /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" +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..74c47ec --- /dev/null +++ b/paging/src/main/java/com/samelody/modapter/differ/PagedAsyncDiffer.java @@ -0,0 +1,61 @@ +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.ItemCallback; +import android.support.v7.util.ListUpdateCallback; +import android.support.v7.widget.RecyclerView.Adapter; + +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 Adapter adapter, + @NonNull ItemCallback callback) { + differ = new AsyncPagedListDiffer<>(adapter, callback); + } + + public PagedAsyncDiffer(@NonNull ListUpdateCallback callback, + @NonNull AsyncDifferConfig config) { + differ = new AsyncPagedListDiffer<>(callback, config); + } + + @SuppressWarnings("unchecked") + @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) { + return NonAsyncDiffer.getItem(this, 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..35db2b0 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" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -20,8 +20,10 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation project(':library') -// implementation "com.samelody.modapter:modapter:0.1.0" + implementation project(':core') + implementation project(':paging') +// 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 2d0dda0..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,39 +4,39 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; -import com.samelody.modapter.ModularAdapter; import com.samelody.modapter.AdapterItem; +import com.samelody.modapter.ItemManager; +import com.samelody.modapter.ModularAdapter; 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.add(new ImageItem()); list.add(new DateItem()); list.add(new ImageItem()); - list.add(new ImageItem()); - adapter.getManager().setList(list); + list.add(new DateItem()); + manager.submitList(list); adapter.notifyDataSetChanged(); + + manager.getCurrentList(); + manager.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'