0

大家,我遇到一个问题,我使用 listView 显示来自本地资源的数百张图像,并且我将图像设置为全屏。每个列表项中有一个带有 imageView 和 TextView 的项目。但是当我滑动到下一项,不太顺利。我使用ImageFactory.options调整图像的比例。但问题仍然存在。我想也许我应该使用异步任务加载和图像缓存来解决这个问题。这是我的代码,希望你们能指出我的问题。非常感谢。

package com.jafir.project.adapter;


import java.util.List;
import java.util.Map;

import com.jafir.project.porunacabeza.R;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.RecyclerListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class PicListViewAdapter extends BaseAdapter  {
    private Context context;
    private Resources resources;
    private LayoutInflater inflater;
    private ViewHolder holder;
    private List<Map<String, Object>> list;
    public PicListViewAdapter(Context context,List<Map<String, Object>> list) {
        this.list = list;
        this.context = context;
        this.inflater = LayoutInflater.from(context);
        resources = context.getResources();
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int arg0) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

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

        if(convertView == null) {
             convertView = inflater.inflate(R.layout.item_pic, null);
            holder =  new ViewHolder();
            holder.imageView = (ImageView) convertView.findViewById(R.id.img_pic);
            holder.textView = (TextView) convertView.findViewById(R.id.txt_pic);
            convertView.setTag(holder);

        }else {
            holder = (ViewHolder) convertView.getTag();
        }
        int resID = (Integer) list.get(position).get("image");
        String text = (String) list.get(position).get("text");
        holder.imageView.setImageBitmap(decodeBitmap(resources, resID, holder.imageView.getWidth(),          holder.imageView.getHeight()));
        holder.textView.setText(text);
        notifyDataSetChanged();
        return convertView;
    }

    public Bitmap decodeBitmap(Resources res,int id,int width,int height){
        BitmapFactory.Options  options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res,id,options);
        options.inSampleSize = getInSampleSize(options,width,height);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res,id,options);
    }

    public int getInSampleSize(BitmapFactory.Options options,int reqWidth,int reqHeight){
        final int width  = options.outWidth;
        final int height = options.outHeight;
        int inSampleSize = 1;
        if(height > reqHeight || width > reqWidth) {
            int radioWidth = Math.round((float)width/(float)reqWidth);
            int radioHeight = Math.round((float)height/(float)reqHeight);
            inSampleSize = radioHeight < radioWidth ?radioHeight:radioWidth;
        }
        return inSampleSize;
    }

      final static class ViewHolder{
            ImageView imageView;
            TextView textView;
        }
}

这是为了活动:

 private void init() {
        listView = (ListView) getActivity().findViewById(R.id.lst_pic);
        list = new ArrayList<Map<String,Object>>();
        for(int i=0;i < texts.length;i++){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("image", R.drawable.img0+ i);
            map.put("text", texts[i]);
            list.add(map);
        }
        listView.setAdapter(new PicListViewAdapter(getActivity(), list));
    }

这是针对 item.xml:

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

    <ImageView android:id="@+id/img_pic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        />
    <TextView android:id="@+id/txt_pic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:gravity="center_horizontal"
        android:layout_gravity="center_horizontal"
        />


</LinearLayout>
4

3 回答 3

0

如果我是你,我会使用该列表适配器,但在其中使用picasso库来加载图像。Picasso 不会在 UI 线程上加载图像。这就是您收到此错误的原因。添加库后,尝试getView()像这样:

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

    if(convertView == null) {
         convertView = inflater.inflate(R.layout.item_pic, null);
        holder =  new ViewHolder();
        holder.imageView = (ImageView) convertView.findViewById(R.id.img_pic);
        holder.textView = (TextView) convertView.findViewById(R.id.txt_pic);
        convertView.setTag(holder);

    }else {
        holder = (ViewHolder) convertView.getTag();
    }
    int resID = (Integer) list.get(position).get("image");
    String text = (String) list.get(position).get("text");
    //Picasso code
    Picasso.Builder builder = new Picasso.Builder(context);
    Picasso picasso = builder.build();
    picasso.load(resID).into(holder.imageView);
    //End Picasso code
    holder.textView.setText(text);
    notifyDataSetChanged();
    return convertView;
}
于 2015-01-09T04:26:04.933 回答
0

There is a comprehensive guide on Android official site, please refer it at http://developer.android.com/training/displaying-bitmaps/index.html

The session contains the following topics:

Loading Large Bitmaps Efficiently This lesson walks you through decoding large bitmaps without exceeding the per application memory limit.

Processing Bitmaps Off the UI Thread Bitmap processing (resizing, downloading from a remote source, etc.) should never take place on the main UI thread. This lesson walks you through processing bitmaps in a background thread using AsyncTask and explains how to handle concurrency issues.

Caching Bitmaps This lesson walks you through using a memory and disk bitmap cache to improve the responsiveness and fluidity of your UI when loading multiple bitmaps.

Managing Bitmap Memory This lesson explains how to manage bitmap memory to maximize your app's performance.

Displaying Bitmaps in Your UI This lesson brings everything together, showing you how to load multiple bitmaps into components like ViewPager and GridView using a background thread and bitmap cache.

于 2015-01-09T03:15:16.767 回答
0

你的猜测是正确的。我可能在 2 年前使用来自 tomgibara的 ViewRenderer ( https://gist.github.com/tomgibara/1084229 ) 测试了实现,从而产生了非常流畅的输出。很好

如果我想尝试一下,我会尝试自己创建一个机制。供您参考的一些注意事项:

  • 将解码后的位图放入 LRUCache,这样就不会出现 OutOfMemoryError。说真的,当您加载大量图像时,这很可能发生。
  • 随意使用 AsyncTask/Loader/Raw Thread。本质上没有太大区别。
于 2015-01-09T03:32:14.690 回答