From cdd504b5f636c2c60d6b5a20f83d6b47c8094422 Mon Sep 17 00:00:00 2001 From: Maxime Jallu Date: Fri, 27 Oct 2017 13:57:08 +0200 Subject: [PATCH] fix(communication): remove default methods --- README.md | 25 ++++-- .../jmaxime/adapters/RecyclerAdapter.java | 36 +++++--- .../jmaxime/factory/ViewHolderFactory.java | 90 ++++++++++++++----- .../jmaxime/interfaces/IItemViewType.java | 5 ++ .../android/jmaxime/interfaces/IViewType.java | 7 -- .../CheckableRecyclerViewHolder.java | 7 -- .../viewholder/RecyclerViewHolder.java | 10 --- build.gradle | 4 +- 8 files changed, 118 insertions(+), 66 deletions(-) create mode 100644 adapter/src/main/java/com/android/jmaxime/interfaces/IItemViewType.java diff --git a/README.md b/README.md index c3bfd21..7e6780f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ minSdkVersion = 16 # Gradle ``` -compile "com.github.maximejallu:adapters:1.9" +compile "com.github.maximejallu:adapters:1.1.2" ``` # RecyclerAdapter (Easy sample method) @@ -59,6 +59,7 @@ public class CustomerViewHolder2 extends RecyclerViewHolder { } } +//# Solution 1 : the object determines are own item view type public class Customer implements IViewType { public static final int TYPE_ON_LINE = 0; /*default*/ public static final int TYPE_STORE = 1; @@ -71,12 +72,24 @@ public class Customer implements IViewType { } } -private RecyclerAdapter mAdapter; +public class MyFragment extends Fragment { + + public void onCreateView(){ + private RecyclerAdapter mAdapter; + + mAdapter = new RecyclerAdapter(customerList, CustomerViewHolder1.class/*type par default*/); + mAdapter.putViewType(Customer.TYPE_STORE, CustomerViewHolder2.class, null /*callback*/); + mAdapter.putViewType(Customer.TYPE_OTHER, CustomerViewHolder3.class, true /*add default callback*/); + + //# Solution 2 : We give the strategy of the IViewType to our adapt it + mAdapter.setItemViewType(item -> { + //todo stategy type of item + return 0; + }); + mRecyclerView.setAdapter(adapter); + } -mAdapter = new RecyclerAdapter(customerList, CustomerViewHolder1.class/*type par default*/); -mAdapter.putViewType(Customer.TYPE_STORE, CustomerViewHolder2.class); -mAdapter.putViewType(Customer.TYPE_OTHER, CustomerViewHolder3.class); -mRecyclerView.setAdapter(adapter); +} ``` # SectionDecorator (Recycler with LinearLayout) precondition : create your RecyclerViewHolder diff --git a/adapter/src/main/java/com/android/jmaxime/adapters/RecyclerAdapter.java b/adapter/src/main/java/com/android/jmaxime/adapters/RecyclerAdapter.java index 9a3193f..d54b17c 100644 --- a/adapter/src/main/java/com/android/jmaxime/adapters/RecyclerAdapter.java +++ b/adapter/src/main/java/com/android/jmaxime/adapters/RecyclerAdapter.java @@ -8,6 +8,7 @@ import com.android.jmaxime.factory.ViewHolderFactory; import com.android.jmaxime.interfaces.IAdapterChanged; import com.android.jmaxime.interfaces.IBaseCommunication; +import com.android.jmaxime.interfaces.IItemViewType; import com.android.jmaxime.interfaces.IViewType; import com.android.jmaxime.interfaces.InitViewHolderDecorator; import com.android.jmaxime.interfaces.ShowPictureDecorator; @@ -20,7 +21,8 @@ public class RecyclerAdapter extends RecyclerView.Adapter> { private List mTList; - private ViewHolderFactory mFactory; + private ViewHolderFactory mViewHolderFactory; + private IItemViewType mViewTypeStategy; private IAdapterChanged mAdapterChanged; public RecyclerAdapter() { @@ -50,20 +52,20 @@ public RecyclerAdapter(List TList, Class> vie public RecyclerAdapter(List TList, ViewHolderFactory factory) { mTList = TList; - mFactory = factory; + mViewHolderFactory = factory; } public void setFactory(ViewHolderFactory factory) { - mFactory = factory; + mViewHolderFactory = factory; } @Override public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if (mFactory == null) { - throw new AccessControlException("mFactory is not instancied. thanks use setFactory() method."); + if (mViewHolderFactory == null) { + throw new AccessControlException("mViewHolderFactory is not instancied. thanks use setFactory() method."); } - RecyclerViewHolder vh = mFactory.createVH(parent, viewType); + RecyclerViewHolder vh = mViewHolderFactory.createVH(parent, viewType); /*used for decorator. Sample ButterKnife*/ vh.initBinding(); return vh; @@ -95,14 +97,24 @@ public T getItem(int position) { @Override public int getItemViewType(int position) { - if (getItem(position) != null && getItem(position) instanceof IViewType) { + if (mViewTypeStategy != null){ + return mViewTypeStategy.getItemViewType(getItem(position)); + }else if (getItem(position) != null && getItem(position) instanceof IViewType) { return ((IViewType) getItem(position)).getItemViewType(); } return super.getItemViewType(position); } - public void putViewType(int viewType, Class> viewHolder){ - mFactory.putViewType(viewType, viewHolder); + public void setViewTypeFactory(IItemViewType viewTypeStategy) { + mViewTypeStategy = viewTypeStategy; + } + + public void putViewType(int viewType, Class> viewHolder, boolean setDefaultCom){ + mViewHolderFactory.putViewType(viewType, viewHolder, setDefaultCom); + } + + public void putViewType(int viewType, Class> viewHolder, IBaseCommunication callback){ + mViewHolderFactory.putViewType(viewType, viewHolder, callback); } public boolean contains(final T obj) { @@ -120,16 +132,16 @@ public void setOnAdapterChangedListener(IAdapterChanged adapterChanged) { } public void setCommunication(IBaseCommunication communication) { - mFactory.setCommunication(communication); + mViewHolderFactory.setCommunication(communication); notifyDataSetChanged(); } public void attachInitHolderDecorator(InitViewHolderDecorator holderDecorator) { - mFactory.setInitViewDecorator(holderDecorator); + mViewHolderFactory.setInitViewDecorator(holderDecorator); } public void attachShowPictureDecorator(ShowPictureDecorator pictureDecorator) { - mFactory.setShowPictureDecorator(pictureDecorator); + mViewHolderFactory.setShowPictureDecorator(pictureDecorator); } /** diff --git a/adapter/src/main/java/com/android/jmaxime/factory/ViewHolderFactory.java b/adapter/src/main/java/com/android/jmaxime/factory/ViewHolderFactory.java index b4a9e6e..51e68d1 100644 --- a/adapter/src/main/java/com/android/jmaxime/factory/ViewHolderFactory.java +++ b/adapter/src/main/java/com/android/jmaxime/factory/ViewHolderFactory.java @@ -27,11 +27,11 @@ public class ViewHolderFactory { private static final String TAG = ViewHolderFactory.class.getName(); - private WeakReference mCommunication; + private static final int DEFAULT_VIEW_TYPE = 0; + private WeakReference mDecoratorWeakReference; private WeakReference mInitViewDecoratorWeakReference; - private Class> mViewHolderType; - private SparseArray>> mClassHashMap; + private SparseArray> mViewHashMap; public ViewHolderFactory() { this(null, null); @@ -42,25 +42,27 @@ public ViewHolderFactory(Class> viewHolderType) this(viewHolderType, null); } - public ViewHolderFactory(Class> viewHolderType, @Nullable IBaseCommunication callback) { + public ViewHolderFactory(Class> viewHolderType, + @Nullable IBaseCommunication callback) { this(viewHolderType, callback, null, null); } public ViewHolderFactory(Class> viewHolderType, - @Nullable IBaseCommunication callback, @Nullable InitViewHolderDecorator holderDecorator, - @Nullable ShowPictureDecorator pictureDecorator) { - mViewHolderType = viewHolderType; - mClassHashMap = new SparseArray<>(); - setCommunication(callback); + @Nullable IBaseCommunication callback, + @Nullable InitViewHolderDecorator holderDecorator, + @Nullable ShowPictureDecorator pictureDecorator) { + mViewHashMap = new SparseArray<>(); + + mViewHashMap.put(DEFAULT_VIEW_TYPE, new ViewTypeContainer<>(viewHolderType, callback)); setInitViewDecorator(holderDecorator); setShowPictureDecorator(pictureDecorator); } public final RecyclerViewHolder createVH(ViewGroup view, int viewType) { RecyclerViewHolder ret = getInstance(LayoutInflater.from(view.getContext()) - .inflate(getLayoutRes(viewType), view, false), viewType); + .inflate(getLayoutRes(viewType), view, false), viewType); if (ret != null) { - ret.setCommunication(getInterfaceCallback()); + ret.setCommunication(getInterfaceCallback(viewType)); ret.setInitViewDecorator(mInitViewDecoratorWeakReference.get()); ret.setPictureDecorator(mDecoratorWeakReference.get()); } @@ -87,11 +89,11 @@ private RecyclerViewHolder getInstance(View view, int viewType) { return ret; } - protected I getInterfaceCallback() { + protected I getInterfaceCallback(int viewType) { I i = null; try { //noinspection unchecked - i = (I) getCommunication(); + i = (I) getCommunication(viewType); } catch (ClassCastException e) { Log.e(TAG, "getInterfaceCallback: ", e); } @@ -99,19 +101,19 @@ protected I getInterfaceCallback() { } protected Class> getViewHolderType(int viewType) { - Class> vm = mViewHolderType; - if (mClassHashMap.indexOfKey(viewType) > -1) { - vm = mClassHashMap.get(viewType); + Class> vm = mViewHashMap.get(DEFAULT_VIEW_TYPE).mViewHolderType; + if (containsViewType(viewType)) { + vm = mViewHashMap.get(viewType).mViewHolderType; } return vm; } - public final IBaseCommunication getCommunication() { - return mCommunication.get(); + public final IBaseCommunication getCommunication(int viewType) { + return containsViewType(viewType) ? mViewHashMap.get(viewType).mCallback : null; } public void setCommunication(IBaseCommunication communication) { - mCommunication = new WeakReference<>(communication); + mViewHashMap.get(DEFAULT_VIEW_TYPE).mCallback = communication; } public void setShowPictureDecorator(@Nullable ShowPictureDecorator decoratorWeakReference) { @@ -123,10 +125,54 @@ public void setInitViewDecorator(@Nullable InitViewHolderDecorator initViewDecor } final @LayoutRes int getLayoutRes(int viewType) { - return getViewHolderType(viewType).getAnnotation(BindLayoutRes.class).value(); + return containsViewType(viewType) ? mViewHashMap.get(viewType).mLayoutResId : 0; + } + + public void putViewType(int viewType, Class> viewHolder, boolean setDefaultCommunication){ + putViewType(viewType, viewHolder, setDefaultCommunication ? mViewHashMap.get(DEFAULT_VIEW_TYPE).mCallback : null); } - public void putViewType(int viewType, Class> viewHolder) { - mClassHashMap.put(viewType, viewHolder); + public void putViewType(int viewType, Class> viewHolder, IBaseCommunication communicationCallback) { + if (viewType == 0){ + throw new IllegalArgumentException("viewType must be greater than 0. Because 0 is reserved for viewHolder by default"); + } + if (containsViewType(viewType)){ + mViewHashMap.get(viewType).update(viewHolder, communicationCallback); + }else { + mViewHashMap.put(viewType, new ViewTypeContainer<>(viewHolder, communicationCallback)); + } + } + + private boolean containsViewType(int viewType){ + return mViewHashMap.indexOfKey(viewType) > 0; + } + + private static class ViewTypeContainer { + Class> mViewHolderType; + @LayoutRes int mLayoutResId; + IBaseCommunication mCallback; + + public ViewTypeContainer(Class> viewHolderType, IBaseCommunication callback) { + update(viewHolderType, callback); + } + + public void update(Class> viewHolderType, IBaseCommunication callback){ + mViewHolderType = viewHolderType; + /*optimisation reflexion*/ + mLayoutResId = getLayoutResId(viewHolderType); + mCallback = callback; + } + + private int getLayoutResId(Class> aClass){ + checkViewType(aClass); + return aClass.getAnnotation(BindLayoutRes.class).value(); + } + + private void checkViewType(Class> viewHolder) { + if (!viewHolder.isAnnotationPresent(BindLayoutRes.class)) { + throw new IllegalArgumentException(viewHolder.getSimpleName() + + "is not annoted by " + BindLayoutRes.class.getSimpleName()); + } + } } } diff --git a/adapter/src/main/java/com/android/jmaxime/interfaces/IItemViewType.java b/adapter/src/main/java/com/android/jmaxime/interfaces/IItemViewType.java new file mode 100644 index 0000000..4e8170a --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/interfaces/IItemViewType.java @@ -0,0 +1,5 @@ +package com.android.jmaxime.interfaces; + +public interface IItemViewType { + int getItemViewType(T item); +} diff --git a/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java b/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java index b20fba8..0437cd8 100644 --- a/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java +++ b/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java @@ -1,12 +1,5 @@ package com.android.jmaxime.interfaces; -/** - * @author Maxime Jallu - * @since 29/09/2017 - *

