2012-03-17 51 views
4

我有一個自定義ListViewAdapter,我正在爲列表創建行。我的問題是,它似乎並沒有區分對方。這似乎是隨機挑選ImageViews當我上下滾動時卡入到位。文本信息(從這段代碼中省略)不會中斷。它按照人們的預期工作。自定義ListView適配器,奇怪的ImageView行爲

這裏是我的Adapter的相關方法:

public View getView(int position, View convertView, ViewGroup parent) 
    { 
    View v = convertView; 

    if(v == null) 
    { 
     LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.generic_row, null); 
    } 

    // find the image 
    ImageView favImage = (ImageView)v.findViewById(R.id.toggle_favorite); 

    // when clicked... 
    favImage.setOnClickListener(new OnClickListener() { 

    @Override 
    public void onClick(View v) 
    { 
     // make the gray star a yellow one 
     int newImage = R.drawable.ic_star_yellow_embossed; 
     ((ImageView)v).setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(), newImage)); 
    } 

    }); 

    return v; 
    } 
+0

** ** getView2 ........? – waqaslam 2012-03-17 21:52:57

+0

@Waqas:忽略這一點,那是我在課堂上覆制,粘貼和剝離的東西。它在代碼中正確命名。 – Josh 2012-03-17 21:53:41

回答

3

出現這種行爲,因爲ListView回收行的意見,您滾動列表上下,正因爲如此你行由用戶(圖像發生了變化)所採取行動的圖像應該是未修改的。爲避免這種情況,您必須以某種方式爲列表中的每一行保存ImageView的狀態,並使用此狀態在getView()方法中設置正確的圖像。因爲你沒有說明你是如何實現你的適配器的,我將向你展示一個簡單的例子。

首先你應該存儲你的狀態ImageView。我使用ArrayList<Boolean>作爲自定義適配器的成員,如果該列表中的位置(對應於列表中的行的位置)爲false則圖像爲默認圖像,否則如果是true,則用戶單擊它,我們應該把新形象:

private ArrayList<Boolean> imageStatus = new ArrayList<Boolean>(); 

在您的自定義適配器的構造函數初始化這個名單。在getView()方法

//... initialize the imageStatus, objects is the list on which your adapter is based 
for (int i = 0; i < objects.size(); i++) { 
    imageStatus.add(false); 
} 

然後:例如,如果你把你的適配器的東西名單,那麼你應該讓你的imageStatus那樣大名單,並充滿false(默認/啓動狀態)

View v = convertView; 

      if (v == null) { 
       LayoutInflater vi = (LayoutInflater) getContext() 
         .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = vi.inflate(R.layout.adapters_adapter_with_images, null); 
      } 

      // find the image 
      ImageView favImage = (ImageView) v 
        .findViewById(R.id.toggle_favorite); 
      // Set the image bitmap. If the imageStatus flag for this position is TRUE then we 
      // show the new image because it was previously clicked by the user 
      if (imageStatus.get(position)) { 
       int newImage = R.drawable.ic_star_yellow_embossed; 
       favImage.setImageBitmap(BitmapFactory.decodeResource(
         getContext().getResources(), newImage)); 
      } else { 
       // If the imageStatus is FALSE then we explicitly set the image 
       // back to the default because we could be dealing with a 
       // recycled ImageView that has the new image set(there is no need to set a default drawable in the xml layout)          
       int newImage = R.drawable.basket_empty; //the default image 
       favImage.setImageBitmap(BitmapFactory.decodeResource(
         getContext().getResources(), newImage)); 
      } 
      // when clicked... we get the real position of the row and set to TRUE 
      // that position in the imageStatus flags list. We also call notifyDataSetChanged 
      //on the adapter object to let it know that something has changed and to update! 
      favImage.setOnClickListener(new OnClickListener() { 

       @Override 
       public void onClick(View v) { 
        Integer realPosition = (Integer) v.getTag(); //get the position from the view's tag 
        imageStatus.set(realPosition, true); //this position has been clicked be the user 
        adapter.notifyDataSetChanged(); //notify the adapter 
       } 

      }); 
      // set the position to the favImage as a tag, we later retrieve it 
      // in the onClick method 
      favImage.setTag(new Integer(position)); 
      return v; 

     } 

如果您不打算動態修改列表(刪除/添加行),這應該很好,否則您還必須照顧修改該列表imageStatus以反映更改。你沒有說什麼是你的行數據,另一種方法(如果用戶點擊那個圖像(除了改變它),如果你打算做點什麼)的另一種方法是將圖像的狀態合併到行的數據模型中。對此這裏有一些教程:

Android ListView Advanced InteractiveCommonsware-Android Excerpt(交互式行)

2

你需要找到它的引用後立即定義默認的圖像:

// find the image 
ImageView favImage = (ImageView)v.findViewById(R.id.toggle_favorite); 
//setting to default 
favImage.setImageResource(R.drawable.default_image); 
// when clicked... 
favImage.setOnClickListener.... 

你需要這樣做,因爲一旦圖像更改,並且您滾動ListView,它會重新出現,因爲ListView可以回收項目視圖。因此,你需要在getView來定義它使用的默認圖像當列表滾動

+0

我不明白。我試圖在點擊圖片時執行此操作。我已經在.xml文件中設置了它的默認圖像。 – Josh 2012-03-17 22:01:18

+0

設置它在xml中是一次,這是在'if(v == null)'中實現的,但之後當ListView回收視圖時,它不會從xml讀取,它只是回收視圖,在這種情況下,您的ImageView包含點擊時定義的舊圖像。只需在代碼中設置默認圖像,我相信它會起作用 – waqaslam 2012-03-17 22:04:12