Skip to content

Commit

Permalink
Resolved #427 - Dynamically add and remove listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
davideas committed Aug 23, 2017
1 parent d42a397 commit 4fc5158
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ public FlexibleAdapter(@Nullable List<T> items, @Nullable Object listeners, bool
*
* @param listener the object(s) instance(s) of any listener
* @return this Adapter, so the call can be chained
* @see #removeListener(Class[])
* @since 5.0.0-b6
*/
@CallSuper
Expand All @@ -264,19 +265,18 @@ public FlexibleAdapter<T> addListener(@Nullable Object listener) {
if (listener instanceof OnItemClickListener) {
Log.i("- OnItemClickListener");
mItemClickListener = (OnItemClickListener) listener;
for (FlexibleViewHolder holder : getAllBoundViewHolders()) {
holder.getContentView().setOnClickListener(holder);
}
}
if (listener instanceof OnItemLongClickListener) {
Log.i("- OnItemLongClickListener");
mItemLongClickListener = (OnItemLongClickListener) listener;
// Restore the event
for (FlexibleViewHolder holder : getAllBoundViewHolders()) {
holder.getContentView().setOnLongClickListener(holder);
}
}
// if (listener instanceof OnItemAddListener) {
// Log.i("- OnItemAddListener");
// mItemAddListener = (OnItemAddListener) listener;
// }
// if (listener instanceof OnItemRemoveListener) {
// Log.i("- OnItemRemoveListener");
// mItemRemoveListener = (OnItemRemoveListener) listener;
// }
if (listener instanceof OnItemMoveListener) {
Log.i("- OnItemMoveListener");
mItemMoveListener = (OnItemMoveListener) listener;
Expand All @@ -301,6 +301,66 @@ public FlexibleAdapter<T> addListener(@Nullable Object listener) {
return this;
}

/**
* Removes one or more listeners from this Adapter.
* <p><b>Warning:</b>
* <ul><li>In case of <i>Click</i> and <i>LongClick</i> events, it will remove also the callback
* from all bound ViewHolders too. To restore these 2 events on the current bound ViewHolders
* call {@link #addListener(Object)} providing the instance of desired listener.</li>
* <li>To remove a specific listener you have to provide the class names of the listener,
* example:
* <pre>removeListener(FlexibleAdapter.OnUpdateListener.class,
* FlexibleAdapter.OnItemLongClickListener.class);</pre></li></ul></p>
*
* @param listeners the listeners type Classes to remove from the this Adapter and/or from all bound ViewHolders
* @return this Adapter, so the call can be chained
* @see #addListener(Object)
* @since 5.0.0-rc3
*/
public final FlexibleAdapter<T> removeListener(@NonNull Class... listeners) {
if (listeners == null || listeners.length == 0) {
Log.w("No listener class to remove!");
return this;
}
for (Class listener : listeners) {
if (listener == OnItemClickListener.class) {
mItemClickListener = null;
Log.i("- Removed OnItemClickListener");
for (FlexibleViewHolder holder : getAllBoundViewHolders()) {
holder.getContentView().setOnClickListener(null);
}
}
if (listener == OnItemLongClickListener.class) {
mItemLongClickListener = null;
Log.i("- Removed OnItemLongClickListener");
for (FlexibleViewHolder holder : getAllBoundViewHolders()) {
holder.getContentView().setOnLongClickListener(null);
}
}
if (listener == OnItemMoveListener.class) {
mItemMoveListener = null;
Log.i("- Removed OnItemMoveListener");
}
if (listener == OnItemSwipeListener.class) {
mItemSwipeListener = null;
Log.i("- Removed OnItemSwipeListener");
}
if (listener == OnDeleteCompleteListener.class) {
mDeleteCompleteListener = null;
Log.i("- Removed OnDeleteCompleteListener");
}
if (listener == OnStickyHeaderChangeListener.class) {
mStickyHeaderChangeListener = null;
Log.i("- Removed OnStickyHeaderChangeListener");
}
if (listener == OnUpdateListener.class) {
mUpdateListener = null;
Log.i("- Removed OnUpdateListener");
}
}
return this;
}

/**
* {@inheritDoc}
* <p>Attaches the {@code StickyHeaderHelper} to the RecyclerView if necessary.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,7 @@ private void notifySelectionChanged(int positionStart, int itemCount) {
if (itemCount > 0) {
// Avoid to rebind the VH, direct call to the itemView activation
for (FlexibleViewHolder flexHolder : mBoundViewHolders) {
if (isSelectable(flexHolder.getFlexibleAdapterPosition()))
flexHolder.toggleActivation();
flexHolder.toggleActivation();
}
// Use classic notification, in case FlexibleViewHolder is not implemented
if (mBoundViewHolders.isEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@

/**
* Helper Class that implements:
* <br/>- Single tap
* <br/>- Long tap
* <br/>- Touch for Drag and Swipe.
* <br>- Single tap
* <br>- Long tap
* <br>- Touch for Drag and Swipe.
* <p>You must extend and implement this class for the own ViewHolder.</p>
*
* @author Davide Steduto
* @since 03/01/2016 Created
* <br/>23/01/2016 ItemTouch with Drag&Drop, Swipe
* <br/>26/01/2016 Constructor revisited
* <br/>18/06/2016 StickyHeader flag is delegated to the super class (ContentViewHolder)
* <br>23/01/2016 ItemTouch with Drag&Drop, Swipe
* <br>26/01/2016 Constructor revisited
* <br>18/06/2016 StickyHeader flag is delegated to the super class (ContentViewHolder)
*/
public abstract class FlexibleViewHolder extends ContentViewHolder
implements View.OnClickListener, View.OnLongClickListener,
Expand Down Expand Up @@ -93,8 +93,12 @@ public FlexibleViewHolder(View view, FlexibleAdapter adapter, boolean stickyHead
super(view, adapter, stickyHeader);
this.mAdapter = adapter;

getContentView().setOnClickListener(this);
getContentView().setOnLongClickListener(this);
if (mAdapter.mItemClickListener != null) {
getContentView().setOnClickListener(this);
}
if (mAdapter.mItemLongClickListener != null) {
getContentView().setOnLongClickListener(this);
}
}

/*--------------------------------*/
Expand Down Expand Up @@ -135,10 +139,10 @@ public void onClick(View view) {
public boolean onLongClick(View view) {
int position = getFlexibleAdapterPosition();
if (!mAdapter.isEnabled(position)) return false;
Log.v("onLongClick on position %s mode=%s", position, FlexibleUtils.getModeName(mAdapter.getMode()));
// If DragLongPress is enabled, then LongClick must be skipped and the listener will
// If LongPressDrag is enabled, then LongClick must be skipped and the listener will
// be called in onActionStateChanged in Drag mode.
if (mAdapter.mItemLongClickListener != null && !mAdapter.isLongPressDragEnabled()) {
Log.v("onLongClick on position %s mode=%s", position, FlexibleUtils.getModeName(mAdapter.getMode()));
mAdapter.mItemLongClickListener.onItemLongClick(position);
toggleActivation();
return true;
Expand All @@ -148,7 +152,7 @@ public boolean onLongClick(View view) {
}

/**
* <b>Should be used only by the Handle View!</b><br/>
* <b>Should be used only by the Handle View!</b><br>
* {@inheritDoc}
*
* @see #setDragHandleView(View)
Expand Down Expand Up @@ -201,8 +205,8 @@ protected void setDragHandleView(@NonNull View view) {
/**
* Allows to change and see the activation status on the itemView and to perform animation
* on inner views.
* <p><b>IMPORTANT NOTE!</b> the selected background is visible if you added
* {@code android:background="?attr/selectableItemBackground"} on the item layout <u>AND</u>
* <p><b>Important note!</b> the selected background is visible if you added
* {@code android:background="?attr/selectableItemBackground"} in the item layout <u>AND</u>
* customized the file {@code style.xml}.</p>
* Alternatively, to set a background at runtime, you can use the new
* {@link eu.davidea.flexibleadapter.utils.DrawableUtils}.
Expand Down Expand Up @@ -331,8 +335,9 @@ public void onActionStateChanged(int position, int actionState) {
// Next check, allows to initiate the ActionMode and to add selection if configured
if ((shouldAddSelectionInActionMode() || mAdapter.getMode() != Mode.MULTI) &&
mAdapter.mItemLongClickListener != null && mAdapter.isSelectable(position)) {
Log.v("onLongClick on position %s mode=%s", position, mAdapter.getMode());
mAdapter.mItemLongClickListener.onItemLongClick(position);
alreadySelected = true; //Keep selection on release!
alreadySelected = true; // Keep selection on release!
}
}
// If still not selected, be sure current item appears selected for the Drag transition
Expand Down Expand Up @@ -369,9 +374,11 @@ public void onItemReleased(int position) {
(mActionState == ItemTouchHelper.ACTION_STATE_SWIPE ? "Swipe(1)" : "Drag(2)"));
// Be sure to keep selection if MULTI and shouldAddSelectionInActionMode is active
if (!alreadySelected) {
if (shouldAddSelectionInActionMode() &&
mAdapter.getMode() == Mode.MULTI) {
mAdapter.mItemLongClickListener.onItemLongClick(position);
if (shouldAddSelectionInActionMode() && mAdapter.getMode() == Mode.MULTI) {
Log.v("onLongClick for ActionMode on position %s mode=%s", position, mAdapter.getMode());
if (mAdapter.mItemLongClickListener != null) {
mAdapter.mItemLongClickListener.onItemLongClick(position);
}
if (mAdapter.isSelected(position)) {
toggleActivation();
}
Expand Down

0 comments on commit 4fc5158

Please sign in to comment.