ConvertView is passed as null even if the view exists

I developed an Android application where the image and text are displayed in a grid and when the user scrolls down the next ten elements (image and text). The problem occurs when calling the getView method of the adapter after calling adapter.notifyDataSetChanged (). The adapter processes the data, but the positions are rearranged and repeated in grid mode. I did not encounter this problem until I added a condition to check if the convertView is zero.

Action class:

public class DynamicListViewActivity extends Activity implements OnScrollListener { int visibleElements; int scrollState; int count; TextAdapter adapter = new TextAdapter(); int total=200;// total items limit in grid view @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.grid); count=10; GridView grid = (GridView) findViewById(R.id.gridview); grid.setAdapter(adapter); grid.setOnScrollListener(this); } public void onScroll(AbsListView view, int firstVisible, int visibleCount, int totalCount) { visibleElements= visibleCount; } public void onScrollStateChanged(AbsListView v, int s) { Log.d("ScrollState", s+""); scrollState=s; isScrollStateComplete(); } public void isScrollStateComplete(){ if(visibleElements>0 && scrollState==SCROLL_STATE_IDLE && total>count){ int diff=total-count; count+=(diff>=10)?10:diff;//update count to next ten items adapter.notifyDataSetChanged(); } } class TextAdapter extends BaseAdapter { public int getCount() { return count; } public Object getItem(int pos) { return pos; } public long getItemId(int pos) { return pos; } public View getView(int pos, View convertView, ViewGroup p) { View v = convertView; System.out.println("pos : "+pos+" boolean "+(v==null));// log to check position and convertView if(v==null){ v =((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.textlayout,null); ImageView iv = (ImageView) v.findViewById(R.id.album_thumbnail); iv.setImageDrawable(getResources().getDrawable(R.drawable.icon)); TextView tvAlbumName = (TextView)v.findViewById(R.id.album_name); tvAlbumName.setText("postion "+pos); TextView tvAlbumDesc = (TextView)v.findViewById(R.id.album_description); tvAlbumDesc.setText(""); } return v; } } } 

Before scrolling the screen, the grid is displayed correctly. Journal:

 08-05 14:24:34.440: INFO/ActivityManager(58): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.mis.list.demo/.DynamicListViewActivity } 08-05 14:24:34.642: INFO/System.out(685): pos : 0 boolean true 08-05 14:24:34.710: INFO/System.out(685): pos : 0 boolean false 08-05 14:24:34.710: INFO/System.out(685): pos : 1 boolean true 08-05 14:24:34.730: INFO/System.out(685): pos : 2 boolean true 08-05 14:24:34.800: INFO/System.out(685): pos : 3 boolean true 08-05 14:24:34.860: INFO/System.out(685): pos : 4 boolean true 08-05 14:24:34.880: INFO/System.out(685): pos : 5 boolean true 08-05 14:24:34.910: INFO/System.out(685): pos : 6 boolean true 08-05 14:24:34.920: INFO/System.out(685): pos : 7 boolean true 08-05 14:24:34.960: INFO/System.out(685): pos : 0 boolean true 08-05 14:24:35.030: INFO/ActivityManager(58): Displayed activity com.mis.list.demo/.DynamicListViewActivity: 520 ms (total 520 ms) 

