Android 调用notifyDataSetChanged时GridView顺序已更改
我想在android中使用GridView创建一个月历。 这是我的代码:(对不起我的名字) 活动类别:Android 调用notifyDataSetChanged时GridView顺序已更改,android,gridview,Android,Gridview,我想在android中使用GridView创建一个月历。 这是我的代码:(对不起我的名字) 活动类别: @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_month_calendar); GridView calendar = (GridView) findView
@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();
}
});
}
@覆盖
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u month\u calendar);
GridView日历=(GridView)findViewById(R.id.month\u视图);
最终列表项=新的ArrayList();
项目;
对于(int i=0;i<42;i++){
项目=新项目();
设置日(字符串值为(i+1));
项目。添加(项目);
}
List yoteis=new ArrayList();
添加(“去海滩”);
项目。获取(15)。setYotei(yoteis);
最终MonthCalendarAdapter=新MonthCalendarAdapter(此,项);
calendar.setAdapter(适配器);
calendar.setOnItemClickListener(新的OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父级、视图、int pos、,
长id){
Toast.makeText(MonthCalendarActivity.this,“+pos,Toast.LENGTH_SHORT.show();
List newYoteis=newarraylist();
newYoteis.添加(“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;
}
列表项;
语境;
公共MonthCalendarAdapter(上下文,
列出对象){
超级(上下文,0,对象);
mContext=上下文;
项目=对象;
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
蒙氏细胞;
LayoutParams params=新的GridView.LayoutParams(65,80);
if(convertView==null){
cell=newmonthcell(mContext,items.get(position));
cell.setLayoutParams(params);
cell.setScaleType(ImageView.ScaleType.CENTER\U裁剪);
}否则{
convertView.setLayoutParams(参数);
单元格=(MonthCell)convertView;
}
返回单元;
}
蒙斯凯尔班:
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);
}
}
}
}
}
公共类MonthCell扩展了ImageView{
油漆;
项目;
公共MonthCell(上下文){
超级(上下文);
油漆=新油漆();
}
公共MonthCell(上下文,项){
这(上下文);
this.item=项目;
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
绘制.setColor(Color.rgb(0176240));
drawText(item.getDay(),10,20,paint);
List yoteis=item.getYotei();
if(yoteis!=null){
如果(!yoteis.isEmpty()){
挫折资源(R.drawable.cell);
paint.setColor(Color.rgb(255、124、128));
对于(int i=0;i
第一次加载活动时,屏幕如下所示:
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));
1234567
8910
但当我点击日历时,顺序改变如下:
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));
42 41 40 39
7654321
(抱歉,我无法上传图像,因为我没有足够的声誉)
谁能向我解释一下为什么会发生这种情况以及如何解决它。
提前谢谢 我认为这是由于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;
}
您不能假设请求“位置”时传递的convertView包含“位置”处的项。您必须再次正确初始化convertView 我认为问题发生在这里
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));
此外,在customview
MonthCell
中,您应该为字段项生成getter
谢谢您的回答。我使用了你的代码,它工作正常。但我想知道,在我的情况下,没有办法使用convertView?出于性能原因,您应该使用convertView。但您必须正确初始化它。您的代码以某种方式假设,当调用getView(position,convertView,…)时,convertView包含items.get(position)。这个假设是无效的,因此您必须重新初始化convertView并设置正确的项。jaredzhang先生的建议似乎是使用convertView的一个很好的理想方法,但它仍然不起作用。您能建议我如何正确初始化convertView吗?添加((MonthCell)convertView).setItem(items.get(position));对我来说似乎是正确的。(并删除公共MonthCell(上下文,Item-Item)构造函数并添加一个MontCell.setItem(Item-Item){this.Item=Item;}函数)我试图使用convertView,通过使用您的代码,顺序没有更改,但items.get(position)似乎没有正确获取。当我点击一个项目时,点击了一个单元格,另一个单元格的背景已经改变。我认为,正如@Marc Van Daele先生所说,“您不能假设请求‘位置’时传递的convertView包含‘位置’处的项。”