对于,listView如果同时含有大量文字和图片,那么对于用户,如果不需要滑动到后面,那么此时去加载网络图片,显然是耗费流量的。

此时可以做一些优化:

             listView.getRefreshableView().setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: //点按屏幕,准备滚动
adapter02.setScrolling(true);
// Log.i(MyConfig.TagMain,"1-scrolling...");
//设置ListView的状态
break;
case AbsListView.OnScrollListener.SCROLL_STATE_FLING: //滚动中
adapter02.setScrolling(true);
// Log.i(MyConfig.TagMain,"2-scrolling...");
//设置ListView的状态
break;
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: //滚动结束
//获取第一个可见的item的position
int first = listView.getRefreshableView().getFirstVisiblePosition();
//获取最后一个可见的item的position;
int last = listView.getRefreshableView().getLastVisiblePosition();
//屏幕上可见的item总数
int onScreenCount = listView.getRefreshableView().getChildCount();
int total = first + last;
Log.i(MyConfig.TagMain,"3-first="+first+",last="+last+",onScreenCount="+onScreenCount+",total="+total);
//adapter.setScrolling(false);
adapter02.setPositionRange(first,last);
adapter02.setScrolling(false); View child;
int position;
for (int i = 0 ; i < onScreenCount ; i++) {
position = first + i;
if(adapter02.isInPrevPositionRange(position)) {
Log.i(MyConfig.TagMain, "可见单元位置处在上次滚动可是范围内,无需重新加载图片:"+ position);
continue;
}
//获取可见item子项的视图容器对象
Log.i(MyConfig.TagMain, "now position:"+ position);
child = listView.getRefreshableView().getChildAt(i);
RoundImageView headIco = (RoundImageView) child.findViewById(R.id.iv_hint);
ImageView imageView = (ImageView) child.findViewById(R.id.iv);
Log.i(MyConfig.TagMain, "load image i:"+ position);
adapter02.loadImage(headIco,imageView,channelModels,position);
}
//设置可见listView的维护表
break;
default:
break;
}
} @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { }
});

adapter:

 package com.galaxy.adapter;

 import java.util.ArrayList;
