listview可见再加载图片
对于,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可见再加载图片的更多相关文章
- 网页图片很多时,加载完后再加载图片(defer:延迟加载)
图片影响页面加载速度,可以先加载完页面,再去加载图片. defer:告诉浏览器,这里面的js代码不影响网页脚本解析,可以解析完html脚本再执行这段js代码(个人理解). 网页代码:<img s ...
- Android之ListView和GridVIew加载图片
清除缓存:ImageLoader 对象 . clearCache(); 使用: ImageLoader loader = new ImageLoader(ApplicationContext cont ...
- Listview 异步加载图片之优化篇(有图有码有解释)
在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...
- Listview异步加载图片之优化篇
在APP应用中,listview的异步加载图片方式能够带来很好的用户体验,同时也是考量程序性能的一个重要指标.关于listview的异步加载,网上其实很多示例了,中心思想都差不多,不过很多版本或是有b ...
- android listview 异步加载图片并防止错位
网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ...
- Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...
- android listview 加载图片错乱(错位)
写道 今天晚上一个朋友介绍我看了一篇文章,也是解决android中listview在加载图片错位的问题,看了之后,感觉写的很好,自己也遇到这个问题,但是又不知道从何下手,看到这篇文章后,我的问题 ...
- 解决ListView滑动时卡的问题,实现异步加载图片解决
ListView是最为常见的空间之一,现在的应用的呈现形式大多数都需要用到ListView来呈现,以列表的方式最直观最便于操作. 那么在使用的过程中大家一定使用adapter适配器来匹配这个ListV ...
- android ListView异步加载图片(双缓存)
首先声明,参考博客地址:http://www.iteye.com/topic/685986 对于ListView,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...
随机推荐
- SpringMVC在传递date型数据时的配置
查阅了好多资料, 最后才发现原来只是添加一个方法就能解决的问题, 但是看了半天又没看明白, 只是知道这么写就能成功, 先记下来, 以后再研究吧, 在配置好springMVC的时候, 可以在前台的for ...
- 让IE8支持HTML5及canvas功能!chart.js图表绘制工具库IE8上兼容方案
第一步,我们加上对html5的支持. <!--[if IE]> <script src="/public/html5.js" type="text/ja ...
- [C++]项目中的代码注释规范(整理)
原文:http://blog.csdn.net/pleasecallmewhy/article/details/8658795 1 源文件头部注释 列出:版权.作者.编写日期和描述. 每行不要超过80 ...
- Linux中vi、vim命令大全
一.一般模式:删除.复制与粘贴类命令 x,X x为向后删除一个字符,X为先前删除一个字符 nx(n代表数字) 向后删除n个字符 dd 删除当前行 D 删除当前行所有字符,试成为空行 ndd(n代表数字 ...
- mvc-servlet---servletContext与servletConfig2
在编写servlet过程中,需要用到 ServletConfig.ServletContext对象,对这两种对象的介绍如下: ServletContext对象:servlet容器在启动时会加载web应 ...
- SQL Server 内存数据库原理解析
前言 关系型数据库发展至今,细节上以做足文章,在寻求自身突破发展的过程中,内存与分布式数据库是当下最流行的主题,这与性能及扩展性在大数据时代的需求交相辉映.SQL Server作为传统的数据库也在最新 ...
- 升级adt插件后,eclipse突然出现Unable to build: the file dx.jar was not loaded from the SDK folder 错误
旧版的SDK管理器里面最高只能安装Android 3.2 API,需要更新SDK管理器版本后才能安装Android 4.0.Android 4.1,方法如下: http://blog.csdn.net ...
- 【基础知识】.Net基础加强10天
一. 复习 1. 委托是类型,还是一种引用类型. 2. 使用委托的时候必须new一个委托对象.即便看到代码中没有new委托对象,编译器也会在编译的时候帮我们new赋值给委托的方法,其实是存储在委托对象 ...
- 基于OWIN WebAPI 使用OAUTH2授权服务【授权码模式(Authorization Code)】
之前已经简单实现了OAUTH2的授权码模式(Authorization Code),但是基于JAVA的,今天花了点时间调试了OWIN的实现,基本就把基于OWIN的OAUHT2的四种模式实现完了.官方推 ...
- Designing a Secure REST (Web) API without OAuth
原文:http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/ Situation Y ...