Skip to content
Davide Steduto edited this page Jan 4, 2017 · 22 revisions

In this page


FlexibleViewHolder

FlexibleViewHolder is the predefined ViewHolder for all Adapter items. It manages the click events and manipulates the View for activation due to the selection, dragging and swiping. It drastically reduce the time of developing and extends new functionality at the same time.

Event methods:
onClick(), onLongClick(), onTouch(), onActionStateChanged(), onItemReleased()

Settings for itemView

Each of the following methods specifies a single behavior triggered from an event, carefully read the javaDoc when calling or extending one of them:
toggleActivation(), getActivationElevation(), shouldAddSelectionInActionMode(), shouldActivateViewWhileSwiping(), setDragHandleView(), isDraggable(), isSwipeable(), getFrontView(), getRearLeftView(), getRearRightView()

Important settings for sticky headers

  • To address correct behaviors when using sticky headers it's important to provide sticky=true to the super constructor when extending this ViewHolder.
  • Not only, due to the original ViewHolder Android(R) implementation (itemView is declared final), when retrieving the Adapter position is no longer possible to call getAdapterPosition() (declared final too), therefore, only in case of sticky view holders, you now have to call getFlexibleAdapterPosition(). This overcomes the situation of returning an unknown position (-1) of ViewHolders created out of the LayoutManager.

Scrolling animation

The new way to scroll animate the itemView (or any View inside it!) is to implement the method scrollAnimators of the ViewHolder. Read the Adapter Animations Wiki page to discover the new possibilities to how animate the itemView.

ExpandableViewHolder

ExpandableViewHolder extends FlexibleViewHolder. Here we handle the events to expand/collapse an item through the usual methods onClick, onLongClick and onActionStateChanged (dragging and swiping).

Settings for itemView

More settings are available in the expandable version, read carefully the javaDoc when calling or extending one of them:
isViewExpandableOnClick(), isViewCollapsibleOnLongClick(), shouldNotifyParentOnClick(), toggleExpansion(), expandView(), collapseView()

AnimatedViewHolder

AnimatedViewHolder is a new interface to animate the itemView when a notification is triggered from the Adapter after adding/removing the item. Read the Adapter Animations Wiki page to discover the new possibilities to how animate the itemView.

However, if you decide to implement this interface, the itemView will have independent item animations.

Create/Bind ViewHolders

Method A (new!)

Via Item interfaces. In this case you don't have to implement getItemViewType(), onCreateViewHolder() and onBindViewHolder() adapter methods, but getLayoutRes() (for the item type we need an int, the layoutResID is sufficient), createViewHolder() and bindViewHolder() from inside the implementation of item interfaces.

Adopting item interfaces, it gives several benefits such as: Expandable items, runtime flags to enable/disable drag and swipe, to enable/disable the item itself and to allow/disallow the selection.

@Override
public int getLayoutRes() {
	return R.layout.recycler_expandable_row;
}

@Override
public ViewHolder createViewHolder(FlexibleAdapter adapter, LayoutInflater inflater, ViewGroup parent) {
	return new ViewHolder(inflater.inflate(getLayoutRes(), parent, false), adapter);
}

@Override
public void bindViewHolder(final FlexibleAdapter adapter, ViewHolder holder, int position, List payloads) {
	//Bind your VH
}

The ViewHolder class is an inner [static] class of the same item interface.

From my research, no more notifyItemRangeChanged() calls in selectAll() and clearSelection() methods: This means no more item binding!
Now, bound selectable ViewHolders will have the StateListDrawable background switching status (activated<->normal) when I internally invoke FlexibleViewHolder.toggleSelection(), so that, all inner views can complete animations with no interruptions.

Note:

  • The cached ViewHolders are removed when they are recycled by the RecyclerView.
  • The ViewHolders must extend FlexibleViewHolder, otherwise, item binding still occurs.

Method B (classic)

You override and implement getItemViewType(), onCreateViewHolder() and onBindViewHolder() adapter methods as usual.

Note: If you don't want to adopt item interfaces, you have to override these 3 Adapter methods, otherwise the Adapter enters in AutoMap mode dedicated for item interfaces, throwing an exception!

For multiple view types you still need to add a switch statement in the 3 methods and cast the specific item where necessary.
A difference with others libraries, is that you don't have different names for Creation and Binding methods, because you have item interfaces, therefore, the method B is become (in my opinion) obsolete in case of multiple types, but it can still be used in case of 1 type.

ViewHolders are as well defined all in the same Adapter class. But, others extra attentions to take care, are:

  • To map the correct itemView activation during scrolling based on the current item selection.
  • To map the correct elevation, if any.
  • In case of Endless Scroll, to call onLoadMore(position);
  • In case of Scroll Animation, to call animateView(holder, position);

Clone this wiki locally