0

私の最初の Android プロジェクトとして、ユーザーが Magic The Gathering トレーディング カード ゲームのカードを表示できるようにするアプリケーションを作成しています。

ArrayAdapter で、(エディションに応じて) カードの配列をリストビューに表示する問題が発生しています。

たとえば、{2}{B}{B} のような文字列を読み込んで、各文字の ImageViews を作成しています..そして、それらの ImageViews をリストの LinearLayout ディスプレイに追加します。

問題は、 getView() が呼び出されるたびにプロシージャが呼び出されるため、リストを下にスクロールしている限り、ImageViews の数が際限なく増加することです。その手順を一度だけ呼び出したいと思います。

どんな助けでもとても親切です。さらに情報が必要な場合は、遠慮なくご連絡ください。

ありがとう!ルッツ

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);
    }

}
4

1 に答える 1

1

ListView とそのアダプターは、画面上またはスクロール中に表示されるリストの要素をサポートするのに十分なビューを作成しようとします。ListView には何百ものオブジェクトがあるかもしれませんが、それらのすべてが常にビューに関連付けられているわけではありません。が呼び出されたときgetView()に、十分な数のビュー オブジェクトがすでに作成されている場合、convertViewパラメータは、引数で指定された行に再移入するオブジェクトの 1 つを提供しますposition

これらのビュー オブジェクトには、ViewHolder クラスに保存したビューだけでなく、それらにアタッチされた子ビューも既に取り込まれています。

したがって、「convertview が null ではない」場合は、おそらく の子であるすべての画像を削除する必要がありholder.manacostます。(convertView で提供された既存のビュー階層の状態が、コードの null convertView ブランチで作成したビューと同一である場合にのみ、コードは正しく機能します。)

あるいは、これはより複雑になりますが、manacost ビューを再作成するときに、これらの ImageView オブジェクトを再利用することが適切な場合があります。

于 2012-04-14T12:59:29.463 に答える