对于,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. Maven 自动部署

    自动部署到Tomcat Maven 3.2.5 JDK 1.7 Tomcat 7 首先在Tomcat里配置deploy的用户(tomcat根目录/conf/tomcat-users.xml): < ...

  2. RHEL 集群(RHCS)配置小记 -- 文档记录

    1.RHEL 6 集群配置官方管理手册 https://access.redhat.com/site/documentation/zh-CN/Red_Hat_Enterprise_Linux/6/pd ...

  3. 让阿里云支持ipv6(其他多数VPS通用)

    https://www.tunnelbroker.net/tunnel_detail.php?tid=322922

  4. 转-C#让枚举返回字符串

    下面的手段是使用给枚举项打标签的方式,来返回字符串 下面分别定义一个属性类,和一个枚举帮助类 [AttributeUsage(AttributeTargets.Field,AllowMultiple  ...

  5. css3的学习笔记1

    一.   边框 1.  border-color border-color是设置边框的颜色.包括border-top-color,border-left-color,border-right-colo ...

  6. HDU 1165 Eddy's research II (找规律)

    题意:给定一个表达式,然后让你求表达式的值. 析:多写几个就会发现规律. 代码如下: #pragma comment(linker, "/STACK:1024000000,102400000 ...

  7. JavaWeb学习总结(三)——Tomcat服务器学习和使用(二)

    一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下:

  8. poj 3259 Wormholes 判断负权值回路

    Wormholes Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u   Java ...

  9. 分享MYSQL中的各种高可用技术(源自姜承尧大牛)

    分享MYSQL中的各种高可用技术(源自姜承尧大牛) 图片和资料来源于MYSQL大牛姜承尧老师(MYSQL技术内幕作者) 姜承尧: 网易杭州研究院 技术经理 主导INNOSQL的开发 mysql高可用各 ...

  10. Android 5.x特性概览一

    2014年,Google 携 Android 5.X 重装回归.迄今为止已有已有两年有余,全新设计的 UI风格和更加强悍的性能,再一次奠定了Android 的霸主地位.本文将就 UI 方面 Googl ...