2011-04-08 4 views
2

BaseAdapter.getView()ですでに作成されたビューの位置を保持することは問題に見えます。BaseAdapter.getViewで作成されたビューの安定した位置を維持する方法は?

私の場合、リストビューのすべてのデータを保持するデータオブジェクト(配列)を作成しました。リスト項目には、セパレータ、チェックボックス付きの項目、ダイアログを開くためのクリック可能な画像付きの項目の3種類があります。そのデータは、カスタマイズされたアレイアダプターによって実行され、常に別のレイアウトで行われます。そのために、私はさまざまな視聴者を使用しました。創造は問題ではありませんが、リサイクラーがそれを始めると、すべてのindizes/positionsが変更されます。しかし、その指標に基づいて私のデータが基づいています。

私はリサイクラーの仕組みを知っていますが、プログラマーはどのようにして自分のデータとの関係を保つべきですか?

ここでいくつかの人が同じ質問をしました。答えは「getItemViewType-Methodeをオーバーライドしました。問題はありませんが、ポジションが常に変化する場合、それは本当に役立たない、そうですか?

誰かに解決策を教えてください。

よろしく ピエール

ここ概念コードの私のprooveです:

// *** Activity: onCreate() 

... 
ArrayList<DataObj> data = getData(); 

    final ListView list = (ListView)findViewById(R.id.listView1); 
    list.setAdapter(new PackedListAdapter(this, data)); 
... 

// *** Activity: getData() 

private ArrayList<DataObj> getData() { 
ArrayList<DataObj> dataArr = new ArrayList<DataObj>(); 
DataObj dataset; 
int i; 

dataset = new DataObj(); 
dataset.setType(DataObj.TYPE_CATEGORY); 
dataset.setItemText("Category CheckItems"); 
dataArr.add(dataset); 

for (i = 0; i < 5; i++) { 
      dataset = new DataObj(); 
    dataset.setType(DataObj.TYPE_ITEM_CHECK); 
    dataset.setItemText("ItemCheck #" + i); 
    dataArr.add(dataset); 
} 

dataset = new DataObj(); 
dataset.setType(DataObj.TYPE_CATEGORY); 
dataset.setItemText("Category DialogItems"); 
dataArr.add(dataset); 

for (i = 0; i < 5; i++) { 
    dataset = new DataObj(); 
    dataset.setType(DataObj.TYPE_ITEM_DLG); 
    dataset.setItemText("ItemDlg #" + i); 
    dataArr.add(dataset); 
} 

return dataArr; 
} 

// *** Data-Object: 

public class DataObj { 
private int type = 1; 
// further variables here (e.g. String text1) ... 

public final static int TYPE_CATEGORY = 1; 
public final static int TYPE_ITEM_CHECK = 2; 
public final static int TYPE_ITEM_DLG = 3; 

public void setType(int type) { this.type = type; } 
public int getType() { return type; } 

// further setter/getter-methodes for variables here ... 
} 

// *** BaseAdapter: 

