简体   繁体   中英

Android - scrolling large number of items without Scrollview/Listview/Gridview

I am trying to implement a special custom view that has lots of child views, and I need to implement vertical scrolling.

The ScrollView based approach is too slow since there are too many children to draw. I cannot enable hardware layer as the length of the scrolling content is too long to fit in texture size for HWUI. Software layer also fails with insufficient memory to create such a large layer.

I cannot use Listview & Gridview either for project related matters. So, I think I am going to create listview like functionality by myself.

I know that for this, I have to re-use views. Here is where I have the confusion as to how to proceed. As the content scrolls, I can take a view from top side and move it to bottom. I think there are 3 ways to do this.
1] setTranslateY
2] offsetTopAndBottom
3] change layoutparams top and bottom margins and call requestLayout

But, I am not sure how there are different especially [1] and [2]. Can anybody tell me how [1] and [2] are different and also, guide me on which is the right approach here to implement listview like scrolling, for large number of items.

Thanks, Androbean.

RecyclerView.LayoutManager seems like a possible solution. But it is very difficult to change my design at this time to align with RecyclerView.LayoutManager approach.

So, I have worked out a hack which is doing the job just right for me. Scrolling is perfectly smooth and I didn't have to change a lot of code. Posting it here for my own and others reference.

Basically I create all the child views and do add them to my custom Viewgroup. But then I override the dispatchDraw method to limit drawing to only those that are visible.

No recycling methods are used in this. It is just a huge Viewgroup wrapped inside a Scrollview.

@Override
protected void dispatchDraw(Canvas canvas) {
    int clipSaveCount = canvas.save();
    canvas.clipRect(getScrollX() + getPaddingLeft(), getScrollY() + getPaddingTop(),
            getScrollX() + getRight() - getLeft() - getPaddingRight(),
            getScrollY() + getBottom() - getTop() - getPaddingBottom());

    int rowHeightNoGap = (getHeight() - getPaddingTop() - getPaddingBottom())/mDataScreen.getRowCount();
    int startIndex = Math.max(0, (mScrollPosY - getPaddingTop())/rowHeightNoGap * mDataScreen.getColumnCount()-1);
    int endIndex = Math.min(getChildCount()-1, startIndex + (mDataScreen.getVisibleRowCount()+1) * mDataScreen.getColumnCount());

    final long drawingTime = getDrawingTime();
    for (int i = startIndex; i <= endIndex; i++) {
        drawChild(canvas, getChildAt(i), drawingTime);
    }

    canvas.restoreToCount(clipSaveCount);
}

int mScrollPosY;
public void setScrollPosition(int scrollPosY){
    mScrollPosY = scrollPosY;
    invalidate();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM