16

你好我面临一个特殊的问题,我需要下载图像并将它们显示到ListView对应于他们特定的TextView's. 我拥有的代码成功显示了TextView's我需要显示的,但我不知道如何在我的文本视图旁边显示所有这些不同的图像ListView

在经历了SO中的许多线程之后。最佳答案是通过 1. Lazy List 2. Universal Image Loader 解决这个问题

我已经经历了这两种解决方案。我下载了惰性列表代码,其中 URL 是存储在数组中的硬编码字符串。我想做的是动态创建自己的字符串。将它们存储到缓存中并显示所有相应的图像。

这是我的代码:

public class Tools_ListItemActivity extends ListActivity 
{
    private Context context;
    String s;

    private static final String TAG_POSTS = "posts";
    private static final String TAG_MDNAME = "mdname";
    private static final String TAG_UTCOST = "utcost";
    private static final String TAG_IIMG= "iimg";
    JSONArray posts = null;

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

        setContentView(R.layout.main);
        s=getIntent().getExtras().getString("url");
        new ProgressTask(Tools_ListItemActivity.this).execute();
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
    }

ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();

     ListView lv ;



      private class ProgressTask extends AsyncTask<String, Void, Boolean> {
      private ProgressDialog dialog;

       public ProgressTask(ListActivity activity) {

       Log.i("1", "Called");
       context = activity;
       dialog = new ProgressDialog(context);
      }

       /** progress dialog to show user that the backup is processing. */

       /** application context. */
      private Context context;

       protected void onPreExecute() {
       this.dialog.setMessage("Progress start");
       this.dialog.show();
      }

       @Override
      protected void onPostExecute(final Boolean success) {
       if (dialog.isShowing()) {
        dialog.dismiss();
       }
       ListAdapter adapter = new SimpleAdapter(context, jsonlist,
         R.layout.activity_toolsitem, new String[] { TAG_IIMG, TAG_MDNAME, TAG_UTCOST  }, new int[] {
           R.id.imageViewUrl, R.id.mdname, R.id.utcost });

        setListAdapter(adapter);

        // selecting single ListView item
        lv = getListView();

      }

       protected Boolean doInBackground(final String... args) {

        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(s);


        try {
            posts = json.getJSONArray(TAG_POSTS);
        } catch (JSONException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try
        {
        // looping through All Contacts
        for(int i = 0; i < posts.length(); i++){
            JSONObject c = posts.getJSONObject(i);

            // Storing each json item in variable
            String mdname = c.getString(TAG_MDNAME);
            String utcost= c.getString(TAG_UTCOST);
            String iimg=c.getString(TAG_IIMG);

            //Forming the Url of the image to be shown in the list view
            String imageUrl="My_App_URL"+iimg;

/*  try {

              String imageUrl="My_App_URL"+iimg;
              ImageView imageView = (ImageView)findViewById(R.id.imageViewUrl);
              Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
              imageView.setImageBitmap(bitmap); 
            } catch (MalformedURLException e) {
              e.printStackTrace();
            } catch (IOException e) {
              e.printStackTrace();
            } */


            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            // adding each child node to HashMap key => value
            map.put(TAG_MDNAME, mdname);
            map.put(TAG_UTCOST, utcost);
            map.put(TAG_IIMG, iimg);



         jsonlist.add(map);
        } }catch (JSONException e) 
        {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }


        return null;


       }

      }





}

在这里,我已经调试并发现imageUrl正确形成。Json仅返回名称,jpg因此我将其附加到 URL 并将其存储在imageUrl. 其他两个文本视图正在正确解析和显示。如果有人也可以帮助我在图像视图中显示图像,那就太好了。谢谢。

