【问题标题】:Android ListView with Image and Text; can't display ListView带有图像和文本的 Android ListView;无法显示列表视图
【发布时间】:2013-04-13 04:25:26
【问题描述】:

我正在尝试显示带有图像和文本的 ListView,我使用了 Simpleadapter 类,但我无法显示 ListView 谁能帮助我,我做错了什么?

这是我的代码:

public class HostsActivity extends ListActivity {
    public final static String ITEM_TITLE = "title";
    public final static String ITEM_IMAGE = "Image";
    private List<HostsProfile> hostsProfile1;
    List<Map<String, ?>> security = new LinkedList<Map<String, ?>>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.hostslist);

        Bundle recdData = getIntent().getExtras();

        hostsProfile1 = recdData.getParcelableArrayList("hostsProfile");

        List<Map<String, ?>> security1 = new LinkedList<Map<String, ?>>();
        for (HostsProfile msg1 : hostsProfile1) {
            // Log.v("image","Image path"+msg.getImage());
            try {
                URL url = new URL(msg1.getMediathumbnail());
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                InputStream is = con.getInputStream();
                Bitmap img = BitmapFactory.decodeStream(is);
                security.add(createItem(msg1.getTitle(), img));
            } catch (Throwable t) {
            }
        }
        /*for(int i=0; i<security.size(); i++){
            security.remove(0);
        }
        */
        SimpleAdapter adapter1 = new SimpleAdapter(this, security1,
                R.layout.image_text_layout1, new String[] { ITEM_IMAGE,
                        ITEM_TITLE }, new int[] { R.id.feed_image,
                        R.id.job_text });
        adapter1.setViewBinder(new MyViewBinder());
        this.setListAdapter(adapter1);
    }

    public Map<String, ?> createItem(String title, Bitmap Image) {
        Map<String, Object> item = new HashMap<String, Object>();
        item.put(ITEM_TITLE, title);
        item.put(ITEM_IMAGE, Image);
        return item;
    }
    //for ImageView
    class MyViewBinder implements ViewBinder {
        public boolean setViewValue(View view, Object data,
                String textRepresentation) {
            if ((view instanceof ImageView) & (data instanceof Bitmap)) {
                ImageView image1 = (ImageView) view;
                Bitmap bm = (Bitmap) data;
                image1.setImageBitmap(bm);
                return true;
            }
            return false;
        }
    }

}

这是我的布局 xml 文件:

image_text_layout1:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <ImageView android:id="@+id/feed_image"
        android:layout_width="60dp" 
        android:layout_height="60dp"
        android:gravity="center_vertical"
        android:paddingRight="3dp"
        android:paddingLeft="2dp"/>

    <TextView android:id="@+id/job_text" 
        android:layout_width="wrap_content"
        android:layout_height="60dp" 
        android:textColor="#000000"
        android:textStyle="bold"
        android:gravity="center_vertical"/>
        <!--android:paddingTop="5dip"
        android:paddingBottom="28dip" 
        android:paddingLeft="8dip"
        android:paddingRight="8dip" />-->

</LinearLayout>

hostslist.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/background"
    >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <LinearLayout
            android:id="@+id/linearlayout01"
            android:layout_width="300dp"
            android:layout_height="45dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="52dp"
            android:orientation="vertical" >
        </LinearLayout>

        <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="230dp"
            android:layout_alignParentRight="true"
            android:layout_marginTop="107dp"
            android:cacheColorHint="#00000000">

        </ListView>  

    </RelativeLayout>

</LinearLayout>

