BaseAdapter.getView() for ListActivty using ViewHolder - Android
Here when you have inflated view at that time you should use layout
so change from this
convertView = mInflater.inflate(R.id.gridviewViewOutfits, null);
to
convertView = mInflater.inflate(R.layout.gridviewViewOutfits, null);
user3164083
Updated on June 04, 2022Comments
-
user3164083 almost 2 years
This was my original getView method for the ListView BaseAdapter:
// create a new ImageView for each item referenced by the Adapter public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { // if it's not recycled, initialize some attributes imageView = new ImageView(mContext); imageView.setLayoutParams(new GridView.LayoutParams(150, 150)); imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); imageView.setPadding(8, 8, 8, 8); } else { imageView = (ImageView) convertView; } ImageHelper ih = new ImageHelper(); imageView.setImageBitmap(ih.decodeSampledBitmapFromResource(mContext.getResources(), mList.get(position), 40, 40)); return imageView; }
It did not make use of convertView and I had no mInflater. I read that this way is not good for memory usage, and I found a better way that uses a ViewHolder. I have changed this method to implement a viewHolder and use the convertView instead making an ImageView like I originally did:
static class ViewHolder{ TextView text; ImageView icon; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; ImageView imageView = new ImageView(mContext); ImageHelper ih = new ImageHelper(); if (convertView == null) { convertView = mInflater.inflate(R.id.gridviewViewOutfits, null); holder = new ViewHolder(); holder.icon = (ImageView) convertView; holder.icon.setLayoutParams(new GridView.LayoutParams(150, 150)); holder.icon.setScaleType(ImageView.ScaleType.FIT_CENTER); holder.icon.setPadding(8, 8, 8, 8); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.icon.setImageBitmap(ih.decodeSampledBitmapFromResource(mContext.getResources(), mList.get(position), 40, 40)); return convertView; }
This line caused a nullPointerException:
convertView = mInflater.inflate(R.id.gridviewViewObjects, null);
It's because I had not instantiated my mInflater. Then I did that like this:
mInflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Because I saw that online. Then I got this error:
01-20 20:37:52.080: E/AndroidRuntime(22543): FATAL EXCEPTION: main 01-20 20:37:52.080: E/AndroidRuntime(22543): android.content.res.Resources$NotFoundException: Resource ID #0x7f04002b type #0x12 is not valid 01-20 20:37:52.080: E/AndroidRuntime(22543): at android.content.res.Resources.loadXmlResourceParser(Resources.java:2136) 01-20 20:37:52.080: E/AndroidRuntime(22543): at android.content.res.Resources.getLayout(Resources.java:865) 01-20 20:37:52.080: E/AndroidRuntime(22543): at android.view.LayoutInflater.inflate(LayoutInflater.java:394) 01-20 20:37:52.080: E/AndroidRuntime(22543): at android.view.LayoutInflater.inflate(LayoutInflater.java:352) 01-20 20:37:52.080: E/AndroidRuntime(22543): at com.btf271.imagehelper.ChooseStickersImageAdapter.getView(ChooseObjectsImageAdapter.java:136)
What should I do to instantiate the mInflater, or am I inflating the wrong thing?
This is my XML for the ListActivity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".ViewOutfitsActivity" > <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView> <GridView android:id="@+id/gridviewViewObjects" android:layout_width="fill_parent" android:layout_height="fill_parent" android:columnWidth="90dp" android:numColumns="auto_fit" android:verticalSpacing="10dp" android:horizontalSpacing="10dp" android:stretchMode="columnWidth" android:gravity="center" /> </RelativeLayout>
Thank you.
-
user3164083 over 10 yearsThanks. It says "gridviewViewOutfits cannot be resolved or is not a field"
-
heri.wijoyo over 10 yearsthen you just have to import it: import YOUR_APP_PACKAGE_NAME.R.layout.gridviewViewOutfits
-
user3164083 over 10 yearsThanks. This will just display images in a gridView. Do you mean I create a whole new XML file such as the file that each Activity has created automatically? I have never done this. Would I right-click the Layout folder and click new XML file?
-
user3164083 over 10 yearsMy gridViewViewOutfits is just a view inside my ListActivity layout. So do I right-click the layout folder and click new XML file, to create a new layout? Then inflate that? Thank you.
-
Piyush over 10 yearsYes if you want to make custom list then you should use that one..And you'r going in right direction.
-
user3164083 over 10 yearsThank you :) Should I give it a root element of RelativeLayout? I am creating it now and not sure what option to choose. Or should I go for ListView?
-
user3164083 over 10 yearsThank you. There are a lot of root elements to choose from for my custom layout. Do I choose RelativeLayout or ListView or something else?
-
Piyush over 10 yearsyou can use relative layout or linear layout
-
user3164083 over 10 yearsThanks. It works but does not reduce the heap at all :( When I exit the listActivity I want those list bitmaps out of memory which does not appear to happen. However I will mark this as the answer.
-
Piyush over 10 yearsare you set background image for your layout any where which has a high resolution?
-
user3164083 over 10 yearsNo. I have an ImageView in my main Activity which takes up the full screen. I set it to 500 X 500 px. This just has to be there though. However, the heap keeps growing when accessing the ListActivity and then does not go back down when I click the item which adds it to the main Activity. The item drawn to the main Activity is very small. It is the List that is doing it.
-
Piyush over 10 yearsand this is because you are fetching images from resource folder and that images may be high resolutions.
-
user3164083 over 10 yearsI change their resolution with inSampleSize, to 40px X 40px to draw them to the main Activity. I can confirm their resolution. The heap is growing because of the List, which is fine, but when I exit the List by clicking on an item, they should be removed from memory :(
-
Roman Black over 10 yearsYes, you should give it a root element of RelativeLayout or any other layout class
-
fweigl over 10 yearsExactly, that's what you need to to. If you only want to display an Image the layout needs only to contain an ImageView. You probably want to read a tutorial like this one: vogella.com/tutorials/AndroidListView/… It's about ListViews but the adapter part is exactly the same for GridViews.
-
user3164083 over 10 yearsThank you. I have finished and it works. However it was all for nothing, the heap is still just as big. I am convinced it is growing from this listView and not reducing upon exiting the ListView. Oh well, my original question has been answered well :)