I found the best and kind of official solution for this. Override this 3 methods of RecyclerView. Which play most important role for fading edge.
First create your recyclerView.
public class MyRecyclerView extends RecyclerView {
// ... required constructor
@Override
protected boolean isPaddingOffsetRequired() {
return true;
}
@Override
protected int getTopPaddingOffset() {
return -getPaddingTop();
}
@Override
protected int getBottomPaddingOffset() {
return getPaddingBottom();
}
}
That's it. Use this recyclerview and you will see fadding edge unaffected.
Following content is just for explanation. If you want to know behind the scene.
To understand how this edge effect is working I dig into the class where android:requiresFadingEdge is used, And I found that it's not handled by RecyclerView instead It's handled by View class which is parent for all view.
In onDraw method of View class I found the code for drawing fade edge by using help of this method isPaddingOffsetRequired. Which used only for handling the fade effect.
According to documentation this method should be overridden by child class If you want to change the behaviour of fading edge. Bydefault It return false. So By returning true we are asking view to apply some offset for edge at the time of view drawing.
Look following snippet of onDraw method of View class to understand the calculation.
final boolean offsetRequired = isPaddingOffsetRequired();
if (offsetRequired) {
paddingLeft += getLeftPaddingOffset();
}
int left = mScrollX + paddingLeft;
int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
int top = mScrollY + getFadeTop(offsetRequired);
int bottom = top + getFadeHeight(offsetRequired);
if (offsetRequired) {
right += getRightPaddingOffset();
bottom += getBottomPaddingOffset();
}
As we can see top variable is initialize using getFadeTop(offsetRequired).
protected int getFadeTop(boolean offsetRequired) {
int top = mPaddingTop;
if (offsetRequired) top += getTopPaddingOffset();
return top;
}
In this method, top is calculated by adding value of topOffSet when offset is needed. So to reverse the effect we need to pass negative value of padding which you are passing. so we need to return -getPaddingTop().
Now for bottom we are not passing negative value because bottom is working on top + height. So passing negative value make fade more shorter from the bottom so we need to add bottom padding to make it proper visible.
You can override this 4 method to play with it. getLeftPaddingOffset(), getRightPaddingOffset(), getTopPaddingOffset(), getBottomPaddingOffset()