GcsSloop / pager-layoutmanager

[暂停维护]Android 网格分页布局。
http://www.gcssloop.com/
Apache License 2.0
1.14k stars 182 forks source link

AutoSize #21

Open xmutzlq opened 6 years ago

xmutzlq commented 6 years ago

@Override public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {

    // 如果是 preLayout 则不重新布局
    if (state.isPreLayout() || !state.didStructureChange()) {
        return;
    }

    if (getItemCount() == 0) {
        removeAndRecycleAllViews(recycler);
        // 页面变化回调
        setPageCount(0);
        setPageIndex(0, false);
        return;
    } else {
        setPageCount(getTotalPageCount());
        setPageIndex(getPageIndexByOffset(), false);
    }

    // 计算页面数量
    int mPageCount = getItemCount() / mOnePageSize;
    if (getItemCount() % mOnePageSize != 0) {
        mPageCount++;
    }

    // 计算可以滚动的最大数值,并对滚动距离进行修正
    if (canScrollHorizontally()) {
        mMaxScrollX = (mPageCount - 1) * getUsableWidth();
        mMaxScrollY = 0;
        if (mOffsetX > mMaxScrollX) {
            mOffsetX = mMaxScrollX;
        }
    } else {
        mMaxScrollX = 0;
        mMaxScrollY = (mPageCount - 1) * getUsableHeight();
        if (mOffsetY > mMaxScrollY) {
            mOffsetY = mMaxScrollY;
        }
    }

    // 接口回调
    // setPageCount(mPageCount);
    // setPageIndex(mCurrentPageIndex, false);

    if (mItemWidth <= 0) {
        mItemWidth = getUsableWidth() / mColumns;
    }
    if (mItemHeight <= 0) {
        mItemHeight = getUsableHeight() / mRows;
    }

    mWidthUsed = getUsableWidth() - mItemWidth;
    mHeightUsed = getUsableHeight() - mItemHeight;

    // 预存储两页的View显示区域
    for (int i = 0; i < mOnePageSize * 2; i++) {
        getItemFrameByPosition(i);
    }

    if (mOffsetX == 0 && mOffsetY == 0) {
        // 预存储View
        for (int i = 0; i < mOnePageSize; i++) {
            if (i >= getItemCount()) break; // 防止数据过少时导致数组越界异常
            View view = recycler.getViewForPosition(i);
            RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams();
            lp.width = ScreenUtils.getScreenWidth() / mColumns  - (lp.leftMargin + lp.rightMargin) / 2;
            addView(view);
            measureChildWithMargins(view, mWidthUsed, mHeightUsed);
        }
    }

    // 回收和填充布局
    recycleAndFillItems(recycler, state, true);
}

@Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(recycler, state, widthMeasureSpec, heightMeasureSpec); int widthsize = View.MeasureSpec.getSize(widthMeasureSpec); //取出宽度的确切数值 int widthmode = View.MeasureSpec.getMode(widthMeasureSpec); //取出宽度的测量模式

    // 将 wrap_content 转换为 match_parent
    if (widthmode != EXACTLY && widthsize > 0) {
        widthmode = EXACTLY;
    }
    final int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
    final int heightSize = View.MeasureSpec.getSize(heightMeasureSpec);
    int height = 0;
    //自适应高度
    for (int i = 0; i < getItemCount(); i++) {

        try {
            measureScrapChild(recycler, i,
                    widthMeasureSpec,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        }

        if (i == 0) {
            height = mMeasuredDimension[1];
        }
    }

    switch (heightMode) {
        case EXACTLY:
            height = heightSize;
        case View.MeasureSpec.AT_MOST:
        case View.MeasureSpec.UNSPECIFIED:
    }
    setMeasuredDimension(View.MeasureSpec.makeMeasureSpec(widthsize, widthmode), height - 200);
}

private int[] mMeasuredDimension = new int[2];
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) {
    View view = recycler.getViewForPosition(position);
    if (view != null) {
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                getPaddingTop() + getPaddingBottom(), p.height);
        view.measure(widthSpec, childHeightSpec);
        measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
        measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}
xmutzlq commented 6 years ago

性能不是很好!