Custom Recyclerview layoutmanager滚动到位置问题

时间:2018-03-18 19:59:48

标签: android android-layout android-recyclerview recyclerview-layout

我的设计需要像这样展示:

enter image description here

我已完成所有更改,但我需要滚动到我点击的位置并且它无法正常工作

public class CircularLayoutManager extends LinearLayoutManager {
private static final int CIRCLE = 0;
private static final int ELLIPSE = 1;
private static final int MILLISECONDS_PER_INCH = 30;

private RecyclerView recyclerView;
private Rect recyclerBounds;

private int topOfFirstChild;

private Rect childDecoratedBoundsWithMargin;
private int verticalCenter;
private boolean scrolled;

private float radius;
private float majorRadius, minorRadius;
private float centerX;

private @LayoutPath int layoutPath;

@IntDef({CIRCLE, ELLIPSE})
@interface LayoutPath {

}

public CircularLayoutManager(Context context, int radius, int centerX) {
    super(context);
    this.radius = Utils.dpToPx(context, radius);
    this.centerX = Utils.dpToPx(context, centerX);

    layoutPath = ELLIPSE;
}

public CircularLayoutManager(Context context, int majorRadius, int minorRadius, int centerX) {
    super(context);
    this.majorRadius = Utils.dpToPx(context, majorRadius);
    this.minorRadius = Utils.dpToPx(context, minorRadius);
    this.centerX = Utils.dpToPx(context, centerX);

    layoutPath = ELLIPSE;
}

@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    if (getItemCount() == 0) {
        detachAndScrapAttachedViews(recycler);
        return;
    }

    if (recyclerBounds == null) {
        recyclerBounds = new Rect();
        recyclerView.getHitRect(recyclerBounds);
        verticalCenter = (recyclerBounds.height() / 2);
    }

    if (getChildCount() == 0) {
        fill(0, recycler);
    }
}

private void fill(int indexToStartFill, RecyclerView.Recycler recycler) {
    if (indexToStartFill < 0) {
        indexToStartFill = 0;
    }

    int childTop = topOfFirstChild;

    detachAndScrapAttachedViews(recycler);

    for (int i = indexToStartFill; i < getItemCount(); i++) {
        View child = recycler.getViewForPosition(i);

        measureChildWithMargins(child, 0, 0);

        int sumOfHorizontalMargins = ((RecyclerView.LayoutParams) child.getLayoutParams()).leftMargin
                + ((RecyclerView.LayoutParams) child.getLayoutParams()).rightMargin;
        int sumOfVerticalMargins = ((RecyclerView.LayoutParams) child.getLayoutParams()).topMargin
                + ((RecyclerView.LayoutParams) child.getLayoutParams()).bottomMargin;

        int childLeft = 0;

        switch (layoutPath) {
            case CIRCLE:
                childLeft = calculateCircleXFromY(childTop + (getDecoratedMeasuredHeight(child) +
                        getTopDecorationHeight(child) - getBottomDecorationHeight(child) + sumOfVerticalMargins) / 2);
                break;
            case ELLIPSE:
                childLeft = calculateEllipseXFromY(childTop + (getDecoratedMeasuredHeight(child) +
                        getTopDecorationHeight(child) - getBottomDecorationHeight(child) + sumOfVerticalMargins) / 2);
                break;
        }

        if (!(recyclerBounds.intersects(recyclerBounds.left + childLeft, recyclerBounds.top + childTop,
                recyclerBounds.left + childLeft + getDecoratedMeasuredWidth(child) + sumOfHorizontalMargins,
                recyclerBounds.top + childTop + getDecoratedMeasuredHeight(child) + sumOfVerticalMargins)
                || recyclerBounds.contains(recyclerBounds.left + childLeft, recyclerBounds.top + childTop,
                recyclerBounds.left + childLeft + getDecoratedMeasuredWidth(child) + sumOfHorizontalMargins,
                recyclerBounds.top + childTop + getDecoratedMeasuredHeight(child) + sumOfVerticalMargins))) {
            break;
        }

        addView(child);

        layoutDecoratedWithMargins(child, childLeft, childTop, childLeft + getDecoratedMeasuredWidth(child)
                + sumOfHorizontalMargins, childTop + getDecoratedMeasuredHeight(child) + sumOfVerticalMargins);

        getDecoratedBoundsWithMargins(child, childDecoratedBoundsWithMargin);

        scaleChild(child);

        childTop += childDecoratedBoundsWithMargin.height();
    }

    List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
    for (int i = 0; i < scrapList.size(); i++) {
        View viewRemoved = scrapList.get(i).itemView;
        recycler.recycleView(viewRemoved);
    }

    if (!scrolled) {
        stabilize();
    }
}

@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
    if (!scrolled) {
        scrolled = true;
    }

    int delta = dy;

    if (delta > 50) {
        delta = 50;
    }

    if (delta < -50) {
        delta = -50;
    }

    if (getChildCount() == 0) {
        return dy;
    }
    System.out.println("Dy:"+dy);

    if (getPosition(getChildAt(getChildCount() - 1)) == getItemCount() - 1) {

        View child = getChildAt(getChildCount() - 1);            getDecoratedBoundsWithMargins(child, childDecoratedBoundsWithMargin);

        if (childDecoratedBoundsWithMargin.bottom - delta < recyclerBounds.height()) {
            int position = recyclerBounds.height();
            int indexToStartFill = getPosition(getChildAt(0));

            for (int i = getChildCount() - 1; i >= 0; i--) {
                getDecoratedBoundsWithMargins(getChildAt(i), childDecoratedBoundsWithMargin);

                position -= childDecoratedBoundsWithMargin.height();

                if (position <= 0) {
                    topOfFirstChild = position;
                    if (topOfFirstChild <= -childDecoratedBoundsWithMargin.height()) {
                        topOfFirstChild += childDecoratedBoundsWithMargin.height();
                    }
                    indexToStartFill = getPosition(getChildAt(i));
                    if (indexToStartFill >= getItemCount()) {
                        indexToStartFill = getItemCount() - 1;
                    }
                    break;
                }
            }

            fill(indexToStartFill, recycler);
            return 0;
        }
    }

    topOfFirstChild -= delta;

    getDecoratedBoundsWithMargins(getChildAt(0), childDecoratedBoundsWithMargin);

    int indexToStartFill = getPosition(getChildAt(0));

    if (topOfFirstChild > 0) {
        topOfFirstChild -= childDecoratedBoundsWithMargin.height();
        indexToStartFill--;
        if (indexToStartFill == -1) {
            topOfFirstChild = 0;
            fill(0, recycler);
            return 0;
        }
    } else if (topOfFirstChild <= -childDecoratedBoundsWithMargin.height()) {
        topOfFirstChild += childDecoratedBoundsWithMargin.height();
        indexToStartFill++;
    }

    fill(indexToStartFill, recycler);

    return dy;
}

}

主要内容如下:

    recyclerView.setAdapter(new RecyclerViewAdapter(getApplicationContext(), list));
    recyclerView.addItemDecoration(new RecyclerItemDecoration());
    layoutManager = new CircularLayoutManager(getApplicationContext(), 350, 0);
    recyclerView.setLayoutManager(layoutManager);

Full Source Code

我需要在首次加载时移除顶部填充,当用户单击列表时,我需要将项目移动到中心。

0 个答案:

没有答案