【问题讨论】:

    标签: android android-layout android-intent android-widget


    【解决方案1】:

    创建一个CustomListview 项目:

    CustomListView.java

    package com.example.customlistview;
    
    import java.util.ArrayList;
    
    import android.os.Bundle;
    import android.widget.ListView;
    import android.app.Activity;
    
    public class CustomListView extends Activity {
        ArrayList<Contact> imageArry = new ArrayList<Contact>();
        ContactImageAdapter adapter;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            // add image and text in arraylist
            imageArry.add(new Contact(R.drawable.facebook, "FaceBook"));
            imageArry.add(new Contact(R.drawable.google, "Google"));
            imageArry.add(new Contact(R.drawable.ical, "Ical"));
            imageArry.add(new Contact(R.drawable.outlook, "Outlook"));
            imageArry.add(new Contact(R.drawable.twitter, "Twitter"));
            // add data in contact image adapter
            adapter = new ContactImageAdapter(this, R.layout.list, imageArry);
            ListView dataList = (ListView) findViewById(R.id.list);
            dataList.setAdapter(adapter);
        }
    }
    

    Contact.java

    package com.example.customlistview;
    public class Contact
    {
        int image;
        String name;
    
        public int getImage() {
            return image;
        }
    
        public void setImage(int image) {
            this.image = image;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Contact(int image, String name) {
            super();
            this.image = image;
            this.name = name;
        }
    }
    

    ContactImageAdapter.java

    package com.example.customlistview;
    
    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class ContactImageAdapter extends ArrayAdapter<Contact> {
        Context context;
       int layoutResourceId;
       ArrayList<Contact> data=new ArrayList<Contact>();
       public ContactImageAdapter(Context context, int layoutResourceId, ArrayList<Contact> data) {
           super(context, layoutResourceId, data);
           this.layoutResourceId = layoutResourceId;
           this.context = context;
           this.data = data;
       }
    
       @Override
       public View getView(int position, View convertView, ViewGroup parent) {
           View row = convertView;
           ImageHolder holder = null;
    
           if(row == null)
           {
               LayoutInflater inflater = ((Activity)context).getLayoutInflater();
               row = inflater.inflate(layoutResourceId, parent, false);
    
               holder = new ImageHolder();
               holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
               holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
               row.setTag(holder);
           }
           else
           {
               holder = (ImageHolder)row.getTag();
           }
    
           Contact myImage = data.get(position);
           holder.txtTitle.setText(myImage.name);
           int outImage=myImage.image;
           holder.imgIcon.setImageResource(outImage);
          return row;
    
       }
    
       static class ImageHolder
       {
           ImageView imgIcon;
           TextView txtTitle;
       }
    }
    

    main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    
        <ListView
            android:id="@+id/list"
            android:layout_width="0dp"
            android:layout_height="fill_parent"
            android:layout_weight="0.55" >
        </ListView>
    </LinearLayout>
    

    list.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal"
        android:padding="10dp" ><ImageView
            android:id="@+id/imgIcon"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.71"
            android:gravity="center_vertical"/>
         <TextView
            android:id="@+id/txtTitle"
            android:layout_width="80dp"
            android:layout_height="fill_parent"
            android:gravity="center_vertical"
            android:textSize="14dp"
            android:layout_marginLeft="7dp" />
          </LinearLayout>
    

    将icon放入drwable中,用于主activity图片数组。

    【讨论】:

      【解决方案2】:

      我建议您使用带有自定义适配器的自定义列表视图。

      下面的链接中提供了一个示例。

      android-custom-listview-with-image-and-text

      使用 viewholder 来实现平滑的滚动和性能。

      您也可以使用惰性列表或通用图像加载器。

      两者都使用缓存。

      Lazy List and Universal Image Loader

      查看以下链接以获取查看器并有效加载位图

      Listview smooth scrolling using ViewHolder

      The world of Listview talk by android developers at google 讨论的是viewholder 和list view 的性能。

      Loading bitmaps efficiently from developer site。有效地加载位图。

      【讨论】:

        【解决方案3】:

        为延迟加载 FileCache.java 添加类

        ========

        public class FileCache {
        
            private File cacheDir;
        
            public FileCache(Context context){
                //Find the dir to save cached images
                if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
                    cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
                else
                    cacheDir=context.getCacheDir();
                if(!cacheDir.exists())
                    cacheDir.mkdirs();
            }
        
            public File getFile(String url){
                //I identify images by hashcode. Not a perfect solution, good for the demo.
                String filename=String.valueOf(url.hashCode());
                //Another possible solution (thanks to grantland)
                //String filename = URLEncoder.encode(url);
                File f = new File(cacheDir, filename);
                return f;
        
            }
        
            public void clear(){
                File[] files=cacheDir.listFiles();
                if(files==null)
                    return;
                for(File f:files)
                    f.delete();
            }
        
        }
        

        =========ImageLoader.java

        public class ImageLoader {
        
            MemoryCache memoryCache=new MemoryCache();
            FileCache fileCache;
            private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
            ExecutorService executorService;
            Handler handler=new Handler();//handler to display images in UI thread
        
            public ImageLoader(Context context){
                fileCache=new FileCache(context);
                executorService=Executors.newFixedThreadPool(5);
            }
        
            final int stub_id=R.drawable.stub;
            public void DisplayImage(String url, ImageView imageView)
            {
                imageViews.put(imageView, url);
                Bitmap bitmap=memoryCache.get(url);
                if(bitmap!=null)
                    imageView.setImageBitmap(bitmap);
                else
                {
                    queuePhoto(url, imageView);
                    imageView.setImageResource(stub_id);
                }
            }
        
            private void queuePhoto(String url, ImageView imageView)
            {
                PhotoToLoad p=new PhotoToLoad(url, imageView);
                executorService.submit(new PhotosLoader(p));
            }
        
            private Bitmap getBitmap(String url) 
            {
                File f=fileCache.getFile(url);
        
                //from SD cache
                Bitmap b = decodeFile(f);
                if(b!=null)
                    return b;
        
                //from web
                try {
                    Bitmap bitmap=null;
                    URL imageUrl = new URL(url);
                    HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
                    conn.setConnectTimeout(30000);
                    conn.setReadTimeout(30000);
                    conn.setInstanceFollowRedirects(true);
                    InputStream is=conn.getInputStream();
                    OutputStream os = new FileOutputStream(f);
                    Utils.CopyStream(is, os);
                    os.close();
                    conn.disconnect();
                    bitmap = decodeFile(f);
                    return bitmap;
                } catch (Throwable ex){
                   ex.printStackTrace();
                   if(ex instanceof OutOfMemoryError)
                       memoryCache.clear();
                   return null;
                }
            }
        
            //decodes image and scales it to reduce memory consumption
            private Bitmap decodeFile(File f){
                try {
                    //decode image size
                    BitmapFactory.Options o = new BitmapFactory.Options();
                    o.inJustDecodeBounds = true;
                    FileInputStream stream1=new FileInputStream(f);
                    BitmapFactory.decodeStream(stream1,null,o);
                    stream1.close();
        
                    //Find the correct scale value. It should be the power of 2.
                    final int REQUIRED_SIZE=70;
                    int width_tmp=o.outWidth, height_tmp=o.outHeight;
                    int scale=1;
                    while(true){
                        if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                            break;
                        width_tmp/=2;
                        height_tmp/=2;
                        scale*=2;
                    }
        
                    //decode with inSampleSize
                    BitmapFactory.Options o2 = new BitmapFactory.Options();
                    o2.inSampleSize=scale;
                    FileInputStream stream2=new FileInputStream(f);
                    Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2);
                    stream2.close();
                    return bitmap;
                } catch (FileNotFoundException e) {
                } 
                catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        
            //Task for the queue
            private class PhotoToLoad
            {
                public String url;
                public ImageView imageView;
                public PhotoToLoad(String u, ImageView i){
                    url=u; 
                    imageView=i;
                }
            }
        
            class PhotosLoader implements Runnable {
                PhotoToLoad photoToLoad;
                PhotosLoader(PhotoToLoad photoToLoad){
                    this.photoToLoad=photoToLoad;
                }
        
                public void run() {
                    try{
                        if(imageViewReused(photoToLoad))
                            return;
                        Bitmap bmp=getBitmap(photoToLoad.url);
                        memoryCache.put(photoToLoad.url, bmp);
                        if(imageViewReused(photoToLoad))
                            return;
                        BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
                        handler.post(bd);
                    }catch(Throwable th){
                        th.printStackTrace();
                    }
                }
            }
        
            boolean imageViewReused(PhotoToLoad photoToLoad){
                String tag=imageViews.get(photoToLoad.imageView);
                if(tag==null || !tag.equals(photoToLoad.url))
                    return true;
                return false;
            }
        
            //Used to display bitmap in the UI thread
            class BitmapDisplayer implements Runnable
            {
                Bitmap bitmap;
                PhotoToLoad photoToLoad;
                public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
                public void run()
                {
                    if(imageViewReused(photoToLoad))
                        return;
                    if(bitmap!=null)
                        photoToLoad.imageView.setImageBitmap(bitmap);
                    else
                        photoToLoad.imageView.setImageResource(stub_id);
                }
            }
        
            public void clearCache() {
                memoryCache.clear();
                fileCache.clear();
            }
        
        }
        

        ======MemoryCache.java

        public class MemoryCache {
        
            private static final String TAG = "MemoryCache";
            private Map<String, Bitmap> cache=Collections.synchronizedMap(
                    new LinkedHashMap<String, Bitmap>(10,1.5f,true));//Last argument true for LRU ordering
            private long size=0;//current allocated size
            private long limit=1000000;//max memory in bytes
        
            public MemoryCache(){
                //use 25% of available heap size
                setLimit(Runtime.getRuntime().maxMemory()/4);
            }
        
            public void setLimit(long new_limit){
                limit=new_limit;
                Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
            }
        
            public Bitmap get(String id){
                try{
                    if(!cache.containsKey(id))
                        return null;
                    //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
                    return cache.get(id);
                }catch(NullPointerException ex){
                    ex.printStackTrace();
                    return null;
                }
            }
        
            public void put(String id, Bitmap bitmap){
                try{
                    if(cache.containsKey(id))
                        size-=getSizeInBytes(cache.get(id));
                    cache.put(id, bitmap);
                    size+=getSizeInBytes(bitmap);
                    checkSize();
                }catch(Throwable th){
                    th.printStackTrace();
                }
            }
        
            private void checkSize() {
                Log.i(TAG, "cache size="+size+" length="+cache.size());
                if(size>limit){
                    Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated  
                    while(iter.hasNext()){
                        Entry<String, Bitmap> entry=iter.next();
                        size-=getSizeInBytes(entry.getValue());
                        iter.remove();
                        if(size<=limit)
                            break;
                    }
                    Log.i(TAG, "Clean cache. New size "+cache.size());
                }
            }
        
            public void clear() {
                try{
                    //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
                    cache.clear();
                    size=0;
                }catch(NullPointerException ex){
                    ex.printStackTrace();
                }
            }
        
            long getSizeInBytes(Bitmap bitmap) {
                if(bitmap==null)
                    return 0;
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        }
        

        =====Utils.java

        public class Utils {
            public static void CopyStream(InputStream is, OutputStream os)
            {
                final int buffer_size=1024;
                try
                {
                    byte[] bytes=new byte[buffer_size];
                    for(;;)
                    {
                      int count=is.read(bytes, 0, buffer_size);
                      if(count==-1)
                          break;
                      os.write(bytes, 0, count);
                    }
                }
                catch(Exception ex){}
            }
        }
        

        ====ContactImageAdapte.java

        public class ContactImageAdapter extends ArrayAdapter<Contact>{
        Context context;
           int layoutResourceId;   
        public ImageLoader imageLoader;
           ArrayList<Contact> data=new ArrayList<Contact>();
           public ContactImageAdapter(Context context, int layoutResourceId, ArrayList<Contact> data) {
               super(context, layoutResourceId, data);
               this.layoutResourceId = layoutResourceId;
               this.context = context;
               this.data = data;
             this.imageLoader=new ImageLoader(context);
           }
        
           @Override
           public View getView(int position, View convertView, ViewGroup parent) {
               View row = convertView;
               ImageHolder holder = null;
        
               if(row == null)
               {
                   LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                   row = inflater.inflate(layoutResourceId, parent, false);
        
                   holder = new ImageHolder();
                   holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
                   holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
                   row.setTag(holder);
               }
               else
               {
                   holder = (ImageHolder)row.getTag();
               }
        
               Contact myImage = data.get(position);
               holder.txtTitle.setText(myImage.name);
                  int outImage=myImage.image;
              imageLoader.DisplayImage(listres.ItemImage,holder.ItamImage);
              return row;
        
           }
        
           static class ImageHolder
           {
               ImageView imgIcon;
               TextView txtTitle;
           }
        }
        

        =====试试这个

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多