我在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);
你可以做一些改进:
- 使用
ViewHolder
模式。 - 实现一个回调/接口来通知你的适配器图像下载已经完成。
- 使用
ProgressBar
来显示图像下载进度,它将在ListView中充当图像的占位符,直到它们被下载。 - 如果可能,使用
RecyclerView
代替ListView
。