- * Use this Class for :
- * {DOCUMENTATION} - */ public interface IViewType { int getItemViewType(); } diff --git a/adapter/src/main/java/com/android/jmaxime/viewholder/CheckableRecyclerViewHolder.java b/adapter/src/main/java/com/android/jmaxime/viewholder/CheckableRecyclerViewHolder.java index 479d9a2..200c640 100644 --- a/adapter/src/main/java/com/android/jmaxime/viewholder/CheckableRecyclerViewHolder.java +++ b/adapter/src/main/java/com/android/jmaxime/viewholder/CheckableRecyclerViewHolder.java @@ -5,13 +5,6 @@ import com.android.jmaxime.adapters.decorators.CheckableAdapterDecorator; -/** - * @author Maxime Jallu - * @since 02/10/2017 - *

- * Use this Class for :
- * {DOCUMENTATION} - */ public abstract class CheckableRecyclerViewHolder extends RecyclerViewHolder { private boolean mIsChecked; diff --git a/adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java b/adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java index 8aa15b5..bed104e 100644 --- a/adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java +++ b/adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java @@ -1,7 +1,6 @@ package com.android.jmaxime.viewholder; -import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; @@ -43,15 +42,6 @@ public abstract class RecyclerViewHolder extends RecyclerView.ViewHolder { private ShowPictureDecorator mPictureDecorator; private IBaseCommunication mCommunication; - /** - * This super() auto BindViews with ButterKnife
- * - * ButterKnife.bind(this, itemView); - * - * - * @param itemView the Views holder - */ - @SuppressLint("NewApi") public RecyclerViewHolder(View itemView) { super(itemView); } diff --git a/build.gradle b/build.gradle index 9ab5772..43a283e 100644 --- a/build.gradle +++ b/build.gradle @@ -27,8 +27,8 @@ ext { buildToolsVersion = "26.0.1" minSdkVersion = 16 targetSdkVersion = 26 - versionCode = 1711122100 - versionName = "1.9" + versionCode = 1711122210 + versionName = "1.1.2" } task clean(type: Delete) {