更新: 借助 Pankaj 共享的链接(https://github.com/AndroidBegin/Android-JSON-Parse-Images-and-Texts-Tutorial)和共享的概念知识,我能够解决我的特定问题拉古南丹在下面。请仔细阅读这些答案以获取详细说明以及延迟加载的实现。我很抱歉,因为我离开了两天,所以无法用赏金来奖励答案。

4

5 回答 5

17

使用 Universal Imageloader 进行延迟加载。用图像的 url 替换硬编码的 url。

根据您的要求修改以下内容

什么是懒惰列表?. 检查此链接以获取详细信息。

MainActivity.java

public class MainActivity extends Activity {

  private String[] mStrings={
            "http://a3.twimg.com/profile_images/670625317/aam-logo-v3-twitter.png",
            "http://a3.twimg.com/profile_images/740897825/AndroidCast-350_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook.png",
            "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",
            "http://a1.twimg.com/profile_images/74724754/android_logo_normal.png",
            "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",
            "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",
            "http://a3.twimg.com/profile_images/548410609/icon_8_73.png",
            "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",
            "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",
            "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_android_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a3.twimg.com/profile_images/670625317/aam-logo-v3-twitter_normal.png",
            "http://a3.twimg.com/profile_images/740897825/AndroidCast-350_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",
            "http://a1.twimg.com/profile_images/74724754/android_logo.png",
            "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",
            "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",
            "http://a3.twimg.com/profile_images/548410609/icon_8_73_normal.png",
            "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",
            "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",
            "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_android.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/android_logo_small.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png"
    };

    ListView lv;    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv= (ListView) findViewById(R.id.lv);
        lv.setAdapter(new LazyAdapter(this,mStrings));
    }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <ListView
        android:id="@+id/lv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#000000"
        android:focusableInTouchMode="false"
        android:listSelector="@android:color/transparent"
        android:layout_weight="2.0"
        android:divider="#000000"
        android:headerDividersEnabled="false"
        android:footerDividersEnabled="false"
        android:dividerHeight="8dp"
        android:drawSelectorOnTop="false"
        />
</RelativeLayout>

LazyAdapter.java

public class LazyAdapter extends BaseAdapter {
    private Activity activity;
    private String data[];
    private LayoutInflater inflater=null;
    public ImageLoader imageLoader; 
    DisplayImageOptions options;
    public LazyAdapter(Activity a, String[] d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        File cacheDir = StorageUtils.getOwnCacheDirectory(a, "MyFolderCache");

        // Get singletone instance of ImageLoader
        imageLoader = ImageLoader.getInstance();
        // Create configuration for ImageLoader (all options are optional)
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
              // You can pass your own memory cache implementation
             .discCacheExtraOptions(1024, 1024, CompressFormat.PNG, 100)
             .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
             .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
             .enableLogging()
             .build();
        // Initialize ImageLoader with created configuration. Do it once.
        imageLoader.init(config);
        //imageLoader.init(ImageLoaderConfiguration.createDefault(a));
        // imageLoader=new ImageLoader(activity.getApplicationContext());
        options = new DisplayImageOptions.Builder()
             .showStubImage(R.drawable.ic_launcher)
             .cacheInMemory()
             .cacheOnDisc()
             .displayer(new RoundedBitmapDisplayer(20))
             .build();
    }

    public int getCount() {
        return data.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        ViewHolder vh = new ViewHolder();;
        if(convertView==null)
        {

            vi = inflater.inflate(R.layout.row, null);   
            vh.iv=(ImageView)vi.findViewById(R.id.ivv); 
            vh.pb= (ProgressBar)vi.findViewById(R.id.pb); 
            vh.tv = (TextView) vi.findViewById(R.id.textView1);
            vh.tv1= (TextView) vi.findViewById(R.id.textView2);
        }
        vh.tv.setText("Image in postion =");
        vh.tv1.setText(""+position);
        display(vh.iv, data[position], vh.pb);
        //imageLoader.displayImage(data.get(position).toString(), image,options);
        return vi;
    }

    public void display(ImageView img, String url, final ProgressBar spinner)
    {
        imageLoader.displayImage(url, img, options, new ImageLoadingListener() {
            @Override
            public void onLoadingStarted(String imageUri, View view) {
                spinner.setVisibility(View.VISIBLE);
            }
            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                spinner.setVisibility(View.GONE);
            }
            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            spinner.setVisibility(View.GONE);
            }
            @Override
            public void onLoadingCancelled(String imageUri, View view) {

            }
        });
    }

    public static class ViewHolder
    {
        ImageView iv;
        TextView tv,tv1;
        ProgressBar pb;
    }
}

行.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_launcher" />
    <ProgressBar 
        android:id="@+id/pb"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/textView2"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="21dp"
        android:layout_marginLeft="31dp"
        android:text="TextView" />
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_alignParentBottom="true"
        android:text="TextView" />
</RelativeLayout>

在清单中添加权限

 <uses-permission android:name="android.permission.INTERNET"/>

在此处输入图像描述

于 2013-06-07T07:12:26.580 回答
3

请尝试使用通用图像加载器

public class DetailsListViewAdapter extends ArrayAdapter<Entry>{
    private Context context;
    private List<Entry> detailList;
    DisplayImageOptions options;
    public ImageLoader imageLoader;

    public DetailsListViewAdapter(Context context, int textViewResourceId,List<Entry> detailList) {
        super(context, textViewResourceId,detailList);
        this.detailList = detailList;
        this.context = context;
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(ImageLoaderConfiguration.createDefault(context));
        options = new DisplayImageOptions.Builder()
        .showImageForEmptyUri(R.drawable.blankimage)
        .showImageOnFail(R.drawable.blankimage)
        .resetViewBeforeLoading()
        .cacheOnDisc()
        .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
        .bitmapConfig(Bitmap.Config.RGB_565)
        .displayer(new FadeInBitmapDisplayer(300))
        .build();
    }