import java.util.List; import com.galaxy.activity.LoginActivity;
import com.galaxy.activity_group.GroupPersonActivity;
import com.galaxy.content.MyConfig;
import com.galaxy.models.ChannelModel;
import com.galaxy.models.User;
import com.galaxy.net.GetRequestTask;
import com.galaxy.net.MyBaseClient;
import com.galaxy.picture.SetImageUtils;
import com.galaxy.utils.RoundImageView;
import com.galaxy.yim.R; import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; public class ChannelListAdapter extends BaseAdapter{
private Context context;
private List<ChannelModel> mListData;
//是否滚动中:
private boolean isScrolling; private int mFirstPosition = 0;
private int mLastPosition = 0;
private int mPrevFirstPosition = 0;
private int mPrevLastPosition = 0; /**
* 记录当前已经出现过的item
*/
private List<Integer> listPosition = new ArrayList<Integer>(); /**
* 记录当前已经点赞的列表
*/
private List<String> listLikes = new ArrayList<>(); private CallBackSetLikes callBack;
/**
* 定义点赞回调接口
*/
public interface CallBackSetLikes {
public void setLikes(int position);
} public ChannelListAdapter(Context context, List<ChannelModel> mListData,CallBackSetLikes callBackSetLikes) {
super();
this.context = context;
this.mListData = mListData;
this.callBack = callBackSetLikes;
//设置默认显示前两个item
listPosition.add(0);
listPosition.add(1);
} public void setScrolling(boolean isScrolling) {
this.isScrolling = isScrolling;
} /**
* 设置点赞标志
* @param position
*/
public void setListLikes(int position) {
listLikes.add(mListData.get(position).getPicurl());
} /**
* 设置滚动后可见的起止项目序号
*
* @param first
* @param last
*/
public void setPositionRange(int first, int last) {
// 保存上次滚动后的可见位置
this.mPrevFirstPosition = this.mFirstPosition;
this.mPrevLastPosition = this.mLastPosition;
// 重置当前可见位置
this.mFirstPosition = first;
this.mLastPosition = last;
Log.i(MyConfig.TagMain, "上次可见first: "+ mPrevFirstPosition +", 上次可见last: "+ mPrevLastPosition +", 当前可见first: "+ mFirstPosition +", 当前可见last: "+ mLastPosition);
} /**
* 可见单元位置对比是否处在在上次滚动可是范围内
*
* @param position
* @return
*/
public boolean isInPrevPositionRange(int position) {
if(!listPosition.contains(position)) {
listPosition.add(position);
}
// 初始化时直接返回 false
if (this.mPrevLastPosition == 0) return false;
// 检测当前 item 的位置是否在上次滚动范围内, 是则表示该 item 正处于屏幕可见状态中无需重新加载
return (position >= this.mPrevFirstPosition && position <= this.mPrevLastPosition) ? true : false;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return mListData.size();
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mListData.get(position);
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} @SuppressLint("NewApi") @Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.item_listview_group_channel_list, null);
holder = new ViewHolder();
holder.id = position;
holder.iv_hint = (RoundImageView) convertView.findViewById(R.id.iv_hint);
holder.tv_username = (TextView) convertView.findViewById(R.id.tv_username);
holder.tv_sharecounts = (TextView) convertView.findViewById(R.id.tv_sharecounts);
holder.tv_date = (TextView) convertView.findViewById(R.id.tv_date);
holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
holder.iv = (ImageView) convertView.findViewById(R.id.iv);
holder.tv_address = (TextView) convertView.findViewById(R.id.tv_address);
holder.tv_likes = (TextView) convertView.findViewById(R.id.tv_likes);
holder.tv_reply = (TextView) convertView.findViewById(R.id.tv_reply);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
} if (mListData.size()>0) {
final ChannelModel model = mListData.get(position);
final String nickname = model.getNickname();
String forwarding = model.getForwarding();
String date = model.getTime();
String title = model.getTitle();
String address = model.getAddress();
String likes = model.getLikes();
String reply = model.getComments(); holder.tv_username.setText(nickname);
holder.tv_sharecounts.setText(forwarding);
holder.tv_date.setText(date.substring(0,10));
holder.tv_title.setText(title);
holder.tv_address.setText(address); if(address == null || address.equals("") || address.equals("所在位置")) {
holder.tv_address.setVisibility(View.GONE);
}else{
holder.tv_address.setVisibility(View.VISIBLE);
}
holder.tv_likes.setText(likes);
holder.tv_reply.setText(reply);
//判断当前图片是否有,没有就设置为空
if(model.getPicurl().equals("")) {
holder.iv.setVisibility(View.GONE);
}else {
holder.iv.setVisibility(View.VISIBLE);
} if(listPosition.contains(position)) {
this.loadImage(holder.iv_hint,holder.iv,mListData,position);
}else{
//没曾经出现过的item就设置默认图片
holder.iv_hint.setImageResource(R.drawable.icon_person);
holder.iv.setImageResource(R.drawable.icon_no_photo);
} //判断男女
String sex = model.getSex();
if(sex.equals("女")) {
Drawable drawable = context.getDrawable(R.drawable.icon_sex_woman);
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
holder.tv_username.setCompoundDrawables(null,null,drawable,null);
}else if(sex.equals("男")){
Drawable drawable = context.getDrawable(R.drawable.icon_sex_man);
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
holder.tv_username.setCompoundDrawables(null,null,drawable,null);
}else{
holder.tv_username.setCompoundDrawables(null,null,null,null);
} //判断是否已经点赞
final String mark = model.getMark();
if(mark.length()>2 ) {
Log.i("main",mark+","+mark.length());
listLikes.contains(model.getPicurl());
Drawable drawable= context.getResources().getDrawable(R.drawable.icon_likes_pressed);
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
// Log.i("main","已点赞"+position);
holder.tv_likes.setCompoundDrawables(drawable,null,null,null);
}else{
Drawable drawable= context.getResources().getDrawable(R.drawable.icon_likes);
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
// Log.i("main","已点赞"+position);
holder.tv_likes.setCompoundDrawables(drawable,null,null,null);
} holder.tv_likes.setTag(position);
holder.tv_likes.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Toast.makeText(context,"position="+position+",mark="+mark,Toast.LENGTH_SHORT).show();
if((!listLikes.contains(model.getPicurl())) && mark.length()<3) {
User user = MyConfig.getUser(context);
if(user.getUsername().equals("")) {
Toast.makeText(context,"请登录",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context,LoginActivity.class);
intent.putExtra(MyConfig.IntentPageTitle, "登录");
context.startActivity(intent);
return;
}
int id = Integer.valueOf(((TextView)v).getTag().toString());
callBack.setLikes(id);
Drawable drawable= context.getResources().getDrawable(R.drawable.icon_likes_pressed);
/// 这一步必须要做,否则不会显示.
drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
// Log.i("main","已点赞"+position);
((TextView)v).setCompoundDrawables(drawable,null,null,null);
//标志图片已经更新
listLikes.add(model.getPicurl());
mListData.get(position).setLikes(Integer.valueOf(model.getLikes())+1+"");
mListData.get(position).setMark(context.getString(R.string.group_likes));
((TextView)v).setText(Integer.valueOf(model.getLikes())+"");
}else{
Toast.makeText(context,context.getString(R.string.group_likes),Toast.LENGTH_SHORT).show();
}
}
}); holder.iv_hint.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
User user = MyConfig.getUser(context);
if(user.getUsername().equals("")) {
Toast.makeText(context,"请登录",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context,LoginActivity.class);
intent.putExtra(MyConfig.IntentPageTitle, "登录");
context.startActivity(intent);
return;
}
Intent intent = new Intent(context, GroupPersonActivity.class);
intent.putExtra(MyConfig.IntentPageTitle,nickname);
intent.putExtra(MyConfig.IntentUrlPic,model.getPortrait());
intent.putExtra("username",model.getUsername()); //点击的头像的username
context.startActivity(intent);
}
});
}
return convertView;
} public void loadImage(RoundImageView head_ico,ImageView pic,List<ChannelModel> mListData,int position) {
ChannelModel model = mListData.get(position);
String icoUrl = model.getPortrait();
String picUrl = model.getPicurl();
if(!icoUrl.contains("http")) {
icoUrl = MyConfig.serviceTest + icoUrl;
}
// 通过 tag 来防止图片错位
SetImageUtils.setImageWithTag(icoUrl,head_ico,context);
head_ico.setTag(icoUrl); // if (head_ico.getTag() != null && head_ico.getTag().equals(icoUrl)) {
// SetImageUtils.setImage(icoUrl,head_ico,context);
// } String[] pics = picUrl.split("\\|");
if(!pics[0].contains("http")) {
pics[0] = MyConfig.serviceTest + pics[0];
}
SetImageUtils.setImageWithTag(pics[0],pic,context);
// 通过 tag 来防止图片错位
pic.setTag(pics[0]);
// if (pic.getTag() != null && pic.getTag().equals(pics[0])) {
// SetImageUtils.setImage(pics[0],pic,context);
// Log.i(MyConfig.TagMain,"loading..."+position+",pics[0]="+pics[0]);
// } } private class ViewHolder{
int id;
RoundImageView iv_hint;
TextView tv_username;
TextView tv_sharecounts;
TextView tv_date;
TextView tv_title;
ImageView iv;
TextView tv_address;
TextView tv_likes;
TextView tv_reply;
} }

