Unconditional layout, inflation from view adapter: Should use View Holder pattern
Solution 1:
Try this
static class ViewHolder {
private TextView friendsname;
private ImageView thumb_image;
private CheckBox cb;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder = null;
HashMap<String, String> song = null;
if (convertView == null) {
song = new HashMap <String, String>();
mViewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
mViewHolder.friendsname = (TextView) convertView.findViewById(R.id.friendsName); // title
mViewHolder.thumb_image = (ImageView) convertView.findViewById(R.id.list_image); // thumb image
mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(mViewHolder);
mViewHolder.cb.setTag(data.get(position));
mViewHolder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean ischecked) {
InviteFriends.isChecked[position] = buttonView.isChecked();
}
});
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
song = mViewHolder.cb.getTag();
mViewHolder.friendsname.setText(song.get(InviteFriends.KEY_DISPLAY_NAME));
mViewHolder.imageLoader.DisplayImage(song.get(InviteFriends.KEY_IMAGEPROFILE_URL), thumb_image);
mViewHolder.cb.setChecked(InviteFriends.isChecked[position]);
return convertView;
}
Solution 2:
you should init the convert view only if it is null
these lines
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
// [...] the rest of initialization part
// [...] some changes that must be done at refresh
return convertView;
should look like this:
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
// [...] the rest of initialization part
}
// [...] some changes that must be done at refresh
return convertView;
the goal is to recycle the already existing view in that list, not to init it each time you display it when scrolling the list for example.
Solution 3:
My suggestion is try to use convertView = vi.inflate(R.layout.activity_friend_list_row, null);
insted of convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
this may help you.
:-
okey.. insted of accessing like this TextView friendsname = (TextView) convertView.findViewById(R.id.friendsName); // title
ImageView thumb_image = (ImageView) convertView.findViewById(R.id.list_image); // thumb image
you have to use viewholder class in your adapter
for example
static class ViewHolder {
public TextView text;
public ImageView image;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
viewHolder.image = (ImageView) rowView
.findViewById(R.id.ImageView01);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String s = names[position];
holder.text.setText(s);
if (s.startsWith("Windows7") || s.startsWith("iPhone")
|| s.startsWith("Solaris")) {
holder.image.setImageResource(R.drawable.no);
} else {
holder.image.setImageResource(R.drawable.ok);
}
return rowView;
}
Solution 4:
Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling.
It means that you need to use View Holder pattern in your Adapter. The point of using View Holder is to reusing the views because inflating and using findViewById
are slow.
When you're using the following code:
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder;
mViewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(mViewHolder);
...
return convertView;
}
you're not reusing the views but instead you always create new views.
You need to change your code to something like this (please check the comment):
// class for holding the cached view
static class ViewHolder {
TextView tvFriendsName;
ImageView imvThumbImage;
CheckBox cbInviteFriend;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// holder of the views to be reused.
ViewHolder viewHolder;
// get data based on the position
HashMap<String, String> song = data.get(position);
// if no previous views found
if (convertView == null) {
// create the container ViewHolder
viewHolder = new ViewHolder();
// inflate the views from layout for the new row
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.rowlayout, parent, false);
// set the view to the ViewHolder.
viewHolder.cbInviteFriend = convertView.findViewById(R.id.checkBox);
viewHolder.tvFriendsName = convertView.findViewById(R.id.friendsName);
viewHolder.imvThumbImage = convertView.findViewById(R.id.list_image);
// save the viewHolder to be reused later.
convertView.setTag(viewHolder);
} else {
// there is already ViewHolder, reuse it.
viewHolder = (ViewHolder) convertView.getTag();
}
// now we can set populate the data via the ViewHolder into views
viewHolder.tvFriendsName.setText(song.get(InviteFriends.KEY_DISPLAY_NAME));
imageLoader.DisplayImage(song.get(InviteFriends.KEY_IMAGEPROFILE_URL), viewHolder.imvThumbImage);
viewHolder.cbInviteFriend.isChecked(InviteFriends.isChecked[position]);
return convertView;
}