|
|
@@ -0,0 +1,91 @@
|
|
|
+package me.vadik.knigopis.common;
|
|
|
+
|
|
|
+import android.graphics.Canvas;
|
|
|
+import android.support.annotation.NonNull;
|
|
|
+import android.support.v7.widget.RecyclerView;
|
|
|
+import android.view.LayoutInflater;
|
|
|
+import android.view.View;
|
|
|
+import android.view.ViewGroup;
|
|
|
+
|
|
|
+/**
|
|
|
+ * https://stackoverflow.com/questions/32949971
|
|
|
+ */
|
|
|
+public class HeaderItemDecoration extends RecyclerView.ItemDecoration {
|
|
|
+
|
|
|
+ private StickyHeaderInterface mListener;
|
|
|
+
|
|
|
+ public HeaderItemDecoration(@NonNull StickyHeaderInterface listener) {
|
|
|
+ mListener = listener;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
|
|
+ super.onDrawOver(c, parent, state);
|
|
|
+ View topChild = parent.getChildAt(0);
|
|
|
+ if (topChild == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int topChildPosition = parent.getChildAdapterPosition(topChild);
|
|
|
+ if (topChildPosition == RecyclerView.NO_POSITION) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ View currentHeader = getHeaderViewForItem(topChildPosition, parent);
|
|
|
+ fixLayoutSize(parent, currentHeader);
|
|
|
+ int contactPoint = currentHeader.getBottom();
|
|
|
+ View childInContact = getChildInContact(parent, contactPoint);
|
|
|
+ if (childInContact == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (mListener.isHeader(parent.getChildAdapterPosition(childInContact))) {
|
|
|
+ moveHeader(c, currentHeader, childInContact);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ drawHeader(c, currentHeader);
|
|
|
+ }
|
|
|
+
|
|
|
+ private View getHeaderViewForItem(int itemPosition, RecyclerView parent) {
|
|
|
+ int headerPosition = mListener.getHeaderPositionForItem(itemPosition);
|
|
|
+ int layoutResId = mListener.getHeaderLayout(headerPosition);
|
|
|
+ View header = LayoutInflater.from(parent.getContext()).inflate(layoutResId, parent, false);
|
|
|
+ mListener.bindHeaderData(header, headerPosition);
|
|
|
+ return header;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void drawHeader(Canvas c, View header) {
|
|
|
+ c.save();
|
|
|
+ c.translate(0, 0);
|
|
|
+ header.draw(c);
|
|
|
+ c.restore();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void moveHeader(Canvas c, View currentHeader, View nextHeader) {
|
|
|
+ c.save();
|
|
|
+ c.translate(0, nextHeader.getTop() - currentHeader.getHeight());
|
|
|
+ currentHeader.draw(c);
|
|
|
+ c.restore();
|
|
|
+ }
|
|
|
+
|
|
|
+ private View getChildInContact(RecyclerView parent, int contactPoint) {
|
|
|
+ View childInContact = null;
|
|
|
+ for (int i = 0; i < parent.getChildCount(); i++) {
|
|
|
+ View child = parent.getChildAt(i);
|
|
|
+ if (child.getBottom() > contactPoint) {
|
|
|
+ if (child.getTop() <= contactPoint) {
|
|
|
+ childInContact = child;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return childInContact;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void fixLayoutSize(ViewGroup parent, View view) {
|
|
|
+ int widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
|
|
|
+ int heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
|
|
|
+ int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, parent.getPaddingLeft() + parent.getPaddingRight(), view.getLayoutParams().width);
|
|
|
+ int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, parent.getPaddingTop() + parent.getPaddingBottom(), view.getLayoutParams().height);
|
|
|
+ view.measure(childWidthSpec, childHeightSpec);
|
|
|
+ view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
|
|
|
+ }
|
|
|
+
|
|
|
+}
|