调用notifyDataSetChanged时,GridView顺序发生了变化

时间:2012-10-01 08:40:40

标签: android gridview

我想在android中使用GridView创建月历。 这是我的代码:(抱歉我的命名) 活动类:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_month_calendar);

    GridView calendar = (GridView) findViewById(R.id.month_view);
    final List<Item> items = new ArrayList<Item>();
    Item item;
    for (int i = 0; i < 42; i++) {
        item = new Item();
        item.setDay(String.valueOf(i + 1));
        items.add(item);
    }

    List<String> yoteis = new ArrayList<String>();
    yoteis.add("Go to beach");
    items.get(15).setYotei(yoteis);

    final MonthCalendarAdapter adapter = new MonthCalendarAdapter(this, items); 
    calendar.setAdapter(adapter);

    calendar.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int pos,
                long id) {
            Toast.makeText(MonthCalendarActivity.this, "" + pos, Toast.LENGTH_SHORT).show();    
            List<String> newYoteis = new ArrayList<String>();
            newYoteis.add("new yotei");             
            items.get(pos).setYotei(newYoteis);
            adapter.notifyDataSetChanged();
        }

    });
}

适配器:

List<Item> items;
Context mContext;
public MonthCalendarAdapter(Context context,
        List<Item> objects) {
    super(context, 0, objects);
    mContext = context;
    items = objects;
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    MonthCell cell;
    LayoutParams params = new GridView.LayoutParams(65,80);
    if(convertView == null) {
        cell = new MonthCell(mContext, items.get(position));
        cell.setLayoutParams(params);
        cell.setScaleType(ImageView.ScaleType.CENTER_CROP);
    }else {
        convertView.setLayoutParams(params);
        cell = (MonthCell) convertView;
    }

    return cell;
}   

MonthCell类:

public class MonthCell extends ImageView {

    Paint paint;
    Item item;
    public MonthCell(Context context) {
        super(context);
        paint = new Paint();
    }

    public MonthCell(Context context, Item item) {
        this(context);      
        this.item = item;

    }   

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.rgb(0, 176, 240));
        canvas.drawText(item.getDay(), 10, 20, paint);

        List<String> yoteis = item.getYotei();
        if(yoteis != null) {
            if(!yoteis.isEmpty()) {
                setBackgroundResource(R.drawable.cell);

                paint.setColor(Color.rgb(255, 124, 128));
                for(int i = 0; i < yoteis.size(); i++) {
                    canvas.drawText(yoteis.get(i), 10, 20 * (i + 2), paint);
                }
            }
        }
    }   
}

第一次加载Activity时,屏幕是这样的:

1 2 3 4 5 6 7

8 9 10 ....

但是当我点击日历时,订单会改变如下:

42 41 40 39 ....

...

7 6 5 4 3 2 1

(抱歉,由于信誉不足,我无法上传图片) 任何人都可以向我解释为什么会发生这种情况以及如何解决它。 提前谢谢!

2 个答案:

答案 0 :(得分:1)

我认为这是由于convertView的错误使用造成的。通过使用以下getView代码

可以轻松验证此假设
public View getView(int position, View convertView, ViewGroup parent) {
  MonthCell cell;
  LayoutParams params = new GridView.LayoutParams(65,80);
  cell = new MonthCell(mContext, items.get(position));
  cell.setLayoutParams(params);
  cell.setScaleType(ImageView.ScaleType.CENTER_CROP);
  return cell;
}

当请求'position'包含'position'项时,您不能假设convertView已通过。您必须再次正确初始化convertView。

答案 1 :(得分:1)

我认为问题发生在这里

   if(convertView == null) {
    cell = new MonthCell(mContext, items.get(position));
    cell.setLayoutParams(params);
    cell.setScaleType(ImageView.ScaleType.CENTER_CROP);
}else {
    convertView.setLayoutParams(params);
    cell = (MonthCell) convertView;
}

尝试修改如下:

   if(convertView == null) {
       convertView = new MonthCell(mContext, null);
       ((MonthCell)convertView).setLayoutParams(params);
       ((MonthCell)convertView).setScaleType(ImageView.ScaleType.CENTER_CROP);
    }
    ((MonthCell)convertView).setItem(items.get(position));

同样在自定义视图MonthCell中,您应该为字段item生成getter