@Override
  public void getItemOffsets(
      Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    if (mDivider == null) {
      return;
    }

    int position = parent.getChildAdapterPosition(view);
    if (position == RecyclerView.NO_POSITION || (position == 0 && !mShowFirstDivider)) {
      return;
    }

    if (mOrientation == -1) getOrientation(parent);

    if (mOrientation == LinearLayoutManager.VERTICAL) {
      outRect.top = mDivider.getIntrinsicHeight();
      if (mShowLastDivider && position == (state.getItemCount() - 1)) {
        outRect.bottom = outRect.top;
      }
    } else {
      outRect.left = mDivider.getIntrinsicWidth();
      if (mShowLastDivider && position == (state.getItemCount() - 1)) {
        outRect.right = outRect.left;
      }
    }
  }
    @Override
    public void onMeasure(
        RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {

      View view = null;

      if (state.getItemCount() > 0) {
        view = recycler.getViewForPosition(0);
      }

      int height = 0;
      int width = 0;

      if (view != null) {
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec =
            ViewGroup.getChildMeasureSpec(
                widthSpec, getPaddingLeft() + getPaddingRight(), params.width);
        int childHeightSpec =
            ViewGroup.getChildMeasureSpec(
                heightSpec, getPaddingTop() + getPaddingBottom(), params.height);
        view.measure(childWidthSpec, childHeightSpec);
        width = view.getMeasuredWidth() + params.leftMargin + params.rightMargin;
        height = view.getMeasuredHeight() + params.bottomMargin + params.topMargin;
        recycler.recycleView(view);
      }

      setMeasuredDimension(width, height);
    }
  @Override
  public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (mDivider == null) {
      super.onDrawOver(c, parent, state);
      return;
    }

    // Initialization needed to avoid compiler warning
    int left = 0, right = 0, top = 0, bottom = 0, size;
    int orientation = mOrientation != -1 ? mOrientation : getOrientation(parent);
    int childCount = parent.getChildCount();

    if (orientation == LinearLayoutManager.VERTICAL) {
      size = mDivider.getIntrinsicHeight();
      left = parent.getPaddingLeft();
      right = parent.getWidth() - parent.getPaddingRight();
    } else { // horizontal
      size = mDivider.getIntrinsicWidth();
      top = parent.getPaddingTop();
      bottom = parent.getHeight() - parent.getPaddingBottom();
    }

    for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) {
      View child = parent.getChildAt(i);
      RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

      if (orientation == LinearLayoutManager.VERTICAL) {
        top = child.getTop() - params.topMargin - size;
        bottom = top + size;
      } else { // horizontal
        left = child.getLeft() - params.leftMargin;
        right = left + size;
      }
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(c);
    }

    // show last divider
    if (mShowLastDivider && childCount > 0) {
      View child = parent.getChildAt(childCount - 1);
      if (parent.getChildAdapterPosition(child) == (state.getItemCount() - 1)) {
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
        if (orientation == LinearLayoutManager.VERTICAL) {
          top = child.getBottom() + params.bottomMargin;
          bottom = top + size;
        } else { // horizontal
          left = child.getRight() + params.rightMargin;
          right = left + size;
        }
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
      }
    }
  }
