问题
I've been trying to re-set the size of an ImageView. I'm using a custom adapter.
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.grid_item, null);
}
thumb = (ImageView) row.findViewById(R.id.bookThumb);
When I use ImageView thumb = (ImageView) row.findViewById(R.id.bookThumb); inside the custom adapter it works great but because it's looping through every row it makes the scrolling very slow.
So... I'm now trying to get the thumb = (ImageView) row.findViewById(R.id.bookThumb); from my Main Activity and set its size but I get Null and therefore the app force closes.
Tried:
LinearLayout layout = (LinearLayout) findViewById(R.id.gridLayout);
ImageView thumbRow = (ImageView)layout.findViewById(R.id.bookThumb);
Also tried:
// gv is the gridview (R.id.gridview)
ImageView thumbRow = (ImageView)gv.findViewById(R.id.bookThumb);
Always get null.
Appreciate any help! feels like I'm missing something silly :)
回答1:
I think the problem stems in two places.
First off the original problem. Your Adapter is slow because of the findViewById call. You make use of the recycled view and that's great, but you still traverse the view for the thumbnail. There is a technique, informally called ViewHolder, which basically makes it more of a direct call.
So instead of just using the recycled view as a place to start filling data, also attach some structure to it so you can prefetch the elements you want to manipulate
if (row == null) {
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.grid_item, null);
row.setTag(row.findViewById(R.id.bookThumb));
}
thumb = (ImageView) row.getTag();
Here we call directly by variable and no traversing is done. This should be much faster.
Also the second problem, the NullPointerExcepton.
I think it's the ambiguity of ids mixed with the point at which you call findViewById in your main activity. You can't really do it well in your mainActivity especially if there is scrolling involved as you would have to intercept the call to render within the adapter view. Most of the callbacks are already on the main thread so two things cannot happen at the same time on that thread.
So at the point you called findViewById() the adapter may not have even run yet and attached that view to the hierarchy. And if it did, it might not have finished manipulating it yet.
I would try to speed up your adapter before approaching the second issue as I am not sure it is even possible to do it safely or accurately, without abandoning the use of an adapter view entirely.
来源:https://stackoverflow.com/questions/5369252/android-findviewbyid-of-an-imageview-custom-adapter