ListView Images are only showed when I scroll (and

2019-08-02 23:43发布

问题:

I know that the problem have been treated in other post but after reading several articles and tutorial i don't understand...

I have the follogin rox.xml for each listview item

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
android:id="@+id/RelativeLayout01" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"
android:background="#FFFFFF" 
xmlns:android="http://schemas.android.com/apk/res/android">

<ImageView 
android:layout_height="50sp" 
android:layout_width="50sp" 
android:layout_alignParentLeft="true" 
android:id="@+id/ImageIcon"/>

<TextView 
android:text="@+id/TextView01" 
android:id="@+id/TitleText"
android:textStyle="bold"
android:textSize="20sp" 
android:layout_toRightOf="@id/ImageIcon"
android:layout_alignParentTop="true"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:textColor="#333333"
/>

<TextView 
android:text="@+id/TextView02" 
android:id="@+id/DescriptionText" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
android:textSize="12sp"
android:background="#FFFFFF"
android:textColor="#333333"
android:layout_toRightOf="@id/ImageIcon"
android:layout_below="@id/TitleText"
android:layout_alignWithParentIfMissing="true"
/>

</RelativeLayout>

My ListViewAdapter has the following getView (with a ViewWrapper)

public View getView(int position, View convertView, ViewGroup parent)
    {
        View row=convertView;
        ViewWrapper wrapper=null;
        Activity activity=(Activity)getContext();

        RssItem item=getItem(position);

        if (row == null) {

            LayoutInflater inflater=activity.getLayoutInflater();
        row=inflater.inflate(R.layout.row,null);
        wrapper=new ViewWrapper(row);
        row.setTag(wrapper);
    }
        else
        {
            wrapper=(ViewWrapper)row.getTag();
        }

        wrapper.getTitle().setText(item.getTitle());
        String cleaned=item.getDescription().replaceAll("\\<.*?\\>", "");
        int Long=cleaned.length();
        if (Long<=100)
        {
            wrapper.getDescription().setText(cleaned);
        }
        else wrapper.getDescription().setText(cleaned.substring(0, 50)+"...");

        String laurl=item.getImageUrl();

        if (laurl!="") 
        { 
            Drawable cachedImage = imageloader.loadDrawable(laurl);
            wrapper.getImage().setImageDrawable(cachedImage);
        }
        else 
        {
            wrapper.getImage().setImageResource(R.drawable.icon);
        }

        return row;

    }

    class ViewWrapper {

        private View base;
        private TextView title=null;
        private TextView description=null;
        private ImageView icono=null;

        ViewWrapper (View base) {
            this.base=base;
        }

        public TextView getTitle() {
            if (title==null) {
                title=(TextView)base.findViewById(R.id.TitleText);
            }
            return title;
        }

        public TextView getDescription() {
            if (description==null) {
                description=(TextView)base.findViewById(R.id.DescriptionText);
            }
            return description;
        }

        public ImageView getImage() {
            if (icono==null) {
                icono=(ImageView)base.findViewById(R.id.ImageIcon);
            }
            return icono;
        }       

    }

And I'm getting images throgh the following class.

public class ImageThreadLoader  {


    //GlobalCache
    private HashMap<String, SoftReference<Drawable>> imagecache;

    public ImageThreadLoader()
    {
        imagecache= new HashMap<String, SoftReference<Drawable>>();
    }

    public Drawable loadDrawable(final String imageurl) //,final ImageCallback imageCallback)
    {
        if (imagecache.containsKey(imageurl))
        {
            SoftReference<Drawable> softReference=imagecache.get(imageurl);
            Drawable drawable=softReference.get();
            if (drawable != null) {
                return drawable;
            }
        }

        new Thread() {
            @Override
            public void run() {
                Drawable drawable = loadImageFromUrl(imageurl);
                imagecache.put(imageurl, new SoftReference<Drawable>(drawable));
            }
        }.start();
        return null;
    }

    public static Drawable loadImageFromUrl(String url) {
        InputStream inputStream;
        try {
            inputStream = new URL(url).openStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return Drawable.createFromStream(inputStream, "src");
    }

}

Now the listview scrolls smoothly but at the beginning no image are loaded. Then if I scroll up and down repeatedly images appear and sometime disappear.

I think the problem is that i really dont understand how things works..

Thanks in adavance

回答1:

Might want to take a look at this: http://www.youtube.com/watch?v=wDBM6wVEO70

It's a session from Google I/O entirely about ListViews.



回答2:

I had the same problem today. What is not explained in the documentation nor in the video posted by Pavandroid is that you need to set the state of certain properties and not rely upon the defaults of those states as they are set in the layout file.

For example, in my app, an image is displayed in a row depending on the state of the data for that row. In my layout file the default is that the image normally would be shown. When getView is called and an image is not to be shown, I make the image invisible with

If (hideImage)
  someImage.setVisibility(View.INVISIBLE);

It was logical to assume that if hideImage was false, then the image would be displayed but during scrolling it eventually disappears. Instead of relying upon the layout file default, I had to explicity set the visibility:

If (hideImage)
  someImage.setVisibility(View.INVISIBLE);
else
  someImage.setVisibility(View.VISIBLE);

This corrected the problem.