davideas / FlexibleAdapter

Fast and versatile Adapter for RecyclerView which regroups several features into one library to considerably improve the user experience :-)
Apache License 2.0
3.56k stars 552 forks source link

Elevation is not applied correctly with getActivationElevation #761

Open dzielins42 opened 4 years ago

dzielins42 commented 4 years ago

Hello, I came up with an issue. I've tried to implement simple list with draggable items. Dragged item has to have elevation (shadow). I've tried to use getActivationElevation but it does not work as described in wiki.

According to Wiki, getActivationElevation returns value of desired elevation when view is activated (eg. dragged), however this value is not applied correctly.

I've done some investigation myself. FlexibleViewHolder.toggleActivation correctly calls ViewCompat.setElevation with value from getActivationElevation. However, this is quickly overwritten by ItemTouchUIUtilImpl.onDraw. The new elevation value is 1f + findMaxElevation(...), and findMaxElevation ignores dragged item. This means that, if my base items have no elevation, dragged item will have elevation 1f no matter what value is returned by getActivationElevation.

This is easily reproducible in demo app, just change value returned in Simple.getActivationElevation to see that it has no effect or remove elevation from root RelativeLayout in recycler_header_item.xml to see that it will change elevation of item to 1f.

dzielins42 commented 4 years ago

There is a rather hacky way to walk around it. Implementing getActivationElevation as below will trick ItemTouchUIUtilImpl.

@Override
public float getActivationElevation() {
   itemView.setTag(R.id.item_touch_helper_previous_elevation,50f);
   return (Float)itemView.getTag(R.id.item_touch_helper_previous_elevation);
}