2014-01-30 21 views
0

我在C#中编写我的应用程序(使用monodroid),但我认为这个问题可以适用于普通的android java到。在gridview中的对号出现在随机项目

我有一个gridview,如果用户触摸一个瓷砖或物品我想勾选出现,如果他们触摸一个选中的瓷砖,我想勾选消失。我遇到的问题是,如果用户触摸一个图块,然后向下滚动,则该复选图案将出现在随机图块上。我知道这与Android回收视图的事实有关,但我无法弄清楚如何解决它。

这里是我的GridView getview()方法

public override View GetView(int position, View convertView, ViewGroup parent) 
    { 

     File f = files[position]; 

     ViewHolder holder; 

     if (convertView == null) 
     { 
      LayoutInflater li = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService); 
      convertView = li.Inflate(Resource.Layout.gallery_item, parent, false) as LinearLayout; 

      holder = new ViewHolder(); 

      holder.iv = convertView.FindViewById(Resource.Id.ivGalleryItem) as ImageView; 
      holder.iv.SetScaleType(ImageView.ScaleType.CenterCrop); 

      holder.ivCheck = convertView.FindViewById<ImageView>(Resource.Id.ivCheck); 

      convertView.SetTag(Resource.Layout.gallery_item, holder); 

// *这里就是我说,如果用户触摸瓷砖显示勾选这个瓷砖设置为true检查

  holder.iv.Click += delegate 
      { 

       if (isChecked[position]) 
       { 
        holder.ivCheck.Visibility = ViewStates.Invisible; 
        isChecked[position] = false; 
       } 
       else 
       { 
        holder.ivCheck.Visibility = ViewStates.Visible; 
        isChecked[position] = true; 
       } 

      }; 
     } 
     else 
     { 
      holder = (ViewHolder)convertView.GetTag(Resource.Layout.gallery_item); 
     } 


// **************************here is wherere I say if the tile is true than show the checkmark if it is false dont show it 
     if (isChecked[position]) 
     { 
      holder.ivCheck.Visibility = ViewStates.Visible; 
     } 
     else 
     { 
      holder.ivCheck.Visibility = ViewStates.Invisible; 
     } 

     if (f.Exists() && f.IsFile) 
     { 
      getPhotoTask.getphoto(holder.iv, f); 
     } 
     else 
     { 
      holder.iv.SetImageResource(Resource.Drawable.boostitred); 
     } 

     return convertView; 
    } 

回答

1

它看起来像问题是,你只是设置单击监听器的第一个项目是可见的scre恩;当您滚动显示其他项目时,您需要输入convertView != null。 这意味着点击你的一些网格物品(那些在屏幕上开始并在后来出现在屏幕上的物品)将会错误地修改你的isChecked数组。

例如,假设您在屏幕右侧第一次显示12个网格物品。当第一次,convertView == nullGridView电话getView,所以你的代码创建一个新View(在这种情况下LinearLayout),新ViewHolder,并分配一个点击监听器与位置查看0 - 11滚动时,该GridView开始回收现在不在屏幕上的视图,以便在屏幕上创建新视图。在这些情况下,convertView != null,因此您的代码未设置点击侦听器。

我认为,简单的修补程序是这样的:

public override View GetView(int position, View convertView, ViewGroup parent) 
{ 

    File f = files[position]; 

    ViewHolder holder; 

    if (convertView == null) 
    { 
     LayoutInflater li = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService); 
     convertView = li.Inflate(Resource.Layout.gallery_item, parent, false) as LinearLayout; 

     holder = new ViewHolder(); 

     holder.iv = convertView.FindViewById(Resource.Id.ivGalleryItem) as ImageView; 
     holder.iv.SetScaleType(ImageView.ScaleType.CenterCrop); 

     // *Here is where i say if the user touches a tile show a checkmark and set this tile to true for checked 
     holder.ivCheck = convertView.FindViewById<ImageView>(Resource.Id.ivCheck); 

     convertView.SetTag(Resource.Layout.gallery_item, holder); 

    } 
    else 
    { 
     holder = (ViewHolder)convertView.GetTag(Resource.Layout.gallery_item); 
    } 

    holder.iv.Click += delegate 
    { 

     if (isChecked[position]) 
     { 
      holder.ivCheck.Visibility = ViewStates.Invisible; 
      isChecked[position] = false; 
     } 
     else 
     { 
      holder.ivCheck.Visibility = ViewStates.Visible; 
      isChecked[position] = true; 
     } 

    }; 

    // **************************here is wherere I say if the tile is true than show the checkmark if it is false dont show it 
    if (isChecked[position]) 
    { 
     holder.ivCheck.Visibility = ViewStates.Visible; 
    } 
    else 
    { 
     holder.ivCheck.Visibility = ViewStates.Invisible; 
    } 

    if (f.Exists() && f.IsFile) 
    { 
     getPhotoTask.getphoto(holder.iv, f); 
    } 
    else 
    { 
     holder.iv.SetImageResource(Resource.Drawable.boostitred); 
    } 

    return convertView; 
} 

正如你所看到的,我干脆搬到你Click代表的设定初始的if/else之外。

但是,在Android世界中,我们通常不会在适配器中设置点击侦听器。相反,GridView和任何AdapterView就此而言,都有一个名为setOnItemClickListener(AdapterView.OnItemClickListener listener)的方法。只要网格项被点击,该方法就会被调用。此时,您可以更新您的isChecked阵列,例如,该阵列可能是Fragment的成员,而不是适配器。