2015-10-18 193 views
1

我想实现一个特殊的自定义视图,有很多子视图,我需要实现垂直滚动。Android - 滚动大量的项目没有滚动视图/列表视图/ Gridview

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

我不能使用列表视图& Gridview无论是与项目有关的问题。 因此,我认为我将自己创建listview类似的功能。

我知道为此,我必须重新使用视图。 这里是我如何进行混乱。当内容滚动时,我可以从顶端进行查看并将其移至底部。 我认为有3种方法可以做到这一点。
1] setTranslateY
2] offsetTopAndBottom
3]变化layoutparams顶部和底部边缘,并呼吁requestLayout

但是,我不知道怎么有不同的特别是[1] [2]。 有没有人可以告诉我[1]和[2]是如何不同的,并指导我如何实现listview这个正确的方法,就像滚动大量的项目一样。

谢谢, Androbean。

+0

''我知道为此,我必须重新使用视图“'所以使用'RecyclerView'。 docs:“Class Overview 一个灵活的视图,用于为大型数据集提供有限的窗口。” – pskink

+0

我认为Recyclerview也不能使用,因为子项目不完全是垂直列表。我把孩子的观点排列成一个交错的网格。 :( –

+0

请参阅[RecyclerView.LayoutManager](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html) – pskink

回答

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(); 
} 
+0

你在这里修改哪个班级? – ataulm

+0

@ataulm这是包装在Scrollview中的ViewGroup的子类。 –

+0

所以这不会做任何视图回收?如果您可以更新您的答案以明确说明,那就太好了,正如您所提到的,您希望在您的问题中查看回收。 – ataulm