Android - 在没有Scrollview / Listview / Gridview的情况下滚动大量项目

时间:2015-10-18 04:59:56

标签: android android-view

我正在尝试实现一个包含大量子视图的特殊自定义视图,我需要实现垂直滚动。

基于ScrollView的方法太慢,因为要绘制太多孩子。我无法启用硬件层,因为滚动内容的长度太长而无法适应HWUI的纹理大小。软件层也因内存不足而无法创建如此大的层。

我无法使用Listview& Gridview要么针对项目相关事宜。 所以,我想我将自己创建listview类似的功能。

我知道为此,我必须重新使用观点。 这是我对如何进行的困惑。 当内容滚动时,我可以从顶部拍摄视图并将其移动到底部。 我认为有3种方法可以做到这一点 1] setTranslateY
2] offsetTopAndBottom
3]更改layoutparams上边距和下边距并调用requestLayout

但是,我不确定特别是[1]和[2]有何不同。 任何人都可以告诉我[1]和[2]是如何不同的,并指导我在这里采用正确的方法来实现listview像滚动这样的大量项目。

谢谢, Androbean。

1 个答案:

答案 0 :(得分:0)

RecyclerView.LayoutManager似乎是一种可能的解决方案。但目前很难改变我的设计以与RecyclerView.LayoutManager方法保持一致。

所以,我已经找到了一个适合我的工作。滚动非常顺利,我没有必要改变很多代码。 将它发布在这里供我自己和其他人参考。

基本上我创建了所有子视图,并将它们添加到我的自定义Viewgroup中。但后来我重写了dispatchDraw方法,将绘图限制为只有那些可见的。

此处不使用回收方法。它只是一个巨大的Viewgroup包裹在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();
}