From 5295bc85d2050d707602405fe6d06fd6dda68982 Mon Sep 17 00:00:00 2001 From: Janishar Ali Date: Fri, 16 Feb 2018 14:45:13 +0530 Subject: [PATCH 1/2] Add RecyclableEditText and Recycle Callback --- app/src/main/AndroidManifest.xml | 2 +- .../mindorks/test/gallery/ImageTypeBig.java | 8 +- .../mindorks/placeholderview/ViewAdapter.java | 79 ++++++++---------- .../mindorks/placeholderview/ViewBinder.java | 83 ++++++++++--------- .../mindorks/placeholderview/ViewHolder.java | 21 +++-- .../placeholderview/annotations/Recycle.java | 14 ++++ .../widget/RecyclableEditText.java | 48 +++++++++++ 7 files changed, 166 insertions(+), 89 deletions(-) create mode 100644 placeholderview/src/main/java/com/mindorks/placeholderview/annotations/Recycle.java create mode 100644 placeholderview/src/main/java/com/mindorks/placeholderview/widget/RecyclableEditText.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4c194e7..545f7a5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/app/src/main/java/com/mindorks/test/gallery/ImageTypeBig.java b/app/src/main/java/com/mindorks/test/gallery/ImageTypeBig.java index 0572895..4e815f1 100644 --- a/app/src/main/java/com/mindorks/test/gallery/ImageTypeBig.java +++ b/app/src/main/java/com/mindorks/test/gallery/ImageTypeBig.java @@ -14,6 +14,7 @@ import com.mindorks.placeholderview.annotations.LongClick; import com.mindorks.placeholderview.annotations.NonReusable; import com.mindorks.placeholderview.annotations.Position; +import com.mindorks.placeholderview.annotations.Recycle; import com.mindorks.placeholderview.annotations.Resolve; import com.mindorks.placeholderview.annotations.View; import com.mindorks.test.R; @@ -45,7 +46,12 @@ public ImageTypeBig(Context context, PlaceHolderView placeHolderView, String ulr @Resolve private void onResolved() { Glide.with(mContext).load(mUlr).into(imageView); - Log.d("DEBUG", "position " + position); + Log.d("DEBUG", "onResolved position " + position); + } + + @Recycle + private void onRecycled() { + Log.d("DEBUG", "onRecycled position " + position); } @LongClick(R.id.imageView) diff --git a/placeholderview/src/main/java/com/mindorks/placeholderview/ViewAdapter.java b/placeholderview/src/main/java/com/mindorks/placeholderview/ViewAdapter.java index 40bf8ee..d1ee758 100644 --- a/placeholderview/src/main/java/com/mindorks/placeholderview/ViewAdapter.java +++ b/placeholderview/src/main/java/com/mindorks/placeholderview/ViewAdapter.java @@ -18,13 +18,12 @@ * Created by janisharali on 18/08/16. */ -public class ViewAdapter extends RecyclerView.Adapter { +public class ViewAdapter extends RecyclerView.Adapter>> { private List> mViewBinderList; private Context mContext; /** - * * @param context */ public ViewAdapter(Context context) { @@ -33,31 +32,29 @@ public ViewAdapter(Context context) { } /** - * * @param parent * @param viewType * @return */ @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public ViewHolder> onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false); - return new ViewHolder(view); + return new ViewHolder<>(view); } /** - * * @param holder * @param position */ @Override - public void onBindViewHolder(ViewHolder holder, int position) { - mViewBinderList.get(position).bindView(holder.itemView, position); + public void onBindViewHolder(ViewHolder> holder, int position) { + holder.bind(mViewBinderList.get(position), position); } @Override - public void onViewAttachedToWindow(ViewHolder holder) { + public void onViewAttachedToWindow(ViewHolder> holder) { super.onViewAttachedToWindow(holder); - if(holder.getLayoutPosition() > RecyclerView.NO_POSITION && holder.getLayoutPosition() < mViewBinderList.size()) { + if (holder.getLayoutPosition() > RecyclerView.NO_POSITION && holder.getLayoutPosition() < mViewBinderList.size()) { mViewBinderList.get(holder.getLayoutPosition()).bindAnimation( Utils.getDeviceWidth(mContext), Utils.getDeviceHeight(mContext), @@ -66,7 +63,6 @@ public void onViewAttachedToWindow(ViewHolder holder) { } /** - * * @param position * @return */ @@ -76,7 +72,6 @@ public int getItemViewType(int position) { } /** - * * @return */ @Override @@ -85,40 +80,37 @@ public int getItemCount() { } /** - * * @param position * @throws IndexOutOfBoundsException */ - protected void removeView(int position)throws IndexOutOfBoundsException{ + protected void removeView(int position) throws IndexOutOfBoundsException { mViewBinderList.get(position).unbind(); mViewBinderList.remove(position); notifyItemRemoved(position); } /** - * * @param viewResolver * @throws IndexOutOfBoundsException */ - protected void addView(T viewResolver)throws IndexOutOfBoundsException{ + protected void addView(T viewResolver) throws IndexOutOfBoundsException { mViewBinderList.add(new ViewBinder<>(viewResolver)); notifyItemInserted(mViewBinderList.size() - 1); } /** - * * @param viewResolver * @throws IndexOutOfBoundsException */ - protected void removeView(T viewResolver)throws IndexOutOfBoundsException{ + protected void removeView(T viewResolver) throws IndexOutOfBoundsException { int position = -1; - for(ViewBinder viewBinder : mViewBinderList){ - if(viewBinder.getResolver() == viewResolver){ + for (ViewBinder viewBinder : mViewBinderList) { + if (viewBinder.getResolver() == viewResolver) { position = mViewBinderList.indexOf(viewBinder); break; } } - if(position != -1){ + if (position != -1) { mViewBinderList.get(position).unbind(); mViewBinderList.remove(position); notifyItemRemoved(position); @@ -126,42 +118,39 @@ protected void removeView(T viewResolver)throws IndexOutOfBoundsException{ } /** - * * @param position * @param viewResolver * @throws IndexOutOfBoundsException */ - protected void addView(int position, T viewResolver)throws IndexOutOfBoundsException{ + protected void addView(int position, T viewResolver) throws IndexOutOfBoundsException { mViewBinderList.add(position, new ViewBinder<>(viewResolver)); notifyItemInserted(position); } /** - * * @param resolverOld * @param resolverNew * @param after * @throws Resources.NotFoundException */ - protected void addView(T resolverOld, T resolverNew, boolean after)throws Resources.NotFoundException{ + protected void addView(T resolverOld, T resolverNew, boolean after) throws Resources.NotFoundException { int position = -1; - for(ViewBinder viewBinder : mViewBinderList){ - if(viewBinder.getResolver() == resolverOld){ + for (ViewBinder viewBinder : mViewBinderList) { + if (viewBinder.getResolver() == resolverOld) { position = mViewBinderList.indexOf(viewBinder); break; } } - if(position != -1){ - if(after)position++; + if (position != -1) { + if (after) position++; mViewBinderList.add(position, new ViewBinder<>(resolverNew)); notifyItemInserted(position); - }else{ + } else { throw new Resources.NotFoundException("Old view don't Exists in the list"); } } /** - * * @return */ protected List> getViewBinderList() { @@ -169,7 +158,6 @@ protected List> getViewBinderList() { } /** - * * @return */ protected Context getContext() { @@ -177,26 +165,24 @@ protected Context getContext() { } /** - * * @return */ - protected int getViewBinderListSize(){ + protected int getViewBinderListSize() { return mViewBinderList.size(); } /** - * * @param position * @return * @throws IndexOutOfBoundsException */ - protected T getViewResolverAtPosition(int position) throws IndexOutOfBoundsException{ + protected T getViewResolverAtPosition(int position) throws IndexOutOfBoundsException { return mViewBinderList.get(position).getResolver(); } - protected int getViewResolverPosition(T resolver){ - for(int i = 0; i < mViewBinderList.size(); i++){ - if(mViewBinderList.get(i).getResolver() == resolver){ + protected int getViewResolverPosition(T resolver) { + for (int i = 0; i < mViewBinderList.size(); i++) { + if (mViewBinderList.get(i).getResolver() == resolver) { return i; } } @@ -204,19 +190,18 @@ protected int getViewResolverPosition(T resolver){ } /** - * * @return */ - protected List getAllViewResolvers() { + protected List getAllViewResolvers() { List resolverList = new ArrayList<>(); - for(ViewBinder viewBinder : mViewBinderList){ + for (ViewBinder viewBinder : mViewBinderList) { resolverList.add(viewBinder.getResolver()); } return resolverList; } - protected void removeAllViewBinders(){ - for(ViewBinder viewBinder : mViewBinderList){ + protected void removeAllViewBinders() { + for (ViewBinder viewBinder : mViewBinderList) { viewBinder.unbind(); } mViewBinderList.clear(); @@ -240,4 +225,10 @@ public int compare(ViewBinder binder1, ViewBinder binder2) { }); notifyDataSetChanged(); } + + @Override + public void onViewRecycled(ViewHolder> holder) { + super.onViewRecycled(holder); + holder.recycle(); + } } diff --git a/placeholderview/src/main/java/com/mindorks/placeholderview/ViewBinder.java b/placeholderview/src/main/java/com/mindorks/placeholderview/ViewBinder.java index 30fbc1d..062b338 100644 --- a/placeholderview/src/main/java/com/mindorks/placeholderview/ViewBinder.java +++ b/placeholderview/src/main/java/com/mindorks/placeholderview/ViewBinder.java @@ -5,6 +5,7 @@ import com.mindorks.placeholderview.annotations.LongClick; import com.mindorks.placeholderview.annotations.NonReusable; import com.mindorks.placeholderview.annotations.Position; +import com.mindorks.placeholderview.annotations.Recycle; import com.mindorks.placeholderview.annotations.Resolve; import com.mindorks.placeholderview.annotations.View; @@ -24,10 +25,9 @@ public class ViewBinder { private boolean isNullable = false; /** - * * @param resolver */ - protected ViewBinder(final T resolver){ + protected ViewBinder(final T resolver) { mResolver = resolver; bindLayout(resolver); getNullable(resolver); @@ -35,11 +35,10 @@ protected ViewBinder(final T resolver){ } /** - * * @param promptsView * @param position */ - protected void bindView(V promptsView, int position){ + protected void bindView(V promptsView, int position) { bindViews(mResolver, promptsView); bindViewPosition(mResolver, position); bindClick(mResolver, promptsView); @@ -48,46 +47,42 @@ protected void bindView(V promptsView, int position){ } /** - * * @param deviceWidth * @param deviceHeight * @param view */ - protected void bindAnimation(int deviceWidth, int deviceHeight, V view){ - mAnimationResolver.bindAnimation(deviceWidth,deviceHeight, mResolver, view); + protected void bindAnimation(int deviceWidth, int deviceHeight, V view) { + mAnimationResolver.bindAnimation(deviceWidth, deviceHeight, mResolver, view); } /** - * * @param resolver */ - private void bindLayout(final T resolver){ + private void bindLayout(final T resolver) { Layout layout = resolver.getClass().getAnnotation(Layout.class); - if(layout != null) { + if (layout != null) { mLayoutId = layout.value(); } } /** - * * @param resolver */ - private void getNullable(final T resolver){ + private void getNullable(final T resolver) { NonReusable nonReusable = resolver.getClass().getAnnotation(NonReusable.class); - if(nonReusable != null) { + if (nonReusable != null) { isNullable = nonReusable.value(); } } /** - * * @param resolver * @param promptsView */ - protected void bindViews(final T resolver, V promptsView){ - for(final Field field : resolver.getClass().getDeclaredFields()) { + protected void bindViews(final T resolver, V promptsView) { + for (final Field field : resolver.getClass().getDeclaredFields()) { View viewAnnotation = field.getAnnotation(View.class); - if(viewAnnotation != null) { + if (viewAnnotation != null) { android.view.View view = promptsView.findViewById(viewAnnotation.value()); try { field.setAccessible(true); @@ -100,15 +95,14 @@ protected void bindViews(final T resolver, V promptsView){ } /** - * * @param resolver * @param position */ - protected void bindViewPosition(final T resolver, int position){ + protected void bindViewPosition(final T resolver, int position) { mPosition = position; - for(final Field field : resolver.getClass().getDeclaredFields()) { + for (final Field field : resolver.getClass().getDeclaredFields()) { Position annotation = field.getAnnotation(Position.class); - if(annotation != null) { + if (annotation != null) { try { field.setAccessible(true); field.set(resolver, position); @@ -120,13 +114,12 @@ protected void bindViewPosition(final T resolver, int position){ } /** - * * @param resolver */ - protected void resolveView(final T resolver){ - for(final Method method : resolver.getClass().getDeclaredMethods()) { + protected void resolveView(final T resolver) { + for (final Method method : resolver.getClass().getDeclaredMethods()) { Resolve annotation = method.getAnnotation(Resolve.class); - if(annotation != null) { + if (annotation != null) { try { method.setAccessible(true); method.invoke(resolver); @@ -140,14 +133,13 @@ protected void resolveView(final T resolver){ } /** - * * @param resolver * @param promptsView */ - protected void bindClick(final T resolver,final V promptsView){ - for(final Method method : resolver.getClass().getDeclaredMethods()){ + protected void bindClick(final T resolver, final V promptsView) { + for (final Method method : resolver.getClass().getDeclaredMethods()) { Click clickAnnotation = method.getAnnotation(Click.class); - if(clickAnnotation != null) { + if (clickAnnotation != null) { android.view.View view = promptsView.findViewById(clickAnnotation.value()); view.setOnClickListener(new android.view.View.OnClickListener() { @Override @@ -167,14 +159,13 @@ public void onClick(android.view.View v) { } /** - * * @param resolver * @param promptsView */ - protected void bindLongPress(final T resolver,final V promptsView){ - for(final Method method : resolver.getClass().getDeclaredMethods()){ + protected void bindLongPress(final T resolver, final V promptsView) { + for (final Method method : resolver.getClass().getDeclaredMethods()) { LongClick longClickAnnotation = method.getAnnotation(LongClick.class); - if(longClickAnnotation != null) { + if (longClickAnnotation != null) { android.view.View view = promptsView.findViewById(longClickAnnotation.value()); view.setOnLongClickListener(new android.view.View.OnLongClickListener() { @Override @@ -197,11 +188,11 @@ public boolean onLongClick(android.view.View v) { /** * Remove all the references in the original class */ - protected void unbind(){ - if(mResolver != null && isNullable) { + protected void unbind() { + if (mResolver != null && isNullable) { for (final Field field : mResolver.getClass().getDeclaredFields()) { try { - if(!field.getType().isPrimitive()) { + if (!field.getType().isPrimitive()) { field.setAccessible(true); field.set(mResolver, null); } @@ -215,7 +206,6 @@ protected void unbind(){ } /** - * * @return */ protected int getLayoutId() { @@ -223,7 +213,6 @@ protected int getLayoutId() { } /** - * * @return */ protected T getResolver() { @@ -233,4 +222,22 @@ protected T getResolver() { protected int getPosition() { return mPosition; } + + protected void recycleView() { + if (mResolver != null) { + for (final Method method : mResolver.getClass().getDeclaredMethods()) { + Recycle annotation = method.getAnnotation(Recycle.class); + if (annotation != null) { + try { + method.setAccessible(true); + method.invoke(mResolver); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + } + } + } } diff --git a/placeholderview/src/main/java/com/mindorks/placeholderview/ViewHolder.java b/placeholderview/src/main/java/com/mindorks/placeholderview/ViewHolder.java index c0dfc7c..bd7b8f6 100644 --- a/placeholderview/src/main/java/com/mindorks/placeholderview/ViewHolder.java +++ b/placeholderview/src/main/java/com/mindorks/placeholderview/ViewHolder.java @@ -1,18 +1,29 @@ package com.mindorks.placeholderview; +import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.View; /** * Created by janisharali on 18/08/16. */ -public class ViewHolder extends RecyclerView.ViewHolder { +public class ViewHolder> extends RecyclerView.ViewHolder { + + private B mBinder; - /** - * - * @param itemView - */ public ViewHolder(View itemView) { super(itemView); } + + public void bind(@NonNull B binder, int position) { + mBinder = binder; + mBinder.bindView(itemView, position); + } + + public void recycle() { + if (mBinder != null) { + mBinder.recycleView(); + mBinder = null; + } + } } diff --git a/placeholderview/src/main/java/com/mindorks/placeholderview/annotations/Recycle.java b/placeholderview/src/main/java/com/mindorks/placeholderview/annotations/Recycle.java new file mode 100644 index 0000000..1f5bc3e --- /dev/null +++ b/placeholderview/src/main/java/com/mindorks/placeholderview/annotations/Recycle.java @@ -0,0 +1,14 @@ +package com.mindorks.placeholderview.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by janisharali on 16/02/18. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Recycle { +} diff --git a/placeholderview/src/main/java/com/mindorks/placeholderview/widget/RecyclableEditText.java b/placeholderview/src/main/java/com/mindorks/placeholderview/widget/RecyclableEditText.java new file mode 100644 index 0000000..529ad1a --- /dev/null +++ b/placeholderview/src/main/java/com/mindorks/placeholderview/widget/RecyclableEditText.java @@ -0,0 +1,48 @@ +package com.mindorks.placeholderview.widget; + + +import android.content.Context; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.widget.EditText; + +/** + * Created by janisharali on 16/02/18. + */ + +public class RecyclableEditText extends EditText { + + private OnTextChangeListener mOnTextChangeListener; + + public RecyclableEditText(Context context) { + super(context); + } + + public RecyclableEditText(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public RecyclableEditText(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { + super.onTextChanged(text, start, lengthBefore, lengthAfter); + if (mOnTextChangeListener != null) { + mOnTextChangeListener.onTextChanged(text, start, lengthBefore, lengthAfter); + } + } + + public void setTextChangedListener(@NonNull OnTextChangeListener listener) { + mOnTextChangeListener = listener; + } + + public void removeTextChangedListener() { + mOnTextChangeListener = null; + } + + public interface OnTextChangeListener { + void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter); + } +} From 2ee234fd61f21d8ca240205b311e2130784615dd Mon Sep 17 00:00:00 2001 From: Janishar Ali Date: Fri, 16 Feb 2018 14:55:47 +0530 Subject: [PATCH 2/2] Update Version --- placeholderview/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/placeholderview/build.gradle b/placeholderview/build.gradle index db653e9..6b7ef8e 100644 --- a/placeholderview/build.gradle +++ b/placeholderview/build.gradle @@ -13,7 +13,7 @@ ext { siteUrl = 'https://github.com/janishar/PlaceHolderView' gitUrl = 'https://github.com/janishar/PlaceHolderView.git' - libraryVersion = '0.7.2' + libraryVersion = '0.7.3-alpha' developerId = 'janishar.ali@gmail.com' developerName = 'Janishar Ali' @@ -31,8 +31,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 25 - versionCode 9 - versionName "0.7.2" + versionCode 10 + versionName "0.7.3-alpha" } buildTypes { release {