After the first end of the scroll

 08-05 14:26:15.740: DEBUG/ScrollState(685): 1 08-05 14:26:15.830: DEBUG/dalvikvm(685): GC_EXTERNAL_ALLOC freed 3624 objects / 257464 bytes in 71ms 08-05 14:26:16.210: INFO/System.out(685): pos : 8 boolean false 08-05 14:26:16.210: INFO/System.out(685): pos : 9 boolean true 08-05 14:26:16.250: DEBUG/ScrollState(685): 0 08-05 14:26:16.260: INFO/System.out(685): pos : 0 boolean true 08-05 14:26:16.271: INFO/System.out(685): pos : 0 boolean false 08-05 14:26:16.271: INFO/System.out(685): pos : 1 boolean false 08-05 14:26:16.271: INFO/System.out(685): pos : 2 boolean false 08-05 14:26:16.271: INFO/System.out(685): pos : 3 boolean false 08-05 14:26:16.271: INFO/System.out(685): pos : 4 boolean false 08-05 14:26:16.271: INFO/System.out(685): pos : 5 boolean false 08-05 14:26:16.280: INFO/System.out(685): pos : 6 boolean false 08-05 14:26:16.280: INFO/System.out(685): pos : 7 boolean false 08-05 14:26:16.280: INFO/System.out(685): pos : 8 boolean false 08-05 14:26:16.280: INFO/System.out(685): pos : 9 boolean false 08-05 14:26:16.280: INFO/System.out(685): pos : 10 boolean false 08-05 14:26:16.280: INFO/System.out(685): pos : 11 boolean true 08-05 14:26:16.371: DEBUG/dalvikvm(685): GC_EXTERNAL_ALLOC freed 644 objects / 33224 bytes in 41ms 08-05 14:26:45.270: WARN/KeyCharacterMap(685): No keyboard for id 0 08-05 14:26:45.270: WARN/KeyCharacterMap(685): Using default keymap: /system/usr/keychars/qwerty.kcm.bin 08-05 14:26:45.341: INFO/System.out(685): pos : 12 boolean true 08-05 14:26:45.351: INFO/System.out(685): pos : 13 boolean true 08-05 14:26:45.371: INFO/System.out(685): pos : 14 boolean true 08-05 14:26:45.380: INFO/System.out(685): pos : 15 boolean true 08-05 14:26:45.450: INFO/System.out(685): pos : 16 boolean false 08-05 14:26:45.450: INFO/System.out(685): pos : 17 boolean false 08-05 14:26:45.460: INFO/System.out(685): pos : 18 boolean false 08-05 14:26:45.460: INFO/System.out(685): pos : 19 boolean false 

But the grid is displayed with duplicate values, and not in the order in which it should be. Sorry, I am not allowed to send images, as I am a new user.

In the log, I see that for position 0, convertView == null is true.

how to set this right, since I plan to upload images instead of the android icon to view the image that is currently in use.

Please, help.

+4
source share
3 answers

Your interpretation of convertView is incorrect.

 public View getView(int pos, View convertView, ViewGroup p) { View v = convertView; //If convertView is null create a new view, else use convert view if(v==null) v =((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.textlayout,null); ImageView iv = (ImageView) v.findViewById(R.id.album_thumbnail); iv.setImageDrawable(getResources().getDrawable(R.drawable.icon)); TextView tvAlbumName = (TextView)v.findViewById(R.id.album_name); tvAlbumName.setText("postion "+pos); TextView tvAlbumDesc = (TextView)v.findViewById(R.id.album_description); tvAlbumDesc.setText(""); return v; } 

- this is what you should do.

As a result of what you did, in cases where the convertView not null, you simply returned the convertView without updating your data, and therefore your images were repeated. Only in cases where convertView was null did you set your data.

Contract between the adapter and the list viewer: if the transmitted convertView is null, create a new one, use it again.

+13
source

Vikram Bodicherla is correct (+1), your implementation is incorrect, and his sample code correctly corrects your problem. However, I want to recommend the following discussion on Google I / O 2010: ListView World . This is one hour, but you will have a much deeper understanding of how ListView works and how you should write an adapter in order to work properly with it.

+3
source

If Android determines that the view that represents the row is no longer displayed, this allows the getView () method to be reused through the convertView parameter.

A performance optimized adapter assigns new data to the converter. This avoids bloating the XML file and creating new Java objects.

If there is no view to reuse, Android will pass null to the convertView parameter. Therefore, to implement the adapter, you need to check this.

0
source

All Articles