ListViewまわりのあれこれをメモ1です。

adapterでnotifyDataSetChanged()しないでListViewから個別にViewを取り出すやり方。

 ListView.getChildAt(int position)で取れます。
 
だけどこのpositionは表示している行からのpositionなので注意。
例えば、adapterで言えば3番目を取りたいので2と入れたいけど、
ListViewに今表示されてるのが2番目からなら positionは2ではなく1となる。
*positionは0から数えた数です。

んでこれの対応。
ネット上でもいろいろお話されてきてますが、
無駄が多いのだけど個人的には以下が安定しとります。


ListView.getFirstVisiblePosition()で画面の最初に表示中のadapterのpositionが取得できる。
ListView.getChildCount()で画面表示数が取得できる。

表示中のViewたちはforなりで表示数分まわしてgetChildAt()すればとれます。
それにたいするadapterのpositionはまわしているカウント+ListView.getFirstVisiblePosition()をすればわかるようになります。

なのでこんな感じ。
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i); //<--表示中のViewはiで
int position = getFirstVisiblePosition() + i;
adapter.getItem(position)//<--adapterはi+getFirstVisiblePosition()で
}

んで、肝心の更新したいViewはどうとんの?って話でいうと
上記で取得した更新したいadapterのアイテムとequalsさせて判断してぶつかればViewを返すという流れ。
メソッド的には以下みたいな。

public View getView(Object o) {
int firstVisiblePosition = getFirstVisiblePosition();
int childCount = getChildCount();
ListAdapter a = getAdapter();

if (a == null)
throw new NullPointerException("ListAdapter is not set.");

for (int i = 0; i < childCount; i++) {
if (a.getItem(firstVisiblePosition + i).equals(o)) {
return getChildAt(i);
}
}
return null;
}
nullがくれば表示されてないってことなので、画面の更新は必要ないというやり方でございます。
ちなみにExpandableListViewでも同じやり方ができます。
基本的にOnItemClickListenerとかで更新させるならViewが返ってきてるのであんまいらないんですがね。


こんなところでございます。

いつものようにサンプルを。
今回の話はサンプルファイルでいうとObtainListView、ObtainExpandableListViewになります。