As a result, I used a completely different approach. Instead of implementing RecyclerView.ItemDecoration I wrote a subclass of RelativeLayout that can draw a foreground selector. I use this layout as a container for all list items that need a selector at the top.
This approach also works well with rows.
public class SelectorRelativeLayout extends RelativeLayout { public static final int[] ATTRS_LIST_SELECTOR = { android.R.attr.listSelector }; private final Drawable selector; public SelectorRelativeLayout(Context context) { this(context, null); } public SelectorRelativeLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SelectorRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, ATTRS_LIST_SELECTOR, 0, 0); selector = a.getDrawable(0); a.recycle(); if (selector != null) { setWillNotDraw(false); selector.setCallback(this); } } @Override protected void drawableStateChanged() { super.drawableStateChanged(); final Drawable d = selector; if (d != null && d.isStateful()) { d.setState(getDrawableState()); } } @Override public void jumpDrawablesToCurrentState() { super.jumpDrawablesToCurrentState(); final Drawable d = selector; if (d != null) { d.jumpToCurrentState(); } } @Override @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void drawableHotspotChanged(float x, float y) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { return; } super.drawableHotspotChanged(x, y); final Drawable d = selector; if (d != null) { d.setHotspot(x, y); } } @Override public void draw(Canvas canvas) { super.draw(canvas); final Drawable d = selector; if (d != null) { d.setBounds(0, 0, getWidth(), getHeight()); d.draw(canvas); } } @Override protected boolean verifyDrawable(Drawable who) { return who == selector || super.verifyDrawable(who); } }
source share