diff --git a/adapter/build.gradle b/adapter/build.gradle index 6411b5e..491d62b 100644 --- a/adapter/build.gradle +++ b/adapter/build.gradle @@ -23,8 +23,8 @@ android { // applicationId "com.android.jmaxime.com.android.jmaxime.adapter" minSdkVersion 23 targetSdkVersion 26 - versionCode 1 - versionName "1.0" + versionCode 1710291355 /*YYMMDDHHMM*/ + versionName "1.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/adapter/src/main/java/com/android/jmaxime/adapter/ArrayRecyclerAdapter.java b/adapter/src/main/java/com/android/jmaxime/adapter/ArrayRecyclerAdapter.java new file mode 100644 index 0000000..b0b1c1d --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/adapter/ArrayRecyclerAdapter.java @@ -0,0 +1,131 @@ +package com.android.jmaxime.adapter; + +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + + +import com.android.jmaxime.viewholder.RecyclerViewHolder; + +import java.util.List; + +/** + * @author Maxime Jallu + * @since 30/06/2016 + * + * Use this Class for :
+ * Crée un adapteur de recycler view de base + * @param Type d'item de la liste + * @param Type de ViewHolder doit extends de RecyclerViewHolder + */ +public abstract class ArrayRecyclerAdapter> extends RecyclerView.Adapter { + + private List mTList; + + /** + * Constructor + * @param TList list items for binding views + */ + public ArrayRecyclerAdapter(@NonNull final List TList) { + mTList = TList; + } + + @Override + public void onBindViewHolder(U holder, int position) { + holder.setItem(getItem(position)); + holder.setBound(false); + holder.bind(holder.getItem()); + holder.setBound(true); + } + + @Override + public int getItemCount() { + return mTList != null ? mTList.size() : 0; + } + + public U onCreateViewHolder(View view){ + return null; + } + + @Override + public U onCreateViewHolder(ViewGroup parent, int viewType) { + if(getLayoutRes(viewType) > 0) { + return onCreateViewHolder(LayoutInflater.from(parent.getContext()).inflate(getLayoutRes(viewType), parent, false)); + }else{ + throw new UnsupportedOperationException("onCreateViewHolder(ViewGroup parent, int viewType)"); + } + } + + @LayoutRes + protected int getLayoutRes(int viewType){ + return 0; + } + + /** + * Get Item + * @param position position founded + * @return instance to position + */ + public T getItem(int position){ + return mTList.get(position); + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * @param item element to be inserted + */ + public void addItem(T item){ + if (mTList != null) { + mTList.add(item); + notifyItemInserted(mTList.size()); + } + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * @param item element to be inserted + * @param position index at which the specified element is to be inserted + */ + public void addItem(T item, int position){ + if (mTList != null) { + position = Math.min(position, mTList.size()); + mTList.add(position, item); + notifyItemInserted(position); + } + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * @param position the index of the element to be removed + */ + public void removeItem(int position){ + if (mTList != null) { + mTList.remove(position); + notifyItemRemoved(position); + } + } + + /** + * Set new list items and notifyDataSetChanged() + * @link notifyDataSetChanged + * @param list new instance items list for bind views + */ + public void updateItems(@NonNull List list){ + mTList = list; + notifyDataSetChanged(); + } + + /** + * + * @return instance items list + */ + public List getTList() { + return mTList; + } +} diff --git a/adapter/src/main/java/com/android/jmaxime/adapter/RecyclerAdapter.java b/adapter/src/main/java/com/android/jmaxime/adapter/RecyclerAdapter.java new file mode 100644 index 0000000..6575cea --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/adapter/RecyclerAdapter.java @@ -0,0 +1,226 @@ +package com.android.jmaxime.adapter; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; +import android.view.ViewGroup; + + +import com.android.jmaxime.factory.ViewHolderFactory; +import com.android.jmaxime.interfaces.IAdapterChanged; +import com.android.jmaxime.interfaces.IBaseCommunication; +import com.android.jmaxime.interfaces.IViewType; +import com.android.jmaxime.viewholder.RecyclerViewHolder; + +import java.security.AccessControlException; +import java.util.ArrayList; +import java.util.List; + + +public class RecyclerAdapter extends RecyclerView.Adapter> { + + private List mTList; + private ViewHolderFactory mFactory; + private IAdapterChanged mAdapterChanged; + + public RecyclerAdapter() { + mTList = new ArrayList<>(); + } + + public RecyclerAdapter(ViewHolderFactory factory) { + this(new ArrayList<>(), factory); + } + + public RecyclerAdapter(Class> viewHolderType) { + this(new ArrayList<>(), viewHolderType, null); + } + + public RecyclerAdapter(Class> viewHolderType, @Nullable IBaseCommunication callback) { + this(new ArrayList<>(), viewHolderType, callback); + } + + public RecyclerAdapter(List TList, Class> viewHolderType) { + this(TList, viewHolderType, null); + } + + public RecyclerAdapter(List TList, Class> viewHolderType, @Nullable IBaseCommunication callback) { + this(TList, new ViewHolderFactory<>(viewHolderType, callback)); + } + + + public RecyclerAdapter(List TList, ViewHolderFactory factory) { + mTList = TList; + mFactory = factory; + } + + public void setFactory(ViewHolderFactory factory) { + mFactory = factory; + } + + @Override + public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (mFactory == null) { + throw new AccessControlException("mFactory is not instancied. thanks use setFactory() method."); + } + + return mFactory.createVH(parent, viewType); + } + + + @Override + public void onBindViewHolder(RecyclerViewHolder holder, int position) { + holder.setItem(getItem(position)); + holder.setBound(false); + holder.bind(holder.getItem()); + holder.setBound(true); + } + + @Override + public int getItemCount() { + return mTList != null ? mTList.size() : 0; + } + + /** + * Get Item + * + * @param position position founded + * @return instance to position + */ + public T getItem(int position) { + return mTList.get(position); + } + + @Override + public int getItemViewType(int position) { + 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 boolean contains(final T obj) { + return mTList.contains(obj); + } + + protected void callChangedListener() { + if (mAdapterChanged != null) { + mAdapterChanged.onItemCountChange(getItemCount()); + } + } + + public void setOnAdapterChangedListener(IAdapterChanged adapterChanged) { + mAdapterChanged = adapterChanged; + } + + public void setCommunication(IBaseCommunication communication) { + mFactory.setCommunication(communication); + notifyDataSetChanged(); + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * + * @param item element to be inserted + */ + public void addItem(T item) { + if (mTList != null) { + mTList.add(item); + notifyItemInserted(mTList.size()); + } + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * + * @param item element to be inserted + * @param position index at which the specified element is to be inserted + */ + public void addItem(T item, int position) { + if (mTList != null) { + position = Math.min(position, mTList.size()); + mTList.add(position, item); + notifyItemInserted(position); + } + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * + * @param collection elements to be inserted + */ + public void addAll(List collection) { + if (mTList != null) { + mTList.addAll(collection); + int start = Math.max(0, (mTList.size() - collection.size()) - 1); + notifyItemRangeInserted(start, collection.size()); + } + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * + * @param collection elements to be inserted + * @param index position to be inserted first element of collection + */ + public void addAll(int index, List collection) { + if (mTList != null) { + mTList.addAll(index, collection); + int start = Math.max(0, (mTList.size() - collection.size()) - 1); + notifyItemRangeInserted(start, collection.size()); + } + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * + * @param item the element to be removed + */ + public void removeItem(T item) { + removeItem(getTList().indexOf(item)); + } + + /** + * Inserts the specified element at the specified position in this list (optional operation). + * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). + * + * @param position the index of the element to be removed + */ + public void removeItem(int position) { + if (mTList != null && position > -1 && position < mTList.size()) { + mTList.remove(position); + notifyItemRemoved(position); + } + } + + /** + * Set new list items and notifyDataSetChanged() + * + * @param list new instance items list for bind views + * @link notifyDataSetChanged + */ + public void updateItems(@NonNull List list) { + mTList = list; + notifyDataSetChanged(); + } + + /** + * @return instance items list + */ + public List getTList() { + return mTList; + } + + public boolean isEmpty() { + return mTList == null || mTList.isEmpty(); + } +} + diff --git a/adapter/src/main/java/com/android/jmaxime/adapters/CheckableAdapter.java b/adapter/src/main/java/com/android/jmaxime/adapters/CheckableAdapter.java index d043e60..7745f9c 100644 --- a/adapter/src/main/java/com/android/jmaxime/adapters/CheckableAdapter.java +++ b/adapter/src/main/java/com/android/jmaxime/adapters/CheckableAdapter.java @@ -2,7 +2,7 @@ import com.android.jmaxime.factory.ViewHolderFactory; import com.android.jmaxime.interfaces.ViewCheckableCallback; -import com.android.jmaxime.viewholder.JRecyclerViewHolder; +import com.android.jmaxime.viewholder.RecyclerViewHolder; import java.util.HashMap; import java.util.List; @@ -18,7 +18,7 @@ public class CheckableAdapter extends RecyclerAdapter implements ViewCheck private HashMap mCheckedMap = new HashMap<>(); - public CheckableAdapter(Class> viewHolderType) { + public CheckableAdapter(Class> viewHolderType) { super(viewHolderType); setCommunication(this); } diff --git a/adapter/src/main/java/com/android/jmaxime/adapters/DividerItemDecoration.java b/adapter/src/main/java/com/android/jmaxime/adapters/DividerItemDecoration.java new file mode 100644 index 0000000..be5698b --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/adapters/DividerItemDecoration.java @@ -0,0 +1,201 @@ +package com.android.jmaxime.adapters; + + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +@SuppressWarnings("WeakerAccess") +public class DividerItemDecoration extends RecyclerView.ItemDecoration { + + private static final String INVALID = "invalid orientation"; + private static final int[] ATTRS = new int[]{ + android.R.attr.listDivider + }; + + public static final int LIST_HORIZONTAL = LinearLayoutManager.HORIZONTAL; + public static final int LIST_VERTICAL = LinearLayoutManager.VERTICAL; + public static final int GRID_STROKE = 3; + public static final int GRID_FILL = 4; + private static Drawable mDivider; + private int mOrientation; + + /** + * Custom constructor + * + * @param context + * @param orientation + */ + public DividerItemDecoration(final Context context, final int orientation) { + final TypedArray a = context.obtainStyledAttributes(ATTRS); + if (mDivider == null){ + mDivider = a.getDrawable(0); + } + a.recycle(); + setOrientation(orientation); + } + + /** + * Set the orientation of the underlying grid / list + * + * @param orientation must be + * {@link com.android.jmaxime.adapters.DividerItemDecoration#LIST_HORIZONTAL} + * {@link com.android.jmaxime.adapters.DividerItemDecoration#LIST_VERTICAL} + * {@link com.android.jmaxime.adapters.DividerItemDecoration#GRID_STROKE} + * {@link com.android.jmaxime.adapters.DividerItemDecoration#GRID_FILL} + */ + public void setOrientation(final int orientation) { + if (orientation != LIST_HORIZONTAL && + orientation != LIST_VERTICAL && + orientation != GRID_STROKE && + orientation != GRID_FILL) { + throw new IllegalArgumentException(INVALID); + } + mOrientation = orientation; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + super.onDraw(c, parent, state); + if (mDivider != null) { + switch (mOrientation) { + case LIST_VERTICAL: + drawVertical(c, parent); + break; + case LIST_HORIZONTAL: + drawHorizontal(c, parent); + break; + case GRID_FILL: + drawGridFill(c, parent); + break; + case GRID_STROKE: + drawGridStroke(c, parent); + break; + default: + throw new IllegalArgumentException(INVALID); + } + } + } + + /** + * Draw vertical divider in parent + * + * @param c canvas + * @param parent recycler view + */ + public void drawVertical(final Canvas c, final RecyclerView parent) { + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth() - parent.getPaddingRight(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int top = child.getBottom() + params.bottomMargin; + final int bottom = top + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + /** + * Draw horizontal divider in parent + * + * @param c Canvas + * @param parent Recycler view + */ + public void drawHorizontal(final Canvas c, final RecyclerView parent) { + final int top = parent.getPaddingTop(); + final int bottom = parent.getHeight() - parent.getPaddingBottom(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int left = child.getRight() + params.rightMargin; + final int right = left + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + /** + * Remove both horizontal and vertical divider in parent + * + * @param c Canvas + * @param parent Recycler view + */ + public void drawGridStroke(final Canvas c, final RecyclerView parent) { + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int left = child.getLeft() - params.leftMargin; + final int right = child.getRight() + params.rightMargin; + final int top = child.getTop() - params.topMargin; + final int bottom = child.getBottom() + params.bottomMargin; + mDivider.setBounds(left, top, left + mDivider.getIntrinsicHeight(), bottom); + mDivider.draw(c); + mDivider.setBounds(right - mDivider.getIntrinsicHeight(), top, right, bottom); + mDivider.draw(c); + mDivider.setBounds(left, top, right, top + mDivider.getIntrinsicHeight()); + mDivider.draw(c); + mDivider.setBounds(left, bottom - mDivider.getIntrinsicHeight(), right, bottom); + mDivider.draw(c); + mDivider.draw(c); + } + } + + /** + * Draw both horizontal and vertical divider in parent + * + * @param c Canvas + * @param parent Recler view + */ + public void drawGridFill(final Canvas c, final RecyclerView parent) { + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int left = child.getLeft() - params.leftMargin; + final int right = child.getRight() + params.rightMargin; + final int top = child.getTop() - params.topMargin; + final int bottom = child.getBottom() + params.bottomMargin; + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); + if (mDivider != null) { + switch (mOrientation) { + case LIST_VERTICAL: + outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); + break; + case LIST_HORIZONTAL: + outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); + break; + case GRID_FILL: + outRect.set(mDivider.getIntrinsicWidth(), mDivider.getIntrinsicWidth(), mDivider.getIntrinsicWidth(), mDivider.getIntrinsicWidth()); + break; + case GRID_STROKE: + outRect.set(0, 0, 0, 0); + break; + default: + throw new IllegalArgumentException(INVALID); + } + } + } +} + diff --git a/adapter/src/main/java/com/android/jmaxime/adapters/EasyPagerAdapter.java b/adapter/src/main/java/com/android/jmaxime/adapters/EasyPagerAdapter.java index 99bbe01..9601b58 100644 --- a/adapter/src/main/java/com/android/jmaxime/adapters/EasyPagerAdapter.java +++ b/adapter/src/main/java/com/android/jmaxime/adapters/EasyPagerAdapter.java @@ -6,7 +6,7 @@ import com.android.jmaxime.factory.ViewHolderFactory; import com.android.jmaxime.interfaces.IBaseCommunication; -import com.android.jmaxime.viewholder.JRecyclerViewHolder; +import com.android.jmaxime.viewholder.RecyclerViewHolder; import java.util.ArrayList; import java.util.List; @@ -23,21 +23,21 @@ public class EasyPagerAdapter extends PagerAdapter { private final List mItems; private final ViewHolderFactory mFactory; - public EasyPagerAdapter(Class> viewHolder) { + public EasyPagerAdapter(Class> viewHolder) { this(new ArrayList<>(), viewHolder); } - public EasyPagerAdapter(List items, Class> viewHolder) { + public EasyPagerAdapter(List items, Class> viewHolder) { this(items, viewHolder, null); } - public EasyPagerAdapter(List items, Class> viewHolder, IBaseCommunication callback) { + public EasyPagerAdapter(List items, Class> viewHolder, IBaseCommunication callback) { mItems = items; mFactory = new ViewHolderFactory<>(viewHolder, callback); } @Override public Object instantiateItem(ViewGroup container, int position) { - JRecyclerViewHolder vh = mFactory.createVH(container, 0); + RecyclerViewHolder vh = mFactory.createVH(container, 0); vh.bind(mItems.get(position)); container.addView(vh.itemView); return vh.itemView; 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 6544a11..ce2f240 100644 --- a/adapter/src/main/java/com/android/jmaxime/adapters/RecyclerAdapter.java +++ b/adapter/src/main/java/com/android/jmaxime/adapters/RecyclerAdapter.java @@ -9,7 +9,7 @@ import com.android.jmaxime.interfaces.IAdapterChanged; import com.android.jmaxime.interfaces.IBaseCommunication; import com.android.jmaxime.interfaces.IViewType; -import com.android.jmaxime.viewholder.JRecyclerViewHolder; +import com.android.jmaxime.viewholder.RecyclerViewHolder; import java.security.AccessControlException; import java.util.ArrayList; @@ -24,7 +24,7 @@ * Use this Class for :
* ... {DOCUMENTATION} */ -public class RecyclerAdapter extends RecyclerView.Adapter> { +public class RecyclerAdapter extends RecyclerView.Adapter> { private List mTList; private ViewHolderFactory mFactory; @@ -38,19 +38,19 @@ public RecyclerAdapter(ViewHolderFactory factory) { this(new ArrayList<>(), factory); } - public RecyclerAdapter(Class> viewHolderType) { + public RecyclerAdapter(Class> viewHolderType) { this(new ArrayList<>(), viewHolderType, null); } - public RecyclerAdapter(Class> viewHolderType, @Nullable IBaseCommunication callback) { + public RecyclerAdapter(Class> viewHolderType, @Nullable IBaseCommunication callback) { this(new ArrayList<>(), viewHolderType, callback); } - public RecyclerAdapter(List TList, Class> viewHolderType) { + public RecyclerAdapter(List TList, Class> viewHolderType) { this(TList, viewHolderType, null); } - public RecyclerAdapter(List TList, Class> viewHolderType, @Nullable IBaseCommunication callback) { + public RecyclerAdapter(List TList, Class> viewHolderType, @Nullable IBaseCommunication callback) { this(TList, new ViewHolderFactory<>(viewHolderType, callback)); } @@ -65,7 +65,7 @@ public void setFactory(ViewHolderFactory factory) { } @Override - public JRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (mFactory == null) { throw new AccessControlException("mFactory is not instancied. thanks use setFactory() method."); } @@ -75,7 +75,7 @@ public JRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) @Override - public void onBindViewHolder(JRecyclerViewHolder holder, int position) { + public void onBindViewHolder(RecyclerViewHolder holder, int position) { holder.setItem(getItem(position)); holder.setBound(false); holder.bind(holder.getItem()); @@ -105,7 +105,7 @@ public int getItemViewType(int position) { return super.getItemViewType(position); } - public void putViewType(int viewType, Class> viewHolder){ + public void putViewType(int viewType, Class> viewHolder){ mFactory.putViewType(viewType, viewHolder); } 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 5dab18b..f6717df 100644 --- a/adapter/src/main/java/com/android/jmaxime/factory/ViewHolderFactory.java +++ b/adapter/src/main/java/com/android/jmaxime/factory/ViewHolderFactory.java @@ -8,9 +8,9 @@ import android.view.View; import android.view.ViewGroup; -import com.android.jmaxime.viewholder.JRecyclerViewHolder; import com.android.jmaxime.annotations.BindLayoutRes; import com.android.jmaxime.interfaces.IBaseCommunication; +import com.android.jmaxime.viewholder.RecyclerViewHolder; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; @@ -25,27 +25,27 @@ public class ViewHolderFactory { private static final String TAG = ViewHolderFactory.class.getName(); private WeakReference mCommunication; - private Class> mViewHolderType; - private SparseArray>> mClassHashMap; + private Class> mViewHolderType; + private SparseArray>> mClassHashMap; public ViewHolderFactory() { - this(null); + this(null, null); } @SuppressLint("UseSparseArrays") - public ViewHolderFactory(Class> viewHolderType) { + public ViewHolderFactory(Class> viewHolderType) { this(viewHolderType, null); } - public ViewHolderFactory(Class> viewHolderType, IBaseCommunication callback) { + public ViewHolderFactory(Class> viewHolderType, IBaseCommunication callback) { mViewHolderType = viewHolderType; mClassHashMap = new SparseArray<>(); setCommunication(callback); } - public final JRecyclerViewHolder createVH(ViewGroup view, int viewType) { - JRecyclerViewHolder ret = getInstance(LayoutInflater.from(view.getContext()) - .inflate(getLayoutRes(viewType), view, false), viewType); + public final RecyclerViewHolder createVH(ViewGroup view, int viewType) { + RecyclerViewHolder ret = getInstance(LayoutInflater.from(view.getContext()) + .inflate(getLayoutRes(viewType), view, false), viewType); if (ret != null) { ret.setCommunication(getInterfaceCallback()); } @@ -53,9 +53,11 @@ public final JRecyclerViewHolder createVH(ViewGroup view, int viewType) { } @SuppressWarnings("TryWithIdenticalCatches") - private JRecyclerViewHolder getInstance(View view, int viewType) { - JRecyclerViewHolder ret = null; + private RecyclerViewHolder getInstance(View view, int viewType) { + RecyclerViewHolder ret = null; try { + /*prévention...*/ + getViewHolderType(viewType).getConstructor(View.class).setAccessible(true); ret = getViewHolderType(viewType).getConstructor(View.class).newInstance(view); } catch (InstantiationException e) { Log.i(TAG, "getInstance: "); @@ -64,7 +66,8 @@ private JRecyclerViewHolder getInstance(View view, int viewType) { } catch (InvocationTargetException e) { Log.i(TAG, "getInstance: ", e); } catch (NoSuchMethodException e) { - Log.i(TAG, "not found constructor. La class suivante doit être en static ou ne pas être en inner class : " + getViewHolderType(viewType).getName(), e); + Log.i(TAG, "not found constructor. La class suivante doit être en static ou ne pas être en inner class : " + getViewHolderType(viewType) + .getName(), e); } return ret; } @@ -80,8 +83,8 @@ protected I getInterfaceCallback() { return i; } - protected Class> getViewHolderType(int viewType) { - Class> vm = mViewHolderType; + protected Class> getViewHolderType(int viewType) { + Class> vm = mViewHolderType; if (mClassHashMap.indexOfKey(viewType) > -1) { vm = mClassHashMap.get(viewType); } @@ -96,11 +99,11 @@ public void setCommunication(IBaseCommunication communication) { mCommunication = new WeakReference<>(communication); } - public final @LayoutRes int getLayoutRes(int viewType) { + final @LayoutRes int getLayoutRes(int viewType) { return getViewHolderType(viewType).getAnnotation(BindLayoutRes.class).value(); } - public void putViewType(int viewType, Class> viewHolder){ + public void putViewType(int viewType, Class> viewHolder) { mClassHashMap.put(viewType, viewHolder); } } diff --git a/adapter/src/main/java/com/android/jmaxime/interfaces/IAdapterChanged.java b/adapter/src/main/java/com/android/jmaxime/interfaces/IAdapterChanged.java new file mode 100644 index 0000000..2957ebc --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/interfaces/IAdapterChanged.java @@ -0,0 +1,12 @@ +package com.android.jmaxime.interfaces; + +/** + * @author Maxime Jallu + * @since 29/09/2017 + *

+ * Use this Class for :
+ * {DOCUMENTATION} + */ +public interface IAdapterChanged { + void onItemCountChange(int count); +} diff --git a/adapter/src/main/java/com/android/jmaxime/interfaces/IBaseCommunication.java b/adapter/src/main/java/com/android/jmaxime/interfaces/IBaseCommunication.java new file mode 100644 index 0000000..f15f7ec --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/interfaces/IBaseCommunication.java @@ -0,0 +1,13 @@ +package com.android.jmaxime.interfaces; + + +public interface IBaseCommunication { + + default void onDeleteClicked(int position, T item) { + /*nothing*/ + } + + default void onEditClicked(int position, T item) { + /*nothing*/ + } +} diff --git a/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java b/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java new file mode 100644 index 0000000..b20fba8 --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/interfaces/IViewType.java @@ -0,0 +1,12 @@ +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/interfaces/ViewCheckableCallback.java b/adapter/src/main/java/com/android/jmaxime/interfaces/ViewCheckableCallback.java new file mode 100644 index 0000000..d182bfc --- /dev/null +++ b/adapter/src/main/java/com/android/jmaxime/interfaces/ViewCheckableCallback.java @@ -0,0 +1,19 @@ +package com.android.jmaxime.interfaces; + +import android.annotation.SuppressLint; + +/** + * @author Maxime Jallu + * @since 29/09/2017 + *

+ * Use this Class for :
+ * {DOCUMENTATION} + */ +@SuppressLint("NewApi") +public interface ViewCheckableCallback extends IBaseCommunication { + boolean isChecked(T item); + default boolean isCheckable(T item) { + return true; + } + void put(String key, boolean value); +} diff --git a/adapter/src/main/java/com/android/jmaxime/viewholder/KRecyclerViewHolder.kt b/adapter/src/main/java/com/android/jmaxime/viewholder/KRecyclerViewHolder.kt deleted file mode 100644 index 03c30d8..0000000 --- a/adapter/src/main/java/com/android/jmaxime/viewholder/KRecyclerViewHolder.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.android.jmaxime.adapter - -import android.content.Context -import android.graphics.drawable.Drawable -import android.support.annotation.* -import android.support.v4.content.ContextCompat -import android.support.v7.widget.RecyclerView -import android.util.Log -import android.view.View -import android.widget.ImageView -import butterknife.ButterKnife -import com.android.jmaxime.interfaces.IBaseCommunication -import com.squareup.picasso.Picasso - -/** - * @author Maxime Jallu - * * - * @link ArrayRecyclerAdapter - * * Tools this class:

- * * - * * getContext() - * * getColor(@ColorRes res) - * * getDrawable(@DrawableRes res) - * * - * @since 30/06/2016 - * * - * * Create for CubeInStore - Android (Decathlon) - * * - * * Use this Class for :

- * * make it easier ViewHolder com.android.jmaxime.adapter recyclerView, define T type of item - * * Must to use in RecyclerAdapter - */ -abstract class KRecyclerViewHolder constructor(itemView: View) : RecyclerView.ViewHolder(itemView) { - - var item: T? = null - var isBound: Boolean = false - private var mCommunication: IBaseCommunication? = null - - init { - ButterKnife.bind(this, itemView) - } - - abstract fun bind(item: T) - - protected val context: Context get() = itemView.context - - protected fun getString(@StringRes stringRes: Int): String { - return context.getString(stringRes) - } - - protected fun getString(@StringRes stringRes: Int, string: String): String { - return context.resources.getString(stringRes, string) - } - - protected fun getQuantityString(@PluralsRes pluralRes: Int, quantity: Int): String { - return context.resources.getQuantityString(pluralRes, quantity, quantity) - } - - protected fun getQuantityStringFormat(@PluralsRes pluralRes: Int, quantity: Int): String { - return context.resources.getQuantityString(pluralRes, quantity, quantity) - } - - protected fun getColor(@ColorRes colorResId: Int): Int { - return ContextCompat.getColor(context, colorResId) - } - - protected fun getDrawable(@DrawableRes drawableResId: Int): Drawable { - return ContextCompat.getDrawable(context, drawableResId) - } - - fun showPicture(picture: ImageView, url: String) { - Picasso.with(picture.context) - .load(url) - .placeholder(R.drawable.ic_image_black_24dp) - .error(R.drawable.ic_image_black_24dp) - .fit() - .centerInside() - .into(picture) - } - - protected fun onClickRemoveItem() { - getDispatcher>()?.onDeleteClicked(adapterPosition, item!!) - } - - protected fun onClickEditItem() { - getDispatcher>()?.onEditClicked(adapterPosition, item!!) - } - - protected fun > getDispatcher(): I? { - var i: I? = null - try { - i = mCommunication as I? - } catch (e: ClassCastException) { - Log.e("ViewHolderFactory", "getInterfaceCallback: ", e) - } - - return i - } - - fun setCommunication(interfaceCallback: IBaseCommunication?) { - mCommunication = interfaceCallback - } -} diff --git a/adapter/src/main/java/com/android/jmaxime/viewholder/JRecyclerViewHolder.java b/adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java similarity index 94% rename from adapter/src/main/java/com/android/jmaxime/viewholder/JRecyclerViewHolder.java rename to adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java index cff531d..d506b78 100644 --- a/adapter/src/main/java/com/android/jmaxime/viewholder/JRecyclerViewHolder.java +++ b/adapter/src/main/java/com/android/jmaxime/viewholder/RecyclerViewHolder.java @@ -34,10 +34,10 @@ * Create for CubeInStore - Android (Decathlon) *

* Use this Class for :
- * make it easier ViewHolder com.android.jmaxime.adapter recyclerView, define T type of item + * make it easier ViewHolder adapter recyclerView, define T type of item * Must to use in ArrayRecyclerAdapter */ -public abstract class JRecyclerViewHolder extends RecyclerView.ViewHolder { +public abstract class RecyclerViewHolder extends RecyclerView.ViewHolder { private T mItem; private boolean isBound; @@ -52,7 +52,7 @@ public abstract class JRecyclerViewHolder extends RecyclerView.ViewHolder { * @param itemView the Views holder */ @SuppressLint("NewApi") - public JRecyclerViewHolder(View itemView) { + public RecyclerViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } @@ -136,3 +136,4 @@ public void setCommunication(IBaseCommunication interfaceCallback) { mCommunication = interfaceCallback; } } + diff --git a/adapter/src/main/kotlin/com/android/jmaxime/adapters/ArrayRecyclerAdapter.kt b/adapter/src/main/kotlin/com/android/jmaxime/adapters/ArrayRecyclerAdapter.kt deleted file mode 100644 index 2455df2..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/adapters/ArrayRecyclerAdapter.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.android.jmaxime.adapter - -import android.support.v7.widget.RecyclerView - -/** - * @author Maxime Jallu - * @since 30/06/2016 - * - * Create for CubeInStore - Android - * - * Use this Class for :

- * Crée un adapteur de recycler view de base - * @param Type d'item de la liste - * @param Type de ViewHolder doit extends de RecyclerViewHolder - **/ -abstract class ArrayRecyclerAdapter>(TList: List) : RecyclerView.Adapter() { - - var tList: List? = null - private set - - init { - tList = TList - } - - override fun onBindViewHolder(holder: U, position: Int) { - holder.bind(getItem(position)) - } - - override fun getItemCount(): Int { - return tList!!.size - } - - /** - * Get Item - * @param position position founded - * @return instance to position - */ - fun getItem(position: Int): T { - return tList!![position] - } - - /** - * Set new list items and notifyDataSetChanged() - * @link notifyDataSetChanged - * @param list new instance items list for bind views - */ - fun updateItems(list: List) { - tList = list - notifyDataSetChanged() - } -} diff --git a/adapter/src/main/kotlin/com/android/jmaxime/adapters/DividerItemDecoration.kt b/adapter/src/main/kotlin/com/android/jmaxime/adapters/DividerItemDecoration.kt deleted file mode 100644 index 47cb619..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/adapters/DividerItemDecoration.kt +++ /dev/null @@ -1,99 +0,0 @@ -package com.android.jmaxime.adapter - -import android.content.Context -import android.content.res.TypedArray -import android.graphics.Canvas -import android.graphics.Rect -import android.graphics.drawable.Drawable -import android.support.v7.widget.LinearLayoutManager -import android.support.v7.widget.RecyclerView -import android.view.View - -/** - * @author Maxime Jallu - * @since 30/09/2016 - * - * - * Create for - Android - * - * - * Use this Class for :

- * ... {DOCUMENTATION} - */ -class DividerItemDecoration(context: Context, orientation: Int) : RecyclerView.ItemDecoration() { - - private val mDivider: Drawable? - - private var mOrientation: Int = 0 - - init { - val a = context.obtainStyledAttributes(ATTRS) - mDivider = a.getDrawable(0) - a.recycle() - setOrientation(orientation) - } - - fun setOrientation(orientation: Int) { - if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { - throw IllegalArgumentException("invalid orientation") - } - mOrientation = orientation - } - - override fun onDraw(c: Canvas?, parent: RecyclerView?) { - if (mOrientation == VERTICAL_LIST) { - drawVertical(c, parent) - } else { - drawHorizontal(c, parent) - } - } - - fun drawVertical(c: Canvas?, parent: RecyclerView?) { - val left = parent!!.paddingLeft - val right = parent.width - parent.paddingRight - - val childCount = parent.childCount - for (i in 0..childCount - 1) { - val child = parent.getChildAt(i) - val params = child - .layoutParams as RecyclerView.LayoutParams - val top = child.bottom + params.bottomMargin - val bottom = top + mDivider!!.intrinsicHeight - mDivider.setBounds(left, top, right, bottom) - mDivider.draw(c!!) - } - } - - fun drawHorizontal(c: Canvas?, parent: RecyclerView?) { - val top = parent!!.paddingTop - val bottom = parent.height - parent.paddingBottom - - val childCount = parent.childCount - for (i in 0..childCount - 1) { - val child = parent.getChildAt(i) - val params = child - .layoutParams as RecyclerView.LayoutParams - val left = child.right + params.rightMargin - val right = left + mDivider!!.intrinsicHeight - mDivider.setBounds(left, top, right, bottom) - mDivider.draw(c!!) - } - } - - override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State?) { - if (mOrientation == VERTICAL_LIST) { - outRect.set(0, 0, 0, mDivider!!.intrinsicHeight) - } else { - outRect.set(0, 0, mDivider!!.intrinsicWidth, 0) - } - } - - companion object { - - private val ATTRS = intArrayOf(android.R.attr.listDivider) - - val HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL - - val VERTICAL_LIST = LinearLayoutManager.VERTICAL - } -} diff --git a/adapter/src/main/kotlin/com/android/jmaxime/adapters/RecyclerAdapter.kt b/adapter/src/main/kotlin/com/android/jmaxime/adapters/RecyclerAdapter.kt deleted file mode 100644 index 403e274..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/adapters/RecyclerAdapter.kt +++ /dev/null @@ -1,187 +0,0 @@ -package com.android.jmaxime.adapter - -import android.support.v7.widget.RecyclerView -import android.view.ViewGroup -import com.android.jmaxime.factory.ViewHolderFactory -import com.android.jmaxime.interfaces.IAdapterChanged -import com.android.jmaxime.interfaces.IBaseCommunication -import com.android.jmaxime.interfaces.IViewType -import java.security.AccessControlException -import java.util.* - -/** - * @author Maxime Jallu - * @since 03/05/2017 - * Use this Class for :

- * ... {DOCUMENTATION} - */ -class RecyclerAdapter : RecyclerView.Adapter> { - - private var mTList: MutableList? = null - private var mFactory: ViewHolderFactory? = null - private var mAdapterChanged: IAdapterChanged? = null - - constructor() { - mTList = ArrayList() - } - - constructor(factory: ViewHolderFactory) : this(ArrayList(), factory, null) {} - - constructor(viewHolderType: Class>) : this(ArrayList(), viewHolderType, null) {} - - constructor(viewHolderType: Class>, callback: IBaseCommunication?) : this(ArrayList(), viewHolderType, callback) {} - - @JvmOverloads constructor(TList: MutableList, viewHolderType: Class>, callback: IBaseCommunication? = null) : this(TList, ViewHolderFactory(viewHolderType), callback) {} - - constructor(TList: MutableList, factory: ViewHolderFactory, callback: IBaseCommunication?) { - mTList = TList - mFactory = factory - mFactory!!.communication = callback - } - - fun setFactory(factory: ViewHolderFactory) { - mFactory = factory - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): KRecyclerViewHolder? { - if (mFactory == null) { - throw AccessControlException("mFactory is not instancied. thanks use setFactory() method.") - } - - return mFactory!!.createVH(parent, viewType) - } - - - override fun onBindViewHolder(holder: KRecyclerViewHolder, position: Int) { - holder.item = getItem(position) - holder.isBound = false - holder.bind(holder.item!!) - holder.isBound = true - } - - override fun getItemCount(): Int { - return if (mTList != null) mTList!!.size else 0 - } - - /** - * Get Item - * - * @param position position founded - * @return instance to position - */ - fun getItem(position: Int): T? { - return mTList!![position] - } - - override fun getItemViewType(position: Int): Int { - return if (getItem(position) != null && getItem(position) is IViewType) { - (getItem(position) as IViewType).getItemViewType() - } else super.getItemViewType(position) - } - - fun putViewType(viewType: Int, viewHolder: Class>) { - mFactory!!.putViewType(viewType, viewHolder) - } - - operator fun contains(obj: T): Boolean { - return mTList!!.contains(obj) - } - - protected fun callChangedListener() { - mAdapterChanged?.onItemCountChange(itemCount) - } - - fun setOnAdapterChangedListener(adapterChanged: IAdapterChanged?) { - mAdapterChanged = adapterChanged - } - - fun setCommunication(communication: IBaseCommunication?) { - mFactory!!.communication = communication - notifyDataSetChanged() - } - - /** - * Inserts the specified element at the specified position in this list (optional operation). - * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). - * - * @param item element to be inserted - */ - fun addItem(item: T) { - if (mTList != null) { - mTList!!.add(item) - notifyItemInserted(mTList!!.size) - } - } - - /** - * Inserts the specified element at the specified position in this list (optional operation). - * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). - * - * @param item element to be inserted - * @param position index at which the specified element is to be inserted - */ - fun addItem(item: T, position: Int) { - if (mTList != null) { - val pos = Math.min(position, mTList!!.size) - mTList!!.add(pos, item) - notifyItemInserted(pos) - } - } - - /** - * Inserts the specified element at the specified position in this list (optional operation). - * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). - * - * @param collection elements to be inserted - */ - fun addAll(collection: List) { - if (mTList != null) { - mTList!!.addAll(collection) - val start = Math.max(0, mTList!!.size - collection.size - 1) - notifyItemRangeInserted(start, collection.size) - } - } - - /** - * Inserts the specified element at the specified position in this list (optional operation). - * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). - * - * @param item the element to be removed - */ - fun removeItem(item: T) { - removeItem(tList!!.indexOf(item)) - } - - /** - * Inserts the specified element at the specified position in this list (optional operation). - * Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices). - * - * @param position the index of the element to be removed - */ - fun removeItem(position: Int) { - if (mTList != null && position > -1 && position < mTList!!.size) { - mTList!!.removeAt(position) - notifyItemRemoved(position) - } - } - - /** - * Set new list items and notifyDataSetChanged() - * - * @param list new instance items list for bind views - * @link notifyDataSetChanged - */ - fun updateItems(list: MutableList) { - mTList = list - notifyDataSetChanged() - } - - /** - * @return instance items list - */ - val tList: List? - get() = mTList - - val isEmpty: Boolean - get() = mTList == null || mTList!!.isEmpty() -} diff --git a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IAdapterChanged.kt b/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IAdapterChanged.kt deleted file mode 100644 index fd447d7..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IAdapterChanged.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.android.jmaxime.interfaces - -/** - * @author Maxime Jallu - * @since 13/09/2017 - * - * Use this Class for :
- * {DOCUMENTATION} - */ -interface IAdapterChanged { - fun onItemCountChange(count: Int) -} \ No newline at end of file diff --git a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IBaseCommunication.kt b/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IBaseCommunication.kt deleted file mode 100644 index fa70d10..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IBaseCommunication.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.android.jmaxime.interfaces - -/** - * @author Maxime Jallu - * @since 10/05/2017 - * Use this Class for :

- * ... {DOCUMENTATION} - */ -interface IBaseCommunication { - - fun onDeleteClicked(position: Int, item : T) { - /*nothing*/ - } - - fun onEditClicked(position: Int, item: T) { - /*nothing*/ - } -} diff --git a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IViewType.kt b/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IViewType.kt deleted file mode 100644 index 6847bc0..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/IViewType.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.android.jmaxime.interfaces - -/** - * @author Maxime Jallu - * @since 13/09/2017 - * - * Use this Class for :
- * {DOCUMENTATION} - */ -interface IViewType { - fun getItemViewType(): Int -} \ No newline at end of file diff --git a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/ViewCheckableCallback.kt b/adapter/src/main/kotlin/com/android/jmaxime/interfaces/ViewCheckableCallback.kt deleted file mode 100644 index 2c699bd..0000000 --- a/adapter/src/main/kotlin/com/android/jmaxime/interfaces/ViewCheckableCallback.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.android.jmaxime.interfaces - -import android.annotation.SuppressLint - -/** - * @author Maxime Jallu - * @since 26/09/2017 - * - * Use this Class for :
- * {DOCUMENTATION} - */ -interface ViewCheckableCallback : IBaseCommunication { - abstract fun isChecked(item: T): Boolean - @SuppressLint("NewApi") - fun isCheckable(item: T): Boolean { - return true - } - fun put(key: String, value: Boolean) -} \ No newline at end of file