Ignacio Garat
Ignacio Garat

Reputation: 1556

ListView Items change position on scroll

I have Implemented a ListView which loads news, but news changes position when I scroll the list. this is list

public class ListNewsFragment extends SherlockListFragment{

private ListNewsAdapter mAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    mAdapter = new ListNewsAdapter(this, app.getAllNews());
    setListAdapter(mAdapter);
    super.onCreate(savedInstanceState);
}
}


public class ListNewsAdapter extends BaseAdapter{
private List<News> news;
private Context mContext;
private LayoutInflater inflater;
private ViewHolder holder;

public ListNewsAdapter(final Fragment c, List<News> news) {
    super();
    this.news = news;
    this.mContext = c.getActivity();
    inflater = LayoutInflater.from(mContext);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View v = convertView;
    if (v == null) {               
         inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         
         holder = new ViewHolder();
         v = inflater.inflate(R.layout.fragment_list_news, null);

         holder.name = (TextView) v.findViewById(R.id.tittle);
         holder.tweet = (TextView) v.findViewById(R.id.news);
         holder.avatar = (ImageView) v.findViewById(R.id.image);


         holder.name.setText(news.get(position).getTitulo());
         holder.tweet.setText(news.get(position).getCopete());
         new ImagefetcherTask(position).execute(holder);

         v.setTag(holder);
    } else {              
     holder = (ViewHolder) convertView.getTag();          
     }                             
   return v; 

}

private class ViewHolder{
    public TextView name, tweet;
    public ImageView avatar;
}

private class ImagefetcherTask extends AsyncTask<ViewHolder, Void, ViewHolder> {

        private Bitmap bitmap;
        int position; 

        public ImagefetcherTask(int position) {
            this.position = position;
        }

        @Override
        protected ViewHolder doInBackground(ViewHolder... params) {
             ViewHolder viewHolder = params[0];

            try{
                bitmap = BitmapFactory.decodeStream((InputStream) new URL("...."+ news.get(position).getImagen().toString()).getContent());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

          return viewHolder;
        }

    @Override
    protected void onPostExecute(ViewHolder result) {
        // TODO Auto-generated method stub
        if (bitmap == null) {
            result.avatar.setImageResource(com.dev.suma_intranet_v1.R.drawable.img_perfil);
        } else {
            result.avatar.setImageBitmap(bitmap);
        }
    }

}

}

Upvotes: 0

Views: 3798

Answers (4)

Vijay Kumawat
Vijay Kumawat

Reputation: 963

I have fixed this by overriding these two methods in my adapter class.

@Override
public int getViewTypeCount() {
   return getCount();
}

@Override
public int getItemViewType(int position) {
   return position;
}

Upvotes: 1

adneal
adneal

Reputation: 30804

Call your ImageFetcher and TextView.seText after your else statement so that when the convertView isn't null and has been recycled, you're updating your row:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        holder = new ViewHolder();
        v = inflater.inflate(R.layout.fragment_list_news, null);

        holder.name = (TextView) v.findViewById(R.id.tittle);
        holder.tweet = (TextView) v.findViewById(R.id.news);
        holder.avatar = (ImageView) v.findViewById(R.id.image);

        v.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.name.setText(news.get(position).getTitulo());
    holder.tweet.setText(news.get(position).getCopete());
    new ImagefetcherTask(position).execute(holder);
    return v;
}

Upvotes: 1

Tautvydas
Tautvydas

Reputation: 2067

Change your getView() method to this:

Map<Integer, View> views = new HashMap<Integer, View>;

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (views.containsKey(position)) {    
         return views.get(position);
    }

     inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         
     holder = new ViewHolder();
     View v = inflater.inflate(R.layout.fragment_list_news, null);

     holder.name = (TextView) v.findViewById(R.id.tittle);
     holder.tweet = (TextView) v.findViewById(R.id.news);
     holder.avatar = (ImageView) v.findViewById(R.id.image);

     holder.name.setText(news.get(position).getTitulo());
     holder.tweet.setText(news.get(position).getCopete());
     new ImagefetcherTask(position).execute(holder);

     v.setTag(holder); 
     views.put(position, v);
     return v; 

}

Upvotes: 9

NullPointerException
NullPointerException

Reputation: 4008

Try to do lazy load an image by using this Universal image loader library. and try to catch image.

so as per this answer set the bitmap options as

DisplayImageOptions  options = new DisplayImageOptions.Builder()
                        .showImageOnLoading(R.drawable.ic_stub)
                        .showImageForEmptyUri(R.drawable.ic_empty)
                        .showImageOnFail(R.drawable.ic_error)
                        .cacheInMemory(true)
                        .cacheOnDisc(true)
                        .considerExifParams(true)
                        .build();

I am sure this will solve your problem

Upvotes: 0

Related Questions