Пример #4
0
    @Override
    public void onMeasure(
        RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
      int[] mMeasuredDimension = new int[2];
      final int widthMode = View.MeasureSpec.getMode(widthSpec);
      final int heightMode = View.MeasureSpec.getMode(heightSpec);
      final int heightSize = View.MeasureSpec.getSize(heightSpec);
      int width = 0;
      int height = 0;
      LogUtils.d("state:" + state.toString());
      for (int i = 0; i < getItemCount(); i++) {
        try {
          measureScrapChild(
              recycler,
              i,
              widthSpec,
              View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
              mMeasuredDimension);
        } catch (IndexOutOfBoundsException e) {
          e.printStackTrace();
        }
        if (getOrientation() == HORIZONTAL) {
          width = width + mMeasuredDimension[0];
          if (i == 0) {
            height = mMeasuredDimension[1];
          }
        } else {
          height = height + mMeasuredDimension[1];
          if (i == 0) {
            width = mMeasuredDimension[0];
          }
        }
      }

      switch (widthMode) {
        case View.MeasureSpec.EXACTLY:
        case View.MeasureSpec.AT_MOST:
        case View.MeasureSpec.UNSPECIFIED:
      }

      switch (heightMode) {
        case View.MeasureSpec.EXACTLY:
          height = heightSize;
        case View.MeasureSpec.AT_MOST:
        case View.MeasureSpec.UNSPECIFIED:
      }
      setMeasuredDimension(widthSpec, height);
    }
  @Override
  public void onMeasure(
      RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
    final int widthMode = View.MeasureSpec.getMode(widthSpec);
    final int heightMode = View.MeasureSpec.getMode(heightSpec);

    final int widthSize = View.MeasureSpec.getSize(widthSpec);
    final int heightSize = View.MeasureSpec.getSize(heightSpec);

    final boolean hasWidthSize = widthMode != View.MeasureSpec.UNSPECIFIED;
    final boolean hasHeightSize = heightMode != View.MeasureSpec.UNSPECIFIED;

    final boolean exactWidth = widthMode == View.MeasureSpec.EXACTLY;
    final boolean exactHeight = heightMode == View.MeasureSpec.EXACTLY;

    final int unspecified = makeUnspecifiedSpec();

    if (exactWidth && exactHeight) {
      // in case of exact calculations for both dimensions let's use default "onMeasure"
      // implementation
      super.onMeasure(recycler, state, widthSpec, heightSpec);
      return;
    }

    final boolean vertical = getOrientation() == VERTICAL;

    initChildDimensions(widthSize, heightSize, vertical);

    int width = 0;
    int height = 0;

    // it's possible to get scrap views in recycler which are bound to old (invalid) adapter
    // entities. This
    // happens because their invalidation happens after "onMeasure" method. As a workaround let's
    // clear the
    // recycler now (it should not cause any performance issues while scrolling as "onMeasure" is
    // never
    // called whiles scrolling)
    recycler.clear();

    final int stateItemCount = state.getItemCount();
    final int adapterItemCount = getItemCount();
    // adapter always contains actual data while state might contain old data (f.e. data before the
    // animation is
    // done). As we want to measure the view with actual data we must use data from the adapter and
    // not from  the
    // state
    for (int i = 0; i < adapterItemCount; i++) {
      if (vertical) {
        if (!hasChildSize) {
          if (i < stateItemCount) {
            // we should not exceed state count, otherwise we'll get IndexOutOfBoundsException. For
            // such items
            // we will use previously calculated dimensions
            measureChild(recycler, i, widthSize, unspecified, childDimensions);
          } else {
            logMeasureWarning(i);
          }
        }
        height += childDimensions[CHILD_HEIGHT];
        if (i == 0) {
          width = childDimensions[CHILD_WIDTH];
        }
        if (hasHeightSize && height >= heightSize) {
          break;
        }
      } else {
        if (!hasChildSize) {
          if (i < stateItemCount) {
            // we should not exceed state count, otherwise we'll get IndexOutOfBoundsException. For
            // such items
            // we will use previously calculated dimensions
            measureChild(recycler, i, unspecified, heightSize, childDimensions);
          } else {
            logMeasureWarning(i);
          }
        }
        width += childDimensions[CHILD_WIDTH];
        if (i == 0) {
          height = childDimensions[CHILD_HEIGHT];
        }
        if (hasWidthSize && width >= widthSize) {
          break;
        }
      }
    }

    if (exactWidth) {
      width = widthSize;
    } else {
      width += getPaddingLeft() + getPaddingRight();
      if (hasWidthSize) {
        width = Math.min(width, widthSize);
      }
    }

    if (exactHeight) {
      height = heightSize;
    } else {
      height += getPaddingTop() + getPaddingBottom();
      if (hasHeightSize) {
        height = Math.min(height, heightSize);
      }
    }

    setMeasuredDimension(width, height);

    if (view != null && overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS) {
      final boolean fit =
          (vertical && (!hasHeightSize || height < heightSize))
              || (!vertical && (!hasWidthSize || width < widthSize));

      ViewCompat.setOverScrollMode(
          view, fit ? ViewCompat.OVER_SCROLL_NEVER : ViewCompat.OVER_SCROLL_ALWAYS);
    }
  }