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,相信很多人都很熟悉,因为确实太常见了,所以,做的用户体验更好,就成了我们的追求... ...
随机推荐
- Android Studio 初使用
Android Studio 更改Eclipse快捷键 Android Studio 更改编码 Android Studio 导包
- python学习笔记-socket
socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. sock ...
- iOS开发之AFNetworking 3.0.4使用-OC
GET请求 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; [manager GET:URL parameters: ...
- XE3随笔3:访问
测试数据提前加入 Memo1 中: { "name": "张三", /* 注释 */ "age": 33, "sex": ...
- php get_magic_quotes_gpc()函数
magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post.get.cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊 ...
- Navicat for Oracle 连接oracle 配置
oci.dll 替换为对应oracle版本的oci.dll
- 20145318赵一Java课程总结
20145318赵一Java课程总结 每周读书笔记链接汇总 问卷调查 第1周读书笔记 第2周读书笔记 第3周读书笔记 第4周读书笔记 第5周读书笔记 第6周读书笔记 第7周读书笔记 第8周读书笔记 第 ...
- 二维码识别 android app
TextView类用于展示文本信息 ImageView展示 id:button1(用来显示“扫描二维码”) 布局:fill_parent使布满屏幕(高级版本用match_parent) wrap_co ...
- C# 基础(2)
打开一个解决方案,以.sin后缀名,.csproj是项目文件的后缀名. Console.WriteLine("这是我的第二个项目!");你想显示的内容 Console.ReadKe ...
- Android 6.0 新功能及主要 API 变更
运行时权限 这个版本中引入了新的权限模型,现在用户可以在运行时直接管理应用程序的权限.这个模型基于用户对权限控制的更多可见性,同时为应用程序的开发者提供更流畅的应用安装和自动升级.用户可以为已安装的每 ...