    static class ViewHolder{
        private TextView popupDetails;
        private TextView pubDate;
        private ImageView image;
        private ProgressBar progress;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder holder;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.details_list_item, null);
            holder = new ViewHolder();
            holder.popupDetails=(TextView)v.findViewById(R.id.detailHeading);
            holder.pubDate = (TextView)v.findViewById(R.id.pubDate);
            holder.image = (ImageView)v.findViewById(R.id.listImg);
            holder.progress = (ProgressBar)v.findViewById(R.id.progressBar);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }
        Entry value = detailList.get(position);
        holder.popupDetails.setText(value.getTitle());
        holder.pubDate.setText(value.getPubDate());
        String url = value.getImageLink();
        try {
            if(url.length() > 5) {
                holder.image.setVisibility(View.VISIBLE);
                loadImage(holder.image,url,holder.progress);
            } else {
                if(url.equals("NO")) {
                    holder.image.setVisibility(View.INVISIBLE);
                } else {
                    holder.image.setVisibility(View.GONE);
                }
            }
        } catch (Exception e) {
            Logger.show(e);
        }
        v.setBackgroundColor(Color.WHITE);
        return v;

    }
    public void loadImage(ImageView imageView, String loadURL,final ProgressBar progress) {
        imageLoader.displayImage(loadURL, imageView, options, new SimpleImageLoadingListener() {
            @Override
            public void onLoadingStarted(String imageUri, View view) {
                progress.setVisibility(View.VISIBLE);
            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                String message = null;
                switch (failReason) {
                case IO_ERROR:
                    message = "Input/Output error";
                    break;
                case OUT_OF_MEMORY:
                    message = "Out Of Memory error";
                    break;
                case NETWORK_DENIED:
                    message = "Downloads are denied";
                    break;
                case UNSUPPORTED_URI_SCHEME:
                    message = "Unsupported URI scheme";
                    break;
                case UNKNOWN:
                    message = "Unknown error";
                    break;
                }
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLoadingComplete(final String imageUri, View view, final Bitmap loadedImage) {
                progress.setVisibility(View.INVISIBLE);
            }  
        });
    }
}
于 2013-05-28T10:41:59.823 回答
2

