对于,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. java核心知识点学习----多线程并发之线程同步

    1.什么是线程同步? 多线程编程是很有趣的事情,它很容易出现"错误情况",这种情况不是由编码造成的,它是由系统的线程调度造成的,当使用多个线程来访问同一个数据时,很容易出现&quo ...

  2. 遇到的check the manual that corresponds to your MySQL server version for the right syntax错误

    遇到的check the manual that corresponds to your MySQL server version for the right syntax错误. 结果发现是SQL关键 ...

  3. 实现的一个ajax请求组件 有加载效果

    var zhanglei_Ajax = function(url,data,fn){ var str = '<div class="mask" style="pos ...

  4. Python基础学习笔记FromImooc.com

    1.list L = ['a','a','a','a','a','a3'] L[0] = a L[-1] = a3   添加新元素 L.append('paul') L.insert(-1,'Paul ...

  5. [转]linux14.04下caffe的安装步骤

     linux14.04下caffe的安装步骤   原文地址:http://blog.csdn.net/xiaoyang19910623/article/details/52997481?locatio ...

  6. unreal3之FName及潜在bug

    FName是unreal3里对字符串高效处理的一种机制 基本原理就是把字符串hash存起来,然后每个字符串就只需要用一个数组索引值来表示了 FName的属性: NAME_INDEX Index; IN ...

  7. 分布式日志2 用redis的队列写日志

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  8. servers无法输入server name

    Here is the workaround that worked for me: Close Eclipse In {workspace-directory}/.metadata/.plugins ...

  9. OpenWRT连接OPENVPN的教程

    这是相当基本没有任何web界面,只是几个命令如何运行OpenWRT的 OpenVPN的例子. OpenWRT的设置更复杂,所以这个教程仅供爱好者和经验的用户使用参考. 本教程假定您有OpenWRT的安 ...

  10. Windows 8.1 应用再出发 - 几种新增控件(2)

    本篇我们接着来介绍Windows 8.1 的新增控件,分别是:Flyout.MenuFlyout.SettingsFlyout.Hub 和 Hyperlink. 1. Flyout Flyout被称为 ...