2011-01-04 14 views
8

カスタマイズしたBaseAdapterを使用してListViewに項目を表示しています。項目は、ArrayListに保持されている文字列です。カスタムBaseAdapterを使用してListViewから項目を削除する

リストの項目には削除ボタンがあります(大きな赤色のX)。ArrayListから項目を削除し、ListViewに更新を通知する必要があります。

しかし、私が試したすべての実装では不思議なポジション番号が与えられています。たとえば、アイテム2の削除ボタンをクリックするとアイテム5が削除されます。それはほぼ完全にランダムなようです。

注意すべき点の1つは、要素を繰り返すことができますが、同じ順序で保持する必要があることです。例えば、私は、要素3として、「アイルランド」二回持つことができ、7

私のコードは以下の通りです:

private static class ViewHolder { 
     TextView lang; 
     int position; 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.language_link_row, null); 
     holder = new ViewHolder(); 
     holder.lang = (TextView)convertView.findViewById(R.id.language_link_text); 
     holder.position = position; 

     final ImageView deleteButton = (ImageView) 
       convertView.findViewById(R.id.language_link_cross_delete); 
     deleteButton.setOnClickListener(this); 

     convertView.setTag(holder); 
     deleteButton.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    holder.lang.setText(mLanguages.get(position)); 

    return convertView; 
} 

私は後でタグをつかんによって削除要素の位置を取得しようとしたが、それはいつもですリストの間違った位置。ここに与えられた位置には目立つパターンはなく、いつもランダムに見えます。

// The delete button's listener 
public void onClick(View v) { 

    ViewHolder deleteHolder = (ViewHolder) v.getTag(); 
    int pos = deleteHolder.position; 

    ... 
    ... 
    ... 
} 

私はただのArrayListから項目を削除し、ListViewコントロール自体を更新持つことは非常に幸せになるが、私は取得しています位置はので、私はそれを行うことはできません間違っています。

最初に、getViewメソッド内でdeleteButton clickListenerを使用し、値を削除するために 'position'を使用しましたが、同じ問題がありました。

何か提案がありがとう、これは本当に私を刺激しています。

答えて

5

毎回位置を設定する必要があります。あなたの実装は、ビューの作成時の位置だけを設定します。ただし、ビューがリサイクルされるとき(convertViewがnullでない場合)、位置は正しい値に設定されません。

public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.language_link_row, null); 
     holder = new ViewHolder(); 
     holder.lang = (TextView)convertView.findViewById(R.id.language_link_text); 

     final ImageView deleteButton = (ImageView) 
       convertView.findViewById(R.id.language_link_cross_delete); 
     deleteButton.setOnClickListener(this); 

     convertView.setTag(holder); 
     deleteButton.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    holder.lang.setText(mLanguages.get(position)); 
    holder.position = position; 
    return convertView; 
} 
+1

素晴らしいです、ありがとうございます。そんなに愚かな問題で私が長く過ごしたとは信じられない。私は自分の一般的な解決策を興味のある人のための別個の答えとして追加しました。 – HXCaine

0

あなたは方法の1つのパラメータが位置であり、OnItemClickListenerインタフェースを実装し、onItemClick方法でアイテムを削除する必要があります。

+1

彼はボタンを持っているので、リスナーは適切ではありません。そのリスナーは、リスト要素全体がclickイベントを受け取った場合にのみ機能します。 –

0

私の最終的な解決策は、グレッグによって受け入れ答えを使用していたと、次の(これはコンストラクタで空として初期化される)をキーとして項目の位置と、HashMapの中

  • ストア保有者

    プライベートHashMap mHolders; [奇妙な書式設定を許しなさい

public void onClick(View v) { 
    ViewHolder deleteHolder = (ViewHolder) v.getTag(); 
    int pos = deleteHolder.position; 
    mHolders.remove(pos);

ViewHolder currentHolder; 

    // Shift 'position' of remaining languages 
    // down since 'pos' was deleted 
    for(int i=pos+1; i<getCount(); i++){ 
     currentHolder = mHolders.get(i); 
     currentHolder.position = i-1; 
    } 
    mLanguages.remove(pos); 
    notifyDataSetChanged(); 
} 

  • はonClickListener方法としてこれを使用してください。コードの埋め込みが正しく機能していません]

  • 関連する問題