2014-01-30 22 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的成員,而不是適配器。