Position of items in listview is changing when I scroll the listview

My application has an listview and listview's rows consist of imageView and Textview. The application downloads images from web to set imageview in the row layout. I had a problem about image redownloading when I scoll up and down the listview. For this reason I used ViewHolder pattern to save list items. The problem had been fixed but this time i have a new problem.

There are 15 rows in Listview. Therefore items at the bottom of list don't appear. When I scrool down the list to see items, items at top of list are coming to end of lisview. Also when I scrool up the list, items at end of list are coming to top of list.

So it doesn't display the values or rows that needed to display.

my getView() method's last state is..

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


        ViewHolder viewHolder;

            if (convertView == null) {

                convertView = mInflater.inflate(R.layout.row_layout, null);

                TextView programName = (TextView)convertView.findViewById(R.id.programName);
                TextView programTime = (TextView)convertView.findViewById(R.id.programTime);
                TextView programState = (TextView)convertView.findViewById(R.id.programState);
                ImageView programImage = (ImageView)convertView.findViewById(R.id.programImage);


                programName.setText(values.programNames.get(position));
                programTime.setText(values.programTimes.get(position));
                new imageDownload(programImage).execute(values.programImageUrls.get(position)); 

                viewHolder = new ViewHolder();
                viewHolder.p_Name = programName;
                viewHolder.p_Time = programTime;
                viewHolder.p_State = programState;
                viewHolder.p_Image = programImage;

                convertView.setTag(viewHolder);

            }else{

                viewHolder = (ViewHolder) convertView.getTag();
            }

            return convertView;
        }

my view Holder...

public static class ViewHolder {
     TextView p_Name;
     TextView p_Time;
     TextView p_State;
     ImageView p_Image;
}

Thank you a lot


Move this outside of where you set up your convertview

programName.setText(values.programNames.get(position));
programTime.setText(values.programTimes.get(position));
new imageDownload(programImage).execute(values.programImageUrls.get(position));

So that it looks like this

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


    ViewHolder viewHolder;

        if (convertView == null) {

            convertView = mInflater.inflate(R.layout.row_layout, null);

            TextView programName = (TextView)convertView.findViewById(R.id.programName);
            TextView programTime = (TextView)convertView.findViewById(R.id.programTime);
            TextView programState = (TextView)convertView.findViewById(R.id.programState);
            ImageView programImage =(ImageView)convertView.findViewById(R.id.programImage);



            viewHolder = new ViewHolder();
            viewHolder.p_Name = programName;
            viewHolder.p_Time = programTime;
            viewHolder.p_State = programState;
            viewHolder.p_Image = programImage;

            convertView.setTag(viewHolder);

        }else{

            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.p_Name.setText(values.programNames.get(position));
        viewHolder.p_Time.setText(values.programTimes.get(position));
        new imageDownload(programImage).execute(values.programImageUrls.get(position)); 


        return convertView;
    }

Also, I would highly recommend using Picasso for your image download since it handles cacheing automatically for you. I would also look at injecting your ViewHolder with Butterknife and that will reduce your code up here as well


Thank you for your answers. I decided to use Picasso for Images. I simply changed the code like below

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

 ViewHolder viewHolder;

    if (convertView == null) {

        convertView = mInflater.inflate(R.layout.row_layout, null);

        TextView programName = (TextView)convertView.findViewById(R.id.programName);
        TextView programTime = (TextView)convertView.findViewById(R.id.programTime);
        TextView programState = (TextView)convertView.findViewById(R.id.programState);
        ImageView programImage =(ImageView)convertView.findViewById(R.id.programImage);

        viewHolder = new ViewHolder();
        viewHolder.p_Name = programName;
        viewHolder.p_Time = programTime;
        viewHolder.p_State = programState;
        viewHolder.p_Image = programImage;

        convertView.setTag(viewHolder);

    }else{

        viewHolder = (ViewHolder) convertView.getTag();
    }
            viewHolder.p_Ad.setText(values.programIsimleri.get(position));
            viewHolder.p_Saat.setText(values.programSaatleri.get(position));
  Picasso.with(getApplicationContext()).load(values.programImageUrls.get(position)).into(viewHolder.p_Image);


    return convertView;
}

The code is working correctly now.


You should have a position value on the ViewHolder class so you can compare the position of the retrieved ViewHolder from convertView.getTag(). If convertView is not null, you want to make sure you have the correct information in the view.

if (viewHolder.position != position) {
    //retrieves the correct position of the information
    viewHolder.p_Name.setText(values.programNames.get(position)); 

    //etc
    viewHolder.position = position;
}
链接地址: http://www.djcxy.com/p/67342.html

上一篇: 在ListViewAdapter中的onClickListener方法内使用holder变量

下一篇: 当我滚动列表视图时,列表视图中项目的位置正在改变