Android-构建自定义LayoutManager

时间:2019-05-27 11:38:02

标签: android android-layout android-recyclerview

对于我的Android项目,我需要构建一个自定义布局管理器。 因此,我查看了http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/https://developer.inthepocket.mobi/2017/01/04/android-layoutmanager-part-1/

上的帖子

但是我在理解scrollVerticallyBy()(或scrollHorizontally())方法的内部实现时遇到了问题。

从上述文章中我得到的是布局管理器有责任移动视图。为此,RecyclerView为我们提供了可以进行移动的前期信息。该信息是dy(或dx)参数,它告诉我们框架认为我们应该改变观点的程度。 然后,在scrollXBy()方法内部,使用该增量值,我们必须确定某些边界条件。 返回值指定框架我们实际行进/移动的距离。

我不理解这些方法中的计算。来自https://developer.inthepocket.mobi/2017/01/04/android-layoutmanager-part-1/的以下代码段将我的问题显示为注释:

@Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (getChildCount() == 0) {
            return 0;
        }

        int scrolled = 0;
        final int left = getPaddingLeft();
        final int right = getWidth() - getPaddingRight();

        // why we check if dy is less than 0 ?
        if (dy < 0) {

            while (scrolled > dy) {

                // that is clear, we obtain the view at index 0
                final View topView = getChildAt(0);

                // getDecoratedTop() gives us the top edge but why we have a - sign ?
                // why is there a 0 ? what is hangingTop representing ?
                final int hangingTop = Math.max(-getDecoratedTop(topView), 0);

                // why we compute scrolled - dy ? 
                final int scrollBy = Math.min(scrolled - dy, hangingTop);

                // ok, we update our scrolled variable which should tell how far we traveled
                scrolled -= scrollBy;

                // that call is clear. It shifts our views by the given value
                offsetChildrenVertical(scrollBy);

                // ???
                if (mFirstPosition > 0 && scrolled > dy) {
                    mFirstPosition--;
                    View v = recycler.getViewForPosition(mFirstPosition);
                    addView(v, 0);
                    measureChildWithMargins(v, 0, 0);
                    final int bottom = getDecoratedTop(topView);
                    final int top = bottom - getDecoratedMeasuredHeight(v);
                    layoutDecorated(v, left, top, right, bottom);
                } else {
                    break;
                }
            }
        } 

        // I could ask the same questions about the lines of this block, too
        else if (dy > 0) {
            final int parentHeight = getHeight();
            while (scrolled < dy) {
                final View bottomView = getChildAt(getChildCount() - 1);
                final int hangingBottom =
                        Math.max(getDecoratedBottom(bottomView) - parentHeight, 0);
                final int scrollBy = -Math.min(dy - scrolled, hangingBottom);
                scrolled -= scrollBy;
                offsetChildrenVertical(scrollBy);
                if (scrolled < dy && state.getItemCount() > mFirstPosition + getChildCount()) {
                    View v = recycler.getViewForPosition(mFirstPosition + getChildCount());
                    final int top = getDecoratedBottom(getChildAt(getChildCount() - 1));
                    addView(v);
                    measureChildWithMargins(v, 0, 0);
                    final int bottom = top + getDecoratedMeasuredHeight(v);
                    layoutDecorated(v, left, top, right, bottom);
                } else {
                    break;
                }
            }
        }
        recycleViewsOutOfBounds(recycler);
        return scrolled;
    }

因此,总而言之:我可以理解这些方法的用途等等,但是我无法弄清楚它们是如何进行计算的等等。

0 个答案:

没有答案