2012-04-14 56 views
0

作爲我的第一個Android項目,我創建了一個應用程序,允許用戶顯示來自Magic The Gathering交易卡遊戲的卡片。Android ArrayAdapter getView問題,以避免多次調用

我在我的ArrayAdapter中遇到了一個問題,它在列表視圖中顯示卡片數組(根據版本)。

我正在讀取一個字符串,例如:{2} {B} {B}併爲每個字符創建ImageView ..我將這些ImageView添加到列表中的LinearLayout顯示中。

問題是每次調用過程getView()都會被調用,所以只要向下滾動我的列表,ImageView的數量就會不斷增加。 我想這個過程被稱爲一勞永逸。

任何幫助都會很友善。 如果您需要更多信息,請不要猶豫。

謝謝! Rudz

package rudy.jaumain.mtgdb; 

import java.util.ArrayList; 

import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.content.Context; 
import android.widget.TextView; 
import android.graphics.Color; 


public class MTGSetListAdapter extends ArrayAdapter<MTGCard> { 

    private ArrayList<MTGCard> set; 

    public MTGSetListAdapter(Context c, int resource, int textViewResourceId, ArrayList<MTGCard> set){ 
     super(c, resource, textViewResourceId, set); 
     this.set = set; 
    } 

    static class ViewHolder{ 
     TextView name; 
     ImageView rarity; 
     LinearLayout manacost; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 



     ViewHolder holder; 
     if(convertView == null){ 
      convertView = super.getView(position, convertView, parent); 
      System.out.println("CONVERTVIEW IS NULL"); 
      holder = new ViewHolder(); 

      holder.name = (TextView)convertView.findViewById(R.id.editionlist_item_name); 
      holder.rarity = (ImageView)convertView.findViewById(R.id.editionlist_item_rarity); 
      holder.manacost = (LinearLayout)convertView.findViewById(R.id.editionlist_item_manacost); 

      convertView.setTag(holder); 
     } 
     else{ 
      System.out.println("CONVERTVIEW IS NOT NULL"); 
      holder = (ViewHolder)convertView.getTag(); 
     } 

     MTGCard currentCard = this.set.get(position); 
     if(currentCard != null){ 
      holder.name.setText(currentCard.getName()); 
      holder.name.setTextColor(Color.BLACK); 
      //Manacost example : {2}{B}{B} 
      String manacostStr = currentCard.getManacost();  
      int i=0; 
      String currentMana = null; 
      while(i < manacostStr.length()){ 
       char currentChar = manacostStr.charAt(i); 
       if(currentChar == '{'){ 
        currentMana = null; 
       } 
       else 
       { 
        if(currentChar == '}'){ 
         ImageView iv = new ImageView(getContext()); 
         int idMana = getContext().getResources().getIdentifier("mana_"+currentMana.toLowerCase(), "drawable", getContext().getPackageName()); 
         iv.setImageResource(idMana); 
         iv.setAdjustViewBounds(true); 
         holder.manacost.addView(iv); 
         currentMana = null; 
        } 
        else{ 
         if(currentMana == null){ 
          currentMana = String.valueOf(currentChar); 
         } 
         else{ 
          currentMana += String.valueOf(currentChar); 
         } 
        } 
       } 
       i++; 
      } 

      String rarityStr = currentCard.getRarity().toLowerCase(); 
      int id = this.getContext().getResources().getIdentifier("rarity_"+rarityStr, "drawable", this.getContext().getPackageName()); 
      holder.rarity.setImageResource(id); 
      /* COLOR SYMBOLS TO HANDLE LISTVIEW_ITEM BACKGROUNDCOLOR 
      * 
      * Colored artifacts are not handled for now as : AG --> O 
      * 
      * L : Land 
      * B : Black 
      * R : Red 
      * W : White 
      * G : Green 
      * U : Blue 
      * A : Artifact 
      * O : Gold (2 colors or more) 
      * C : DoubleSided Cards Back 
      */ 
      boolean posIsPair = (position %2 == 0); 
      int c; 
      char color = '\0'; 
      if(currentCard.getColor().length()>1){ 
       if(currentCard.getColor().charAt(0) == 'A'){ 
        color = currentCard.getColor().charAt(1); 
       } 
       else color = 'O'; 
      } 
      else{ 
       color = currentCard.getColor().charAt(0); 
      } 
      switch(color){ 
      case 'L' : 
       if(posIsPair)c = R.color.L1; 
       else c = R.color.L2; 
       break; 
      case 'B' : 
       if(posIsPair)c = R.color.B1; 
       else c = R.color.B2; 
       break; 
      case 'R' : 
       if(posIsPair)c = R.color.R1; 
       else c = R.color.R2; 
       break; 
      case 'W' : 
       if(posIsPair)c = R.color.W1; 
       else c = R.color.W2; 
       break; 
      case 'G' : 
       if(posIsPair)c = R.color.G1; 
       else c = R.color.G2; 
       break; 
      case 'U' : 
       if(posIsPair)c = R.color.U1; 
       else c = R.color.U2; 
       break; 
      case 'A' : 
       if(posIsPair)c = R.color.A1; 
       else c = R.color.A2; 
       break; 
      case 'O' : 
       if(posIsPair)c = R.color.O1; 
       else c = R.color.O2; 
       break; 
      case 'C' : 
       c = Color.TRANSPARENT; 
       break; 
      default : 
       c = Color.TRANSPARENT; 
       break; 
      } 
      convertView.setBackgroundColor(this.getContext().getResources().getColor(c)); 
     } 
     return convertView; 

    } 

    @Override 
    public int getCount() { 
     return set.size(); 
    } 

    @Override 
    public MTGCard getItem(int arg0) { 
     return set.get(arg0); 
    } 

} 

回答

1

ListView控件和適配器嘗試創建剛夠視圖,以支持那些在屏幕上或在滾動即可看到該列表中的元素。您可能在ListView中有數百個對象,但並非所有對象都始終附加到視圖。調用getView()時,如果已創建足夠的視圖對象,則convertView參數將爲您提供其中一個要爲position參數指定的行重新填充的視圖對象之一。

這些視圖對象不僅會與您在ViewHolder類中存儲的視圖一起填充,還會附加到它們的任何子視圖。

所以在你的「convertview is not null」的情況下,你可能想要刪除所有holder.manacost的子圖片。 (如果在convertView中提供給您的預先存在的視圖層次結構的狀態與您在代碼的null convertView分支中創建的視圖相同,那麼您的代碼才能正常工作。)

或者,雖然這樣會要更復雜一些,重新填充manacost視圖時重用這些ImageView對象可能是合適的。

+0

它像一個魅力工作,謝謝! – Rudz17 2012-04-17 13:51:02