Android GridView
is quite interesting, it reuses the child views. The ones scrolled up comes back from bottom. So there is no method from GridView
to get the child view by its position. But I really need to get view by its position and do some work on it. So to do that, I created an SparseArray
and put views by their position in it from getView
of BaseAdapter
.
SparseArray<View> ViewArray = new SparseArray<View>();
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null)
view = li.inflate(layoutID, null);
ViewArray.put(position, view);
}
Now, I can get all visible views by their position. Everything works perfect as it should but in some devices, the first child view(position 0) is not same as the one in array. I logged the getView
and found that for position 0, getView
got called many times and each time array was set with different view. I have no idea why GridView is calling getView
for position 0 many times and that happens only on few devices. Any solution ?
After reading source of getPositionForView
, I have wrote this method in own GridView, works perfect by API 18
public View GetViewByPosition(int position) {
int firstPosition = this.getFirstVisiblePosition();
int lastPosition = this.getLastVisiblePosition();
if ((position < firstPosition) || (position > lastPosition))
return null;
return this.getChildAt(position - firstPosition);
}
You can't reach the views directly because of the recycling. The view at position 0 may be re-used for the position 10, so you can't be sure of the data present in a specific view.
The way to go is to use the underlying data. If you need to modify data at position 10, then do it in the List or array under your adapter and call notifyDataSetChanged()
on the adapter.
if you need to have different views for different data subtypes, you can override the two following method in your adapter: getItemViewType()
and getViewTypeCount()
Then, in getView()
you can 1) decide which layout to inflate 2) know the type of view recycled using getItemViewType()
You can find an example here: https://stackoverflow.com/a/5301093/990616
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With