Android GridView正在稍后的索引中加载0索引项';数据集更改时的插槽
使用带有扩展BaseAdapter的GridView,我正在加载包含图像和标题的RelativeLayouts集合。当用户在GridView中单击其中一个项目时,应将其从网格中删除并替换为其后面的项目 这适用于除第一个之外的任何项目(适配器管理的项目的ArrayList中的索引0) 在我正在测试的设备上,当屏幕完全滚动到网格顶部(3列4行),最后一行稍微被切断时,屏幕能够显示12个项目。第五排根本没有显示。在这种情况下,如果单击第一个项目(将其删除),所有项目都将正确填写,但是,第5行的第一个项目(索引12)返回第一个项目(索引0)的视图,而不是索引12处的项目 一些屏幕有助于解释问题: 点击布莱恩·麦克奈特(Brian McKnight)将删除他,贝克和其他人将填补空缺 贝克和其他人一起填写了表格,现在向下滚动到下一行 哦。贝克也在那里。我让它部分滚动,以便您可以看到这两个项目都有贝克图片 向上滚动以使项目12(第5行)不可见,然后向下滚动可更正问题Android GridView正在稍后的索引中加载0索引项';数据集更改时的插槽,android,android-gridview,Android,Android Gridview,使用带有扩展BaseAdapter的GridView,我正在加载包含图像和标题的RelativeLayouts集合。当用户在GridView中单击其中一个项目时,应将其从网格中删除并替换为其后面的项目 这适用于除第一个之外的任何项目(适配器管理的项目的ArrayList中的索引0) 在我正在测试的设备上,当屏幕完全滚动到网格顶部(3列4行),最后一行稍微被切断时,屏幕能够显示12个项目。第五排根本没有显示。在这种情况下,如果单击第一个项目(将其删除),所有项目都将正确填写,但是,第5行的第一个项
public class PopularArtistsGridAdapter extends BaseAdapter {
private ArrayList<ArtistsListItem> mArtists = new ArrayList<ArtistsListItem>();
private LayoutInflater mInflater;
private Context mContext;
private int mRemovedIndex = -1;
private int mRefresher = -1;
private int mLastVisible = -1;
public PopularArtistsGridAdapter(Context context) {
mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setItems(ArrayList<ArtistsListItem> artists) {
if(artists == null)
throw new NullPointerException();
mArtists = artists;
notifyDataSetChanged();
}
@Override
public int getCount() {
return mArtists.size();
}
public void removeItem(int position, int lastVisible) {
mLastVisible = lastVisible;
mRemovedIndex = position;
mRefresher = mRemovedIndex;
mArtists.remove(position);
notifyDataSetChanged();
}
public void addItem(int position) {
ArtistsListItem item = getItem(position);
mArtists.add(0, item);
notifyDataSetChanged();
}
@Override
public ArtistsListItem getItem(int position) {
return mArtists.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private void iterateRefresher() {
mRefresher++;
if(mRefresher > mLastVisible) {
mRemovedIndex = -1;
mRefresher = -1;
mLastVisible = -1;
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ArtistsListItem item = getItem(position);
if(convertView == null)
convertView = mInflater.inflate(R.layout.popular_artist_item, null);
final TextView tv = (TextView) convertView.findViewById(R.id.pai_stupid_bubble_button);
final ImageView iv = (ImageView) convertView.findViewById(R.id.pai_image);
final BitmapDrawable drawable = DrawableManager.fetchBitmapDrawable(mContext, item.getImageURL(), true, false);
iv.invalidate();
tv.invalidate();
if(mRefresher >= 0 && position >= mRefresher) {
Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.grid_item_fadein);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
iv.setImageDrawable(drawable);
tv.setText(item.getName());
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
}
});
anim.setStartOffset(300 + (50 * (position - mRemovedIndex)));
convertView.startAnimation(anim);
iterateRefresher();
}
else {
iv.setImageDrawable(drawable);
tv.setText(item.getName());
}
return convertView;
}
}
网格中任何其他项的此过程都正常工作,只有项0。我做了一些记录,发现了一些东西:
- 对象0的getView(…)方法调用很多。当网格第一次加载时,将调用3次,而所有其他项仅调用一次
- 删除项目0以外的项目时,将调用位置0的getView(…)19次。3,然后在调用其他对象的所有getView(…)方法之后再调用16次
- 删除项目0时,向下滚动到第5行(项目12)后,将调用0的getView(…)方法两次。我认为这就是问题发生的地方,因为有时如果你能看到正确的项目在被项目@position 0覆盖之前开始加载
public class PopularArtistsGridAdapter extends BaseAdapter {
private ArrayList<ArtistsListItem> mArtists = new ArrayList<ArtistsListItem>();
private LayoutInflater mInflater;
private Context mContext;
private int mRemovedIndex = -1;
private int mRefresher = -1;
private int mLastVisible = -1;
public PopularArtistsGridAdapter(Context context) {
mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setItems(ArrayList<ArtistsListItem> artists) {
if(artists == null)
throw new NullPointerException();
mArtists = artists;
notifyDataSetChanged();
}
@Override
public int getCount() {
return mArtists.size();
}
public void removeItem(int position, int lastVisible) {
mLastVisible = lastVisible;
mRemovedIndex = position;
mRefresher = mRemovedIndex;
mArtists.remove(position);
notifyDataSetChanged();
}
public void addItem(int position) {
ArtistsListItem item = getItem(position);
mArtists.add(0, item);
notifyDataSetChanged();
}
@Override
public ArtistsListItem getItem(int position) {
return mArtists.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
private void iterateRefresher() {
mRefresher++;
if(mRefresher > mLastVisible) {
mRemovedIndex = -1;
mRefresher = -1;
mLastVisible = -1;
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ArtistsListItem item = getItem(position);
if(convertView == null)
convertView = mInflater.inflate(R.layout.popular_artist_item, null);
final TextView tv = (TextView) convertView.findViewById(R.id.pai_stupid_bubble_button);
final ImageView iv = (ImageView) convertView.findViewById(R.id.pai_image);
final BitmapDrawable drawable = DrawableManager.fetchBitmapDrawable(mContext, item.getImageURL(), true, false);
iv.invalidate();
tv.invalidate();
if(mRefresher >= 0 && position >= mRefresher) {
Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.grid_item_fadein);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
iv.setImageDrawable(drawable);
tv.setText(item.getName());
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
}
});
anim.setStartOffset(300 + (50 * (position - mRemovedIndex)));
convertView.startAnimation(anim);
iterateRefresher();
}
else {
iv.setImageDrawable(drawable);
tv.setText(item.getName());
}
return convertView;
}
}
公共类PopularTistsGridAdapter扩展了BaseAdapter{
private ArrayList mArtists=new ArrayList();
私人停车场;
私有上下文;
私有int mRemovedIndex=-1;
private int mRefresher=-1;
private int mLastVisible=-1;
公共PopularTistsGridAdapter(上下文){
mContext=上下文;
mInflater=(LayoutInflater)context.getSystemService(context.LAYOUT\u充气机\u服务);
}
公共无效集合项(ArrayList艺术家){
如果(艺术家==null)
抛出新的NullPointerException();
火星人=艺术家;
notifyDataSetChanged();
}
@凌驾
public int getCount(){
返回mArtists.size();
}
public void removietem(int position,int lastVisible){
mLastVisible=lastVisible;
mRemovedIndex=位置;
mRefresher=mRemovedIndex;
移除(位置);
notifyDataSetChanged();
}
公共无效附加项(内部位置){
ArtistsListItem=getItem(位置);
添加(0,项目);
notifyDataSetChanged();
}
@凌驾
公共艺术人员StitItem getItem(内部位置){
返回火星人。获取(位置);
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
私有void迭代器刷新器(){
mRefresher++;
如果(mRefresher>mLastVisible){
mRemovedIndex=-1;
mRefresher=-1;
mLastVisible=-1;
}
}
@凌驾
公共视图getView(最终整数位置、视图转换视图、视图组父视图){
最终艺人项目=获取项目(位置);
if(convertView==null)
convertView=mInflater.inflate(R.layout.popular\u艺术家项目,空);
最终文本视图tv=(文本视图)convertView.findViewById(R.id.pai\u dumble\u bubble\u按钮);
最终ImageView iv=(ImageView)convertView.findViewById(R.id.pai_图像);
final BitmapDrawable drawable=DrawableManager.fetchBitmapDrawable(mContext,item.getImageURL(),true,false);
iv.使无效();
tv.invalidate();
如果(mRefresher>=0&&position>=mRefresher){
动画动画=AnimationUtils.loadAnimation(mContext,R.anim.grid\u item\u fadein);
anim.setAnimationListener(新的AnimationListener(){
@凌驾
onAnimationStart上的公共无效(动画){
iv.设置图像可绘制(可绘制);
tv.setText(item.getName());
}
@凌驾
onAnimationRepeat上的公共无效(动画){
//TODO自动生成的方法存根
}
@凌驾
onAnimationEnd上的公共无效(动画){
//TODO自动生成的方法存根
}
});
动画设置开始偏移量(300+(50*(位置-mRemovedIndex));
convertView.startAnimation(动画);
迭代器刷新器();
}
否则{
iv.设置图像可绘制(可绘制);
tv.setText(item.getName());
}
返回视图;
}
}
我制作了一个刷新器,在替换移除的项目时,允许屏幕上所有可见的项目淡入。如果有人
class MyAnimationListener extends AnimationListener {
private int positionToMutate;
public MyAnimationListener(int positionToMutate) {
this.positionToMutate = positionToMutate;
}
@Override
public void onAnimationStart(Animation animation) {
Integer viewPosition = (Integer)localConvertView.getTag(); // add this to getView as final View localConvertView
if (positionToMutate == viewPosition) {
iv.setImageDrawable(drawable);
tv.setText(item.getName());
}
}
// rest of the methods
}
final View localConvertView = convertView;
localConvertView.setTag(new Integer(position));