Android自定义列表视图包含文本和图片从URL加载延迟,尽管使用毕加索图像加载器


Android custom listview containing texts and images loading from URL laggy despite using picasso image loader

我在android中滚动listview时有滞后,基本上我在listview中加载了PHP MySQL远程服务器的数据。数据和图像URL被选中,图像从URL使用picasso加载。

尽管使用了viewhoders和picasso,但它的listview在上下滚动时仍然滞后。

下面是我的代码,谁能建议一个好的方法?

Listview适配器:

public class UserFeedsAdapter extends BaseAdapter {
ViewHolderItem vH;
static class ViewHolderItem {
    ImageView image;
    TextView postUserAndTags;
    TextView postedWhen;
    TextView location;
    TextView feed;
    ImageView feedImage;
}
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
View temp;
HashMap<String, String> feeds = new HashMap<String, String>();
List<String> listItems1;
List<String> listItems2;
public UserFeedsAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
    activity = a;
    data=d;
    inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
    return data.size();
}
public Object getItem(int position) {
    return data.get(position);
}
public long getItemId(int position) {
    return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolderItem viewHolder;
    View vi = convertView;
    if(convertView == null) {
        vi = inflater.inflate(R.layout.user_feeds, null);
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.user_feeds, parent, false);
        viewHolder = new ViewHolderItem();
        viewHolder.image = (ImageView)convertView.findViewById(R.id.imageViewFeed);
        viewHolder.postUserAndTags = (TextView)convertView.findViewById(R.id.postUserAndTags);
        viewHolder.postedWhen = (TextView)convertView.findViewById(R.id.postedWhen);
        viewHolder.location = (TextView)convertView.findViewById(R.id.location);
        viewHolder.feed = (TextView)convertView.findViewById(R.id.feed);
        viewHolder.feedImage = (ImageView)convertView.findViewById(R.id.feedImage);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolderItem) convertView.getTag();
    }
    temp = vi;
    feeds = data.get(position);
    viewHolder.image.setTag(position);
    final String photoPath = feeds.get("user_profile_image");
    if (photoPath != null && photoPath.length() > 0 && !photoPath.equals("null")) {
        GetImage ui = new GetImage(photoPath, viewHolder, 1);
        ui.execute();
    } else {
        viewHolder.image.setImageResource(R.mipmap.ic_default_profile_pic);
    }
    viewHolder.postUserAndTags.setTag(position);
    String a = "<font color='#50c8e3'>" + feeds.get("first_name") + " " + feeds.get("last_name")
            + "</font>";
    int i = 0;
    int count = Integer.parseInt(feeds.get("tagged_tagged_count"));
    while (i < count) {
        if (i == 0) {
            a = a + " <font color='#cccccc'>with</font> ";
        }
        String b = "tagged_first_name" + String.valueOf(i);
        String c = "tagged_last_name" + String.valueOf(i);
        a = a + feeds.get(b) + " " + feeds.get(c);
        if (i + 1 != count) {
            a = a + "<font color='#cccccc'>,</font> ";
        }
        i++;
    }
    if (viewHolder.postUserAndTags != null) {
        viewHolder.postUserAndTags.setText(Html.fromHtml(a));
    }
    viewHolder.postedWhen.setTag(position);
    SimpleDateFormat simpleDateFormat =
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try {
        Date postedDate = simpleDateFormat.parse(feeds.get("insert_dttm"));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(postedDate);
        calendar.add(Calendar.MINUTE, 540);
        postedDate = calendar.getTime();
        String q = simpleDateFormat.format(postedDate);
        postedDate = simpleDateFormat.parse(q);
        Date todaysDate = Calendar.getInstance().getTime();
        String p = simpleDateFormat.format(todaysDate);
        Date today = simpleDateFormat.parse(p);
        long different = today.getTime() - postedDate.getTime();
        long secondsInMilli = 1000;
        long minutesInMilli = secondsInMilli * 60;
        long hoursInMilli = minutesInMilli * 60;
        long daysInMilli = hoursInMilli * 24;
        long elapsedDays = different / daysInMilli;
        different = different % daysInMilli;
        if (elapsedDays > 1) {
            String s = feeds.get("insert_dttm");
            Date d = null;
            SimpleDateFormat inputFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                d = inputFormat.parse(s);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            SimpleDateFormat outputFormat=
                    new SimpleDateFormat("MMMM dd");
            if (viewHolder.postedWhen != null) {
                viewHolder.postedWhen.setText(outputFormat.format(d));
            }
        } else {
            long elapsedHours = different / hoursInMilli;
            different = different % hoursInMilli;
            if (elapsedHours > 1) {
                if (viewHolder.postedWhen != null) {
                    viewHolder.postedWhen.setText(String.valueOf(elapsedHours) + " hours ago");
                }
            } else {
                long elapsedMinutes = different / minutesInMilli;
                different = different % minutesInMilli;
                if (elapsedMinutes > 1) {
                    if (viewHolder.postedWhen != null) {
                        viewHolder.postedWhen.setText(String.valueOf(elapsedMinutes) + " minutes ago");
                    }
                } else {
                    long elapsedSeconds = different / secondsInMilli;
                    if (elapsedSeconds > 1) {
                        if (viewHolder.postedWhen != null) {
                            viewHolder.postedWhen.setText(String.valueOf(elapsedSeconds) + " seconds ago");
                        }
                    }
                }
            }
        }
        viewHolder.postedWhen.append(",");
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    viewHolder.location.setTag(position);
    if (viewHolder.location != null) {
        viewHolder.location.setText(feeds.get("location"));
    }
    viewHolder.feed.setTag(position);
    if (viewHolder.feed != null) {
        viewHolder.feed.setText(feeds.get("feed"));
    }
    viewHolder.feedImage.setTag(position);
    final String photoPath1 = feeds.get("photo");
    if (photoPath1 != null && photoPath1.length() > 0 && !photoPath1.equals("null")) {
        //GetImage ui = new GetImage(photoPath1, viewHolder, 2);
        //ui.execute();
        Picasso.with(activity)
                .load(photoPath1)
                .into(viewHolder.feedImage);
    } else {
        viewHolder.feedImage.setVisibility(View.GONE);
    }

    return convertView;
}
private class GetImage extends AsyncTask<String, Void, Bitmap> {
    String imagePath;
    ViewHolderItem v;
    int iType;
    GetImage(String path, ViewHolderItem viewHolder, int type) {
        imagePath = path;
        v = viewHolder;
        iType = type;
    }
    @Override
    protected void onPostExecute(Bitmap b) {
        super.onPostExecute(b);
        if (iType == 1) {
            v.image.setImageBitmap(b);
        } else {
            v.feedImage.setImageBitmap(b);
        }
    }
    @Override
    protected Bitmap doInBackground(String... params) {
        Bitmap localBmp = null;
        try {
            localBmp = (Bitmap) ImageCache.getInstance().getLru().get(imagePath);
            if (localBmp == null) {
                InputStream in = new URL("http://myurl.com/" + imagePath + ".jpeg").openStream();
                localBmp = BitmapFactory.decodeStream(in);
                ImageCache.getInstance().getLru().put(imagePath, localBmp);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return localBmp;
    }
}
}

我没有发布XML文件,因为我认为这可能不是布局XML问题。

您可以在滚动ListView时暂停任何正在进行的后台工作。

您需要添加一个scrolllistener到您的ListView如下,

your_listview.setOnScrollListener(new PicassoScrollListener(context));

user resize()来减小图像的大小

Picasso.with(activity)
            .load(photoPath1)
            .resize(imagesize, imagesize)
            .into(viewHolder.feedImage);

你可以做一些改进:

  1. 使用ViewHolder模式。
  2. 实现一个回调/接口来通知你的适配器图像下载已经完成。
  3. 使用ProgressBar来显示图像下载进度,它将在ListView中充当图像的占位符,直到它们被下载。
  4. 如果可能,使用RecyclerView代替ListView