2012-04-14 9 views
0

私の最初のAndroidプロジェクトとして、Magic Gatheringトレーディングカードゲームからカードを表示できるアプリケーションを作成しています。複数の呼び出しを避けるAndroid ArrayAdapter getViewの問題

ArrayAdapterで、(バージョンに応じて)一連のカードをリストビューに表示する際に問題が発生しました。

{2} {B} {B}のような文字列を読み込み、各文字ごとにImageViewを作成しています。これらのImageViewをリストのLinearLayout表示に追加します。

問題は、私のリストをスクロールする限り、getView()が呼び出されるたびにプロシージャが呼び出され、ImageViewsの数が無限に増加するということです。 私は、その手続きを一度だけ呼びたいと思います。

非常に親切です。 詳しい情報が必要な場合は、躊躇しないでください。

ありがとうございます! 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引数で指定された行を再配置するパラメータの1つを提供します。

これらのビューオブジェクトには、ViewHolderクラスに格納されているビューだけでなく、それらにも関連付けられた子ビューも設定されています。

したがって、 "convertview is nullではない"ケースでは、holder.manacostの子であるすべての画像を削除することをお勧めします。 (convertViewで提供されている既存のビュー階層の状態が、コードのnull convertViewブランチで作成したビューと同じ場合、コードは正しく動作します)。

マナコンストビューを再作成するときにImageViewオブジェクトを再利用することが適切な場合があります。

+0

それは魅力のように働いた、ありがとう! – Rudz17

関連する問題