public class PackedListAdapter extends BaseAdapter { 

private static ArrayList<DataObj> mData; 
private LayoutInflater mInflater; 

PackedListAdapter(Context context, ArrayList<DataObj> data) { 
    mData = data; 
    mInflater = LayoutInflater.from(context); 
} 

public int getCount() { 
    return mData.size(); 
} 

public Object getItem(int position) { 
    return mData.get(position); 
} 

public long getItemId(int position) { return position; } 

public int getItemViewType(int position) { 
    return mData.get(position).getType(); 
} 

public boolean hasStableIds() { return false; } 

public int getViewTypeCount() { return 3; } 

public View getView(int position, View convertView, ViewGroup parent) { 
    int type = this.getItemViewType(position); 

    if (convertView == null) { 
     switch (type) { 
      case DataObj.TYPE_CATEGORY: 
      { 
       convertView = mInflater.inflate(R.layout.listcat, null); 
       ViewHolderCat holder = new ViewHolderCat(); 
       // setting up data from mData(position) here 
       convertView.setTag(holder); 
       break; 
      } 
      case DataObj.TYPE_ITEM_CHECK: 
      { 
       convertView = mInflater.inflate(R.layout.listrow, null); 
       ViewHolderItem holder = new ViewHolderItem(); 
       // setting up data from mData(position) here 
       convertView.setTag(holder); 
       break; 
      } 
      case DataObj.TYPE_ITEM_DLG: 
      { 
       convertView = mInflater.inflate(R.layout.listdlg, null); 
       ViewHolderDlg holder = new ViewHolderDlg(); 
       // setting up data from mData(position) here 
       convertView.setTag(holder); 
       break; 
      } 
     } 
    } else { 
     switch (type) { 
      case DataObj.TYPE_CATEGORY: 
      { 
       ViewHolderCat holder = (ViewHolderCat)convertView.getTag(); 
       // setting up data from mData(position) here 
       break; 
      } 
      case DataObj.TYPE_ITEM_CHECK: 
      { 
       ViewHolderItem holder = (ViewHolderItem)convertView.getTag(); 
       // setting up data from mData(position) here 
       break; 
      } 
      case DataObj.TYPE_ITEM_DLG: 
      { 
       ViewHolderDlg holder = (ViewHolderDlg)convertView.getTag(); 
       // setting up data from mData(position) here 
       break; 
      } 
     } 
    } 

    return convertView; 
} 

public static class ViewHolderCat { 
    public TextView txtCat; 
} 

public static class ViewHolderItem { 
    public TextView txtItem; 
    public TextView txtDescr; 
    public ImageView imgCheckButton; 
} 

public static class ViewHolderDlg { 
    public TextView txtItem; 
    public TextView txtDescr; 
    public ImageView imgDlgButton; 
} 

} 
+0

さらにアダプタが含まBaseAdapterのようです。正確に何をしようとしているのですか?ポジションを知る必要がありますか? –

+0

こんにちは、ロビー、あなたはベクトルする必要があります想像してください。 1つはデータセットリストで、もう1つはビューリストです。データベクタをビューアリストにコピーすると(baseadapterのように)、新しい作成されたビューのそれぞれがデータセットをポイントします(データセットリストの位置に依存します)。しかし、リサイクラの作業位置/変更を示すため、データセット#0のビュー#0は、たとえばデータセット#9のビュー#9になります。だから、もともとview#0はリストの先頭の区切りであり、#9は別の区切りの下のリストの最後にあるチェックボックス項目です。今はポジション/コンテンツが変更されています。どうすればこれを防ぐことができますか? – Pierre

答えて

2

あなたがgetItemViewTypegetViewTypeCountに加えてhasStableIdsをオーバーライドする必要があります。これは次のようになります。

@Override 
public boolean hasStableIds() { 
    /* the view types for rows will change over time */ 
    return false; 
} 

@Override 
public int getViewTypeCount() { 
    return 3; 
} 

@Override 
public int getItemViewType(int position) { 
    /* calculate the view type for this row */ 
    return ... ; 
} 

これは、これにより、アイテムIDに基づいてキャッシングを行うべきではないことがわかると信じています。

+0

こんにちはMatthew、素敵なアイデアだけど、それは役に立たない。この位置シフトによる問題は、シフト後にデータオブジェクトに保持されている定義済みのビュータイプがもはや一致しないことです。発生するエラーは、もちろんのClassCastExceptionです。 (それは狂っている:穴のことはとても簡単ですが、愚かな行動は私を怒らせます。) – Pierre

+0

おそらくあなたのコードを投稿する必要があります。ビューオブジェクトのリスト、モデルオブジェクトだけを保持してはいけません。ビューオブジェクトのリストは、 'ListView'によって維持され、' getView'メソッドに従って更新されます。 –

+0

投稿したコードはPOCだけですが、すべての必要な部分が表示されています... – Pierre

0

は、私は私のデータが最近設定に関する私の見解のローカルキャッシュを作成しようとしたが、これを見た後、私はあきらめることにしました:ListViewコントロールの開発者がいないことをお勧め

http://www.youtube.com/watch?v=wDBM6wVEO70&feature=player_detailpage#t=816s

場合これを行うには、私は彼らのアドバイスに耳を傾け、それをハックしようとしないように感じた。あなたはビューが再使用されているので、あなたがビューの位置を維持することはできません述べたように

+0

これを行うが、決して諦めることはありません。私はそれが動作することを知っている今、それはどのように見つける時間です... – Pierre

関連する問題