I have an ArrayAdapter and its getView method has something is this:
public View getView(int position, View convertView, ViewGroup parent) {
//get object against selected list item
book thisbook = getItem( position );
ViewHolder viewHolder; // view lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate( R.layout.book, parent, false);
viewHolder.bookImage = (ImageView) convertView.findViewById(R.id.bookImage);
viewHolder.txtbookTitle = (TextView) convertView.findViewById(R.id.txtbookTitle);
//download image and set the bitmap for bookImage ImageView
new DownloadImageService( viewHolder.bookImage ).execute( thisbook.getImageUrl() );
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txtbookTitle.setText(thisbook.getbookTitle());
viewHolder.bookImage = thisbook.getbookImage();
viewHolder.txtbookId.setText(thisbook.getbookId());
new DownloadImageService( viewHolder.bookImage ).execute( thisbook.getImageUrl() );
return convertView;
}
Now, when I scroll down I load more items into my ArrayList of data and then call myAdapter.notifyDataSetChanged() and what happens is the book images are messed up i.e. the newly loaded item will have an image from another item which is already loaded into the list. e.g. if a book with id 1 is loaded already in the list and image is a.jpeg when scroll down the listview and load a new book say with id 10 although its image should be 10.JPEG but it has that a.jpeg with blongs to another book, its strange, not sure what I am doing wrong.
while debugging I have checked the input ArrayList for adapter and I can see all the books in the ArrayList perfectly as they should be.
Related
I am building a Tinder-like Android app with this library : https://github.com/Diolor/Swipecards and Picasso for image loading. Everything works fine, except the first view of the list. The image is not displayed, although the text is correct.
Views are stored in a custom subclass of ArrayAdapter. Here is the code:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
switch (getItemViewType(position)) {
case TYPE_MOVIE:
ViewHolderMovie holder;
if (convertView == null) {
holder = new ViewHolderMovie();
convertView = inflater.inflate(R.layout.movie_card, parent, false);
holder.movieCover = (ImageView)convertView.findViewById(R.id.movieCover);
holder.movieTitle = (TextView)convertView.findViewById(R.id.movieTitle);
holder.movieGenre = (TextView)convertView.findViewById(R.id.movieGenre);
convertView.setTag(holder);
} else {
holder = (ViewHolderMovie) convertView.getTag();
}
Movie movie = (Movie) data.get(position);
Picasso.with(convertView.getContext())
.load(movie.imagePath)
.resize(500, 500)
.into(holder.movieCover); // this doesn't work for the first view
holder.movieTitle.setText(movie.title);
holder.movieGenre.setText("Film au cinéma ("+movie.genre+")");
return convertView;
}
return null;
}
Do you have an idea please?
Check Your image URL path ,especially slash '/'.
Picasso don't show first image of ArrayAdapter when '/' has twice in your imageurl path.
But it show truly when you scroll Gridview or Listview
i have a big problem with my ListViewAdapter.
My listview shows 2 entrys at the same time. Each entry should get a different picture from my server.
The first and the second entrys working fine, but if i'm scrolling down, the next entrys will have the same pictures.
My Code looks like this:
if (viewHolder.imgPic != null) {
String strUrl = mainUrl+list.get(position).getUrl();
new ImageDownload(viewHolder.imgPic).execute(strUrl);
}
I'm checking the view and just doing it, if it's null.
Can someone help me?
Thanks
from your question I can assume that you don't know about the ListView recycling mechanisem
basically, view that that not visible anymore (after user scrolled it away from sight) it been recycled to displayed new item that need to shown. that's the convertView parameter at the getView() method...
probably you are see the same image because the recycled view stays with the same image..
also there is the issue of the asynchronous task (your ImageDownload class) that can finish it execute when the original item that started the request already been recycled.
I recommend you to "dig" as dipper as you can to understand all about ListView - this is one of the most complex and important UI component. reading the post I linked you is a good start.
also this video is very important:
http://www.youtube.com/watch?v=wDBM6wVEO70
Here is my GetView:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;
if(rowResourceId!=R.layout.search_empty_list) {
if (convertView == null) {
LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflator.inflate(rowResourceId, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.textName = (TextView) view.findViewById(R.id.textView1);
viewHolder.imgPic = (ImageView) view.findViewById(R.id.imgPic);
if (viewHolder.imgPic != null) {
String strUrl = mainUrl+list.get(position).getUrl();
new ImageDownload(viewHolder.imgPic).execute(strUrl);
}
view.setTag(viewHolder);
} else {
view = convertView;
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.textName.setText(list.get(position).getName());
} else {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(rowResourceId, parent, false);
TextView textView1 = (TextView) view.findViewById(R.id.textView1);
textView1.setText(list.get(0).getName());
}
return view;
}
I have a list that contain 10 images and name. On clicking next button its showing 10 images with name, but its showing previous 10 images also (total 20 images).
I want to display only the present 10 images and want to delete the previous 10 images from the ListView. How can i do this?
I have tried myArrayList.clear(); arrayList.remove();, adapter.clearListView(); and listView.removeAllView(); but still i am getting 20 images (10 present images and 10 previous image).
Please suggest some solution with sample code.
My code is
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder view;
LayoutInflater inflator = activity.getLayoutInflater();
if(convertView==null)
{
view = new ViewHolder();
convertView = inflator.inflate(R.layout.image_detail_view, null);
view.txtViewTitle = (TextView) convertView.findViewById(R.id.textView1);
view.imgViewFlag = (ImageView) convertView.findViewById(R.id.imageView1);
convertView.setTag(view);
}
else
{
view = (ViewHolder) convertView.getTag();
}
listImage.clear();
listText.clear();
notifySetDataChange();
return convertView;
}
and i am creating list view in another class and calling adapter in above code..
i have tried to clearing listView also..
Images and names are from server and they are dynamic in nature..
You cant clear list data in getView method. You have to clear from listAdapter. Then it will work correctly.
You can deal only with adapter. Reset data in adapter and call adapter.notifyDataSetChanged().
UDP:
getView() is invoked by system every time it needs a view for row. So, don't change a list with data and call notifyDataSetChanged() in this method.
class CustomAdapter extends ArrayAdapter {
private List<YourItem> items;
public void setItems(List<YourItem> newItems) {
items = newItems;
notifyDataSetChanged();
}
public View getView(View convertView, int position, ...) {
if (convertView == null) {
// your code
} else {
// your code
}
YourItem item = items.get(position);
// set image to convertView
return convertView;
}
}
So, call setData() with your new items every time you want to update a ListView.
Are there any more questions?
I've a custom adapter for my ListView where I send to it a List, and if the position is in the list then the imageview (that is in the custom row) change its src to another.. Here is the GetView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.start_row, null); // line
// 47
holder = new ViewHolder();
holder.tv_SuraName = (TextView) convertView.findViewById(R.id.Start_Name);
holder.tv_SuraName.setTypeface(Font);
holder.tv_PageNumber = (TextView) convertView.findViewById(R.id.Start_Numbering);
holder.im_Audio = (ImageView) convertView.findViewById(R.id.Start_ImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_SuraName.setText(SuraList_SuraNamesCode[position]);
holder.tv_PageNumber.setText(Integer.toString(PageNumber[position]));
holder.im_Audio.setOnClickListener(new imageViewClickListener(position));
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
return convertView;
}
I send a List with 1 position.If I scroll the ListView slowly, this works good and only 1 imageview gets changed as it should be. But if I scroll fast, other imagesviews that are close to the correct position also gets changed!
Can anyone tell me why?
You don't ever set the imageResource to something else if position isn't contained in your list. When the view with the custom image leaves the screen it is probably getting placed at a lower position in the list and getting reused.
Try changing this:
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
To this:
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
else
holder.im_audio.setImageResource(r.drawable.SOME_THING_ELSE);
I have list view with custom array adapter. I want to get items click position from getView method. I am getting a few list view items position but when i add more then 7 items into my list i get wrong position from getView method. I mean when i click 9th list item it returns 1.
Here is my code
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
this.position = pos;
Log.v("View position", Integer.toString(pos));
lineView = convertView;
if(lineView==null)
{
adapterLine=new AdapterLine();
layoutInflater=context.getLayoutInflater();
lineView=layoutInflater.inflate(com.inomera.sanalmarket.main.R.layout.adapter, null,true);
adapterLine.sListText = (TextView) lineView.findViewById(R.id.sListText);
adapterLine.sListCheckbox = (CheckBox) lineView.findViewById(R.id.sListCheckbox);
adapterLine.sListImageView = (ImageView) lineView.findViewById(R.id.imageView1);
adapterLine.gestureOverlayView = (GestureOverlayView) lineView.findViewById(com.inomera.sanalmarket.main.R.id.gestureOverlayView1);
adapterLine.gestureOverlayView.setGestureVisible(false);
// To remember whitch tab is selected
adapterLine.sListImageView.setTag(pos);
adapterLine.sListCheckbox.setTag(pos);
adapterLine.sListText.setTag(pos);
Log.v("adapter", "position of adapter is " + Integer.toString(pos));
Thanks for any help!
The array adapter will only create one object per visible row in your list view. After this, the adapter will recycle that already created view. This is the purpose of the:
if(lineView==null)
line in your adapter.
You will want to put in an else section that sets up the row using the recycled view. This other article may be helpful:
How can I make my ArrayAdapter follow the ViewHolder pattern?
This implementation is incomplete add else section which sets value from data. here is implementation which worked for me
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflator = reportViewContext.getLayoutInflater();
convertView = inflator.inflate(R.layout.tabitems, null);
viewHolder.name= (TextView) convertView
.findViewById(R.id.user_reportTab_userName);
//set other values needed in viewHolder if any
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
//data is list of Data model
if(data.size()<=0) {
//if data unavailable }
else {
/***** Get each Model object from Array list ********/
System.out.println("Position:"+position);
/************ Set Model values in Holder elements ***********/
viewHolder.name.setText(data.get(position).getName());
}
return convertView;
}
I know the question is very old, answered in case anyone stumbled on similar problem