这是我在ListView为用户创建联系人列表的过程中加载和缓存图像的方法。所以想象一下左边的个人资料图片,右边的一些文本视图(这听起来接近你正在处理的问题。忽略丑陋的调试标签和可能糟糕的格式(抱歉)。我想这有点像 LazyList 但这里是一个详细的解释,以防有人感到困惑。

第 1 步:设置缓存

private LruCache<String, Bitmap> memoryCache;
private HashMap<String, String> idPairs = new HashMap<String, String>(); 

在我的方法中,我使用 anLruCache和 aHashMap来跟踪我下载了哪些用户的图像。您稍后会看到它是如何实现的,但其想法是避免从服务器下载内容,除非您必须这样做。然后在你的onCreate()或一些相关的方法中,初始化你的缓存。

    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8;
    memoryCache = new LruCache<String, Bitmap>(cacheSize)  {
        @Override 
        protected int sizeOf(String key, Bitmap bitmap){
            return (bitmap.getRowBytes() * bitmap.getHeight()) / 1024; //don't use getByteCount for API < 12
        }
    };

我的下一步是将默认的“空图像”位图添加到缓存中,以防我到达一个没有与之关联的图片的条目。这样我只需要处理和添加这个位图一次

Bitmap defaultPicture = BitmapFactory.decodeResource(getResources(), R.drawable.default_user_picture);
    addBitmapToMemoryCache("default", defaultPicture);

然后是时候获取列表所需的数据了!

第 2 步:获取数据

private class GetPeopleData extends AsyncTask<JSONArray, Void, Void> {

    @Override
    protected Void doInBackground(JSONArray...lists) {
        HttpClient httpClient = new DefaultHttpClient(); 
        HttpPost httpPost = new HttpPost();
        ResponseHandler <String> responseHandler = new BasicResponseHandler();
        if(DEBUG) Log.d("GET PEOPLE DATA TASK", lists[0].length() + " users");
        getUsers(lists[0], httpClient, httpPost, responseHandler);
        return null;
    }

    @Override
    protected void onPostExecute(Void result){
        updateUserListView();
    }

}

这是一个AsyncTaskJSONArray用户数据为参数的无聊。我省略了那部分,因为它几乎只是一个基本的 HTTP 下载,不需要解释。getUsers 方法是我开始将要添加到我的ListView. 我接下来要做的是处理从服务器下载的 JSON 以创建用户对象,并将其添加到将显示的用户列表中。

private void getUsers(JSONArray userArray, HttpClient httpClient, HttpPost httpPost, ResponseHandler<String> responseHandler){
    if(DEBUG) Log.d("USERS ARRAY", userArray.length() + " users");
    try{

        users = new ArrayList<User>();
        if(DEBUG) Log.d("User Array -START", "" + users.size());
        //Go through userArray and get information needed for list
        for(int i = 0; i < userArray.length(); i++){
            User u = new User();
            if(DEBUG) Log.d("User Array - ADD USER", "" + users.size());
            String profileId = userArray.getJSONObject(i).getString("profileid");
            u.setId(userArray.getJSONObject(i).getString("id"));
            u.setDisplayName(userArray.getJSONObject(i).getString("displayname"));
            u.setStatus(userArray.getJSONObject(i).getString("status"));

            //check HashMap for sender/profileid pair
            if(idPairs.containsKey(profileId)){
                if(DEBUG) Log.d("idPairs", "User in HashMap");
                profileId = idPairs.get(profileId);
            } else {
                if(DEBUG) Log.d("idPairs", "User not in HashMap. Add profileId");
                idPairs.put("profileId", profileId);
            }
            u.setProfilePicture(getProfilePictureFromCache(profileId, httpClient, httpPost, responseHandler)); //check cache for image
            users.add(u);
            if(DEBUG) Log.d("User info", u.toString());
        }
    } catch (Exception e) {
        Log.e("BACKGROUND_PROC", e.getMessage());
    }
}

我将图片与最终将显示的用户对象相关联。我认为这不是完全浪费时间,因为图像是从位图缓存中提取的

private Bitmap getProfilePictureFromCache(String profileId, HttpClient httpClient, HttpPost httpPost, ResponseHandler<String> responseHandler){
    Bitmap defaultPicture = getBitmapFromMemCache("default");
    Bitmap profilePicture = getBitmapFromMemCache(profileId);
    if(profilePicture != null){
        return profilePicture;
    } else {        
        String pictureString = getProfilePic(profileId, httpClient, httpPost, responseHandler);
        if(!pictureString.isEmpty()){       
            byte[] decodedString = Base64.decode(pictureString, Base64.DEFAULT);
            profilePicture = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
            addBitmapToMemoryCache(profileId, profilePicture);
            if(DEBUG) Log.d("MEMCACHE", "Download and store picture for " + profileId);
            return profilePicture;
        } else if (defaultPicture != null && pictureString.equals(null)) {
            if(DEBUG) Log.d("MEMCACHE", "Load default picture");
            return defaultPicture;
        }
    }
    return defaultPicture;
}

如果缓存中存在图片,则返回,否则下载。对我来说,显示用户时,每张图片都根据用户 ID 进行缓存,因此即使有人在列表中出现多次,缓存中也只会为该用户存储一张图片。

ImageView profile_picture = (ImageView) v.findViewById(R.id.profile_picture);
if(profile_picture != null){
                profile_picture.setImageBitmap(u.getProfilePicture());
            }

剩下要做的就是ImageView在您的适配器中找到 ,并将该视图设置为您与列表中的对象关联的图片。

于 2013-06-05T19:20:27.803 回答
1

你想要一些易于使用的东西吗?处理缓存文件,删除缓存,在内存处于边界线时释放?

试试 LazyList,看看:

https://github.com/nicolasjafelle/LazyList

如前所述,您只需要在 Application 类或任何其他 Activity 或 Fragment 中创建 Singleton:

//To use the default external folder, this folder will be deleted when the app no longe exists.
ImageLoader.getInstance().init(getApplicationContext());
//Or to use another folder, use...
//ImageLoader.getInstance().init(getApplicationContext(), "MyExternalFolder");

然后在您的具有 ImageView 来显示 de Image 的视图中,您需要实现 ImageProcessingCallback 接口:

public class MyItemView extends LinearLayout implements ImageProcessingCallback {
...
//Do what you need in methods onImagePreProcessing() and onImageProcessing(Bitmap     bitmap)
...
ImageLoader.getInstance().displayImage(data[position], myView);

最后,您需要在 androidManifest.xml 中添加此权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

就是这样。然后你有方法来清除内存缓存或磁盘缓存或两者的缓存。

于 2013-06-06T14:32:14.763 回答
0

我不知道如何存储图像,因为我的应用程序使用来自 APK 的图像。但是,我相信要显示这些图像,您需要自定义 Arrayadapter。

这会扩展每个项目的布局并将其放置在列表中。此布局由您在其构造中创建和指定的 XML 布局定义。您应该尝试使用根据项目设置图像视图的自定义适配器来扩展您当前用于列表视图的任何适配器。

我用 ImageView.setImageResource(resource ID); 但是您的里程可能会有所不同。我在 APK 中有我的图像,不知道如何从外部来源显示它们

于 2013-06-05T18:55:20.530 回答