图片加载工具:

 /**
* 调用display来加载图片,无闪烁
* @param pic_url
* @param imageView
* @param context
*/
public static void setImageWithTag(final String pic_url,final ImageView imageView,Context context) {
if(pic_url != null) {
String tag = (String) imageView.getTag();
if(tag == null) {
tag = "";
}
if(pic_url.equals(imageView.getTag())) {
return;
}
}
Log.i("main","loading pic:"+pic_url);
ImageLoader.getInstance().displayImage(pic_url, new ImageViewAware(imageView), MyApplication.commOptionsCache);
}
 /**
*用于显示图片的选项,没过渡时间
* 用于圈子社区,解决列表图片过多时,出现刷新闪烁的情况
*/
public static DisplayImageOptions commOptionsCache = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.icon_no_photo)
.showImageOnFail(R.drawable.icon_no_photo)
.showImageForEmptyUri(R.drawable.icon_no_photo)//设置图片Uri为空或是错误的时候显示的图片
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.considerExifParams(true)
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
.resetViewBeforeLoading(false)
.displayer(new FadeInBitmapDisplayer(0))
.build();

listview可见再加载图片的更多相关文章

  1. 网页图片很多时,加载完后再加载图片(defer:延迟加载)

    图片影响页面加载速度,可以先加载完页面,再去加载图片. defer:告诉浏览器,这里面的js代码不影响网页脚本解析,可以解析完html脚本再执行这段js代码(个人理解). 网页代码:<img s ...

  2. Android之ListView和GridVIew加载图片

    清除缓存:ImageLoader 对象 . clearCache(); 使用: ImageLoader loader = new ImageLoader(ApplicationContext cont ...

  3. Listview 异步加载图片之优化篇(有图有码有解释)

    在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...

  4. Listview异步加载图片之优化篇

    在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...

  5. android listview 异步加载图片并防止错位

    网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...

  6. Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案

    我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...

  7. android listview 加载图片错乱(错位)

       写道 今天晚上一个朋友介绍我看了一篇文章,也是解决android中listview在加载图片错位的问题,看了之后,感觉写的很好,自己也遇到这个问题,但是又不知道从何下手,看到这篇文章后,我的问题 ...

  8. 解决ListView滑动时卡的问题,实现异步加载图片解决

    ListView是最为常见的空间之一,现在的应用的呈现形式大多数都需要用到ListView来呈现,以列表的方式最直观最便于操作. 那么在使用的过程中大家一定使用adapter适配器来匹配这个ListV ...

  9. android ListView异步加载图片(双缓存)

    首先声明,参考博客地址:http://www.iteye.com/topic/685986 对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...

随机推荐

  1. fragment 碎片整理

    activity_m1.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xm ...

  2. SQL Server 判定时间是否在某个时间区间内

    * FROM sys.objects WHERE name=N'uF_IsRange_Date' AND [type]='FN') DROP FUNCTION uF_IsRange_Date GO S ...

  3. 专题:mdadm Raid & LVM

    >FOR FREEDOM!< {A} Introduction Here's a short description of what is supported in the Linux R ...

  4. 【.net】关于RegexOptions中的各个枚举值的含义

      Member name Description   Compiled Specifies that the regular expression is compiled to an assembl ...

  5. java读取属性文件propertie中文乱码问题

    在属性文件中使用Unicode编码中文 propertie文件默认编辑就是Unicode编码

  6. Jungle Roads

    Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid ...

  7. tomee.xml

    部署 <?xml version="1.0" encoding="UTF-8"?> <tomee> <!-- see http:/ ...

  8. PHP如何连接Access数据库

    PHP代码: <?php $connstr="DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" .realpath(" ...

  9. Linux下使用RecordMyDesktop进行屏幕录像

    近期我们在评估给用户提供视频教程的可能性,以此来展示某些用视频才能更好表达的教程.在挖掘这个问题的时候,我们发现极丰富的可用于屏幕录像的工具.这些程序大体上特性的区别有:视频质量,性能,兼容性.这在此 ...

  10. kafka go producer 启动基本配置

    1.官网上下载kafka安装包:http://kafka.apache.org/downloads.html 2.执行命令运行zookeeper 实例(单点): bin/zookeeper-serve ...