GridView.getFirstVisiblePosition()是错误的

时间:2011-05-19 03:20:59

标签: android

我有一个GridView,每行有4个图像,并且通常只有少于5行,一次适合屏幕。

最初,每次重新生成内容时,它都会重置回顶部。所以,我从有关ListAdapter的帖子中得到了一个提示,并提出了以下内容:

  • 在重新生成GridView之前,我注意到当前的getFirstVisiblePosition()的值。

  • 重新生成后,我使用之前从getFirstVisiblePosition()获得的值调用setSelection()。

问题是,每次重新生成GridView时,它都向后滚动一行直到它到达顶部。看起来无论出于何种原因,如果第一行或第二行是可见的第一行,则返回0,然后返回n-4(每行有4个项目)。

示例:

第1行是第一个可见行:返回0

第2行是第一个可见行:返回0

第3行是第一个可见行:返回4

第4行是第一个可见行:返回8

作为次要问题,第一次调用setSelection()会使其在用户没有将其保持在正确位置时捕捉。有没有办法只问Android,“当前GridView被用户滚动了多少像素”,后来告诉它,“将这个新渲染的GridView向下滚动N个像素”,这样就可以了元素可能会改变,但网格本身会显得稳定并保持在更新前用户留下的相同位置?

示例代码:

// (uList = List<User>;)

// see what the current gridview's top position is
// returns 0 for rows zero and one,
// returns n-4 for rows two and beyond (n = row x 4)
int idx = gridview.getFirstVisiblePosition();

gridview.setAdapter(new ImageAdapter(TabViewActivity.this, uList));
// ImageAdapter is subclass of BaseAdapter
// if it matters, it's populating View with slightly-hacked Droid-Fu 
// WebImageView objects (the official version doesn't support overlaying
// bitmaps, and has its own LayoutParams hardcoded).

// restore the previous incarnation's top position
// the "+4" is a nasty hack to make it sort of work for all rows but the first 
gridview.setSelection(idx+4);


public class ImageAdapter extends BaseAdapter {
    // ...
    public View getView(int position, View v, ViewGroup parent) {
        User u = userList.get(position); 
        LayoutParams lp = new LayoutParams(70,70);
        lp.gravity = Gravity.CENTER;
        IBitmapFilter filter = new UserBitmapFilter(u, overlays);
        StyledWebImageView w = new StyledWebImageView(context, u.getIconUrl(app), true, lp, filter);
        w.setTag(u);
        return w;
    }
}

更新:接受的答案并不能说明问题,但无论如何都帮助我解决了问题。

最后,我通过重复使用ImageAdapter对象而不是每次更改基础内容时生成新对象来解决问题。它解决了这个问题。以上所有代码基本上都被替换为:

if (gridviewImageAdapter.update(uList))
    gridviewImageAdapter.notifyDataSetChanged();

并向ImageAdapter类添加一个方法:

public boolean update(List<User> uList) {
   // make backup copy of the old list
   // replace the values
   // compare old and new lists, return true if different.
}

1 个答案:

答案 0 :(得分:0)

您只需拨打notifyDataSetChanged()上的Adapter即可反映列表中数据的变化。

您如何重新生成视图?

听起来你正在反对框架而不是使用它。观看this video,有助于解释ListView以及更新Adapter的观看次数。我发现它真的很有帮助。