listview可见再加载图片

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

此时可以做一些优化:

 1             listView.getRefreshableView().setOnScrollListener(new AbsListView.OnScrollListener() {
 2                 @Override
 3                 public void onScrollStateChanged(AbsListView view, int scrollState) {
 4                     switch (scrollState) {
 5                         case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:   //点按屏幕,准备滚动
 6                             adapter02.setScrolling(true);
 7                             //        Log.i(MyConfig.TagMain,"1-scrolling...");
 8                             //设置ListView的状态
 9                             break;
10                         case AbsListView.OnScrollListener.SCROLL_STATE_FLING:   //滚动中
11                             adapter02.setScrolling(true);
12                             //        Log.i(MyConfig.TagMain,"2-scrolling...");
13                             //设置ListView的状态
14                             break;
15                         case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:   //滚动结束
16                             //获取第一个可见的item的position
17                             int first = listView.getRefreshableView().getFirstVisiblePosition();
18                             //获取最后一个可见的item的position;
19                             int last = listView.getRefreshableView().getLastVisiblePosition();
20                             //屏幕上可见的item总数
21                             int onScreenCount = listView.getRefreshableView().getChildCount();
22                             int total = first + last;
23                             Log.i(MyConfig.TagMain,"3-first="+first+",last="+last+",onScreenCount="+onScreenCount+",total="+total);
24                             //adapter.setScrolling(false);
25                             adapter02.setPositionRange(first,last);
26                             adapter02.setScrolling(false);
27 
28                             View child;
29                             int position;
30                             for (int i = 0 ; i < onScreenCount ; i++) {
31                                 position = first + i;
32                                 if(adapter02.isInPrevPositionRange(position)) {
33                                     Log.i(MyConfig.TagMain, "可见单元位置处在上次滚动可是范围内,无需重新加载图片:"+ position);
34                                     continue;
35                                 }
36                                 //获取可见item子项的视图容器对象
37                                 Log.i(MyConfig.TagMain, "now position:"+ position);
38                                 child = listView.getRefreshableView().getChildAt(i);
39                                 RoundImageView headIco = (RoundImageView) child.findViewById(R.id.iv_hint);
40                                 ImageView imageView = (ImageView) child.findViewById(R.id.iv);
41                                 Log.i(MyConfig.TagMain, "load image i:"+ position);
42                                 adapter02.loadImage(headIco,imageView,channelModels,position);
43                             }
44                             //设置可见listView的维护表
45                             break;
46                         default:
47                             break;
48                     }
49                 }
50 
51                 @Override
52                 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
53 
54                 }
55             });

adapter:

  1 package com.galaxy.adapter;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 import com.galaxy.activity.LoginActivity;
  7 import com.galaxy.activity_group.GroupPersonActivity;
  8 import com.galaxy.content.MyConfig;
  9 import com.galaxy.models.ChannelModel;
 10 import com.galaxy.models.User;
 11 import com.galaxy.net.GetRequestTask;
 12 import com.galaxy.net.MyBaseClient;
 13 import com.galaxy.picture.SetImageUtils;
 14 import com.galaxy.utils.RoundImageView;
 15 import com.galaxy.yim.R;
 16 
 17 import android.annotation.SuppressLint;
 18 import android.content.Context;
 19 import android.content.Intent;
 20 import android.graphics.drawable.Drawable;
 21 import android.util.Log;
 22 import android.view.LayoutInflater;
 23 import android.view.View;
 24 import android.view.ViewGroup;
 25 import android.widget.BaseAdapter;
 26 import android.widget.ImageView;
 27 import android.widget.TextView;
 28 import android.widget.Toast;
 29 
 30 public class ChannelListAdapter extends BaseAdapter{
 31     private Context context;
 32     private List<ChannelModel> mListData;
 33     //是否滚动中:
 34     private boolean isScrolling;
 35 
 36     private int mFirstPosition = 0;
 37     private int mLastPosition = 0;
 38     private int mPrevFirstPosition = 0;
 39     private int mPrevLastPosition = 0;
 40 
 41     /**
 42      * 记录当前已经出现过的item
 43      */
 44     private List<Integer> listPosition = new ArrayList<Integer>();
 45 
 46     /**
 47      * 记录当前已经点赞的列表
 48      */
 49     private List<String> listLikes = new ArrayList<>();
 50 
 51     private CallBackSetLikes callBack;
 52     /**
 53      * 定义点赞回调接口
 54      */
 55     public interface CallBackSetLikes {
 56         public void setLikes(int position);
 57     }
 58 
 59     public ChannelListAdapter(Context context, List<ChannelModel> mListData,CallBackSetLikes callBackSetLikes) {
 60         super();
 61         this.context = context;
 62         this.mListData = mListData;
 63         this.callBack = callBackSetLikes;
 64         //设置默认显示前两个item
 65         listPosition.add(0);
 66         listPosition.add(1);
 67     }
 68 
 69     public void setScrolling(boolean isScrolling) {
 70         this.isScrolling = isScrolling;
 71     }
 72 
 73     /**
 74      * 设置点赞标志
 75      * @param position
 76      */
 77     public void setListLikes(int position) {
 78         listLikes.add(mListData.get(position).getPicurl());
 79     }
 80 
 81     /**
 82      * 设置滚动后可见的起止项目序号
 83      *
 84      * @param first
 85      * @param last
 86      */
 87     public void setPositionRange(int first, int last) {
 88         // 保存上次滚动后的可见位置
 89         this.mPrevFirstPosition = this.mFirstPosition;
 90         this.mPrevLastPosition = this.mLastPosition;
 91         // 重置当前可见位置
 92         this.mFirstPosition = first;
 93         this.mLastPosition = last;
 94         Log.i(MyConfig.TagMain, "上次可见first: "+ mPrevFirstPosition +", 上次可见last: "+ mPrevLastPosition +", 当前可见first: "+ mFirstPosition +", 当前可见last: "+ mLastPosition);
 95     }
 96 
 97     /**
 98      * 可见单元位置对比是否处在在上次滚动可是范围内
 99      *
100      * @param position
101      * @return
102      */
103     public boolean isInPrevPositionRange(int position) {
104         if(!listPosition.contains(position)) {
105             listPosition.add(position);
106         }
107         // 初始化时直接返回 false
108         if (this.mPrevLastPosition == 0) return false;
109         // 检测当前 item 的位置是否在上次滚动范围内, 是则表示该 item 正处于屏幕可见状态中无需重新加载
110         return (position >= this.mPrevFirstPosition && position <= this.mPrevLastPosition) ? true : false;
111     }
112 
113     @Override
114     public int getCount() {
115         // TODO Auto-generated method stub
116         return mListData.size();
117     }
118 
119     @Override
120     public Object getItem(int position) {
121         // TODO Auto-generated method stub
122         return mListData.get(position);
123     }
124 
125     @Override
126     public long getItemId(int position) {
127         // TODO Auto-generated method stub
128         return position;
129     }
130 
131 
132     @SuppressLint("NewApi") @Override
133     public View getView(final int position, View convertView, ViewGroup parent) {
134         ViewHolder holder = null;
135         if (convertView == null) {
136             convertView = LayoutInflater.from(context).inflate(R.layout.item_listview_group_channel_list, null);
137             holder = new ViewHolder();
138             holder.id = position;
139             holder.iv_hint = (RoundImageView) convertView.findViewById(R.id.iv_hint);
140             holder.tv_username = (TextView) convertView.findViewById(R.id.tv_username);
141             holder.tv_sharecounts = (TextView) convertView.findViewById(R.id.tv_sharecounts);
142             holder.tv_date = (TextView) convertView.findViewById(R.id.tv_date);
143             holder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
144             holder.iv = (ImageView) convertView.findViewById(R.id.iv);
145             holder.tv_address = (TextView) convertView.findViewById(R.id.tv_address);
146             holder.tv_likes = (TextView) convertView.findViewById(R.id.tv_likes);
147             holder.tv_reply = (TextView) convertView.findViewById(R.id.tv_reply);
148             convertView.setTag(holder);
149         } else {
150             holder = (ViewHolder) convertView.getTag();
151         }
152         
153         if (mListData.size()>0) {
154             final ChannelModel model = mListData.get(position);
155             final String nickname = model.getNickname();
156             String forwarding = model.getForwarding();
157             String date = model.getTime();
158             String title = model.getTitle();
159             String address = model.getAddress();
160             String likes = model.getLikes();
161             String reply = model.getComments();
162 
163             holder.tv_username.setText(nickname);
164             holder.tv_sharecounts.setText(forwarding);
165             holder.tv_date.setText(date.substring(0,10));
166             holder.tv_title.setText(title);
167             holder.tv_address.setText(address);
168 
169             if(address == null || address.equals("") || address.equals("所在位置")) {
170                 holder.tv_address.setVisibility(View.GONE);
171             }else{
172                 holder.tv_address.setVisibility(View.VISIBLE);
173             }
174             holder.tv_likes.setText(likes);
175             holder.tv_reply.setText(reply);
176             //判断当前图片是否有,没有就设置为空
177             if(model.getPicurl().equals("")) {
178                 holder.iv.setVisibility(View.GONE);
179             }else {
180                 holder.iv.setVisibility(View.VISIBLE);
181             }
182 
183             if(listPosition.contains(position)) {
184                 this.loadImage(holder.iv_hint,holder.iv,mListData,position);
185             }else{
186                 //没曾经出现过的item就设置默认图片
187                 holder.iv_hint.setImageResource(R.drawable.icon_person);
188                 holder.iv.setImageResource(R.drawable.icon_no_photo);
189             }
190 
191             //判断男女
192             String sex = model.getSex();
193             if(sex.equals("女")) {
194                 Drawable drawable = context.getDrawable(R.drawable.icon_sex_woman);
195                 /// 这一步必须要做,否则不会显示.  
196                 drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());  
197                 holder.tv_username.setCompoundDrawables(null,null,drawable,null); 
198             }else if(sex.equals("男")){
199                 Drawable drawable = context.getDrawable(R.drawable.icon_sex_man);
200                 /// 这一步必须要做,否则不会显示.  
201                 drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());  
202                 holder.tv_username.setCompoundDrawables(null,null,drawable,null); 
203             }else{
204                 holder.tv_username.setCompoundDrawables(null,null,null,null);
205             }
206 
207             //判断是否已经点赞
208             final String mark = model.getMark();
209             if(mark.length()>2 ) {
210                 Log.i("main",mark+","+mark.length());
211                 listLikes.contains(model.getPicurl());
212                 Drawable drawable= context.getResources().getDrawable(R.drawable.icon_likes_pressed);
213                 /// 这一步必须要做,否则不会显示.
214                 drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
215                 //        Log.i("main","已点赞"+position);
216                 holder.tv_likes.setCompoundDrawables(drawable,null,null,null);
217             }else{
218                 Drawable drawable= context.getResources().getDrawable(R.drawable.icon_likes);
219                 /// 这一步必须要做,否则不会显示.
220                 drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
221                 //        Log.i("main","已点赞"+position);
222                 holder.tv_likes.setCompoundDrawables(drawable,null,null,null);
223             }
224 
225             holder.tv_likes.setTag(position);
226             holder.tv_likes.setOnClickListener(new View.OnClickListener() {
227                 @Override
228                 public void onClick(View v) {
229             //        Toast.makeText(context,"position="+position+",mark="+mark,Toast.LENGTH_SHORT).show();
230                     if((!listLikes.contains(model.getPicurl())) && mark.length()<3) {
231                         User user = MyConfig.getUser(context);
232                         if(user.getUsername().equals("")) {
233                             Toast.makeText(context,"请登录",Toast.LENGTH_SHORT).show();
234                             Intent intent = new Intent(context,LoginActivity.class);
235                             intent.putExtra(MyConfig.IntentPageTitle, "登录");
236                             context.startActivity(intent);
237                             return;
238                         }
239                         int id = Integer.valueOf(((TextView)v).getTag().toString());
240                         callBack.setLikes(id);
241                         Drawable drawable= context.getResources().getDrawable(R.drawable.icon_likes_pressed);
242                         /// 这一步必须要做,否则不会显示.
243                         drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
244                         //        Log.i("main","已点赞"+position);
245                         ((TextView)v).setCompoundDrawables(drawable,null,null,null);
246                         //标志图片已经更新
247                         listLikes.add(model.getPicurl());
248                         mListData.get(position).setLikes(Integer.valueOf(model.getLikes())+1+"");
249                         mListData.get(position).setMark(context.getString(R.string.group_likes));
250                         ((TextView)v).setText(Integer.valueOf(model.getLikes())+"");
251                     }else{
252                         Toast.makeText(context,context.getString(R.string.group_likes),Toast.LENGTH_SHORT).show();
253                     }
254                 }
255             });
256 
257             holder.iv_hint.setOnClickListener(new View.OnClickListener() {
258                 @Override
259                 public void onClick(View v) {
260                     User user = MyConfig.getUser(context);
261                     if(user.getUsername().equals("")) {
262                         Toast.makeText(context,"请登录",Toast.LENGTH_SHORT).show();
263                         Intent intent = new Intent(context,LoginActivity.class);
264                         intent.putExtra(MyConfig.IntentPageTitle, "登录");
265                         context.startActivity(intent);
266                         return;
267                     }
268                     Intent intent = new Intent(context, GroupPersonActivity.class);
269                     intent.putExtra(MyConfig.IntentPageTitle,nickname);
270                     intent.putExtra(MyConfig.IntentUrlPic,model.getPortrait());
271                     intent.putExtra("username",model.getUsername());    //点击的头像的username
272                     context.startActivity(intent);
273                 }
274             });
275         }
276         return convertView;
277     }
278 
279     public void loadImage(RoundImageView head_ico,ImageView pic,List<ChannelModel> mListData,int position) {
280         ChannelModel model = mListData.get(position);
281         String icoUrl = model.getPortrait();
282         String picUrl = model.getPicurl();
283         if(!icoUrl.contains("http")) {
284             icoUrl = MyConfig.serviceTest + icoUrl;
285         }
286         // 通过 tag 来防止图片错位
287         SetImageUtils.setImageWithTag(icoUrl,head_ico,context);
288         head_ico.setTag(icoUrl);
289 
290 //        if (head_ico.getTag() != null && head_ico.getTag().equals(icoUrl)) {
291 //            SetImageUtils.setImage(icoUrl,head_ico,context);
292 //        }
293 
294         String[] pics = picUrl.split("\|");
295         if(!pics[0].contains("http")) {
296             pics[0] = MyConfig.serviceTest + pics[0];
297         }
298         SetImageUtils.setImageWithTag(pics[0],pic,context);
299         // 通过 tag 来防止图片错位
300         pic.setTag(pics[0]);
301 //        if (pic.getTag() != null && pic.getTag().equals(pics[0])) {
302 //            SetImageUtils.setImage(pics[0],pic,context);
303 //            Log.i(MyConfig.TagMain,"loading..."+position+",pics[0]="+pics[0]);
304 //        }
305 
306     }
307 
308     private class ViewHolder{
309         int id;
310         RoundImageView iv_hint;
311         TextView tv_username;
312         TextView tv_sharecounts;
313         TextView tv_date;
314         TextView tv_title;
315         ImageView iv;
316         TextView tv_address;
317         TextView tv_likes;
318         TextView tv_reply;
319     }
320 
321 }

图片加载工具:

 1 /**
 2      * 调用display来加载图片,无闪烁
 3      * @param pic_url
 4      * @param imageView
 5      * @param context
 6      */
 7     public static void setImageWithTag(final String pic_url,final ImageView imageView,Context context) {
 8         if(pic_url != null) {
 9             String tag = (String) imageView.getTag();
10             if(tag == null) {
11                 tag = "";
12             }
13             if(pic_url.equals(imageView.getTag())) {
14                 return;
15             }
16         }
17         Log.i("main","loading pic:"+pic_url);
18         ImageLoader.getInstance().displayImage(pic_url, new ImageViewAware(imageView), MyApplication.commOptionsCache);
19     }
 1 /**
 2      *用于显示图片的选项,没过渡时间
 3      * 用于圈子社区,解决列表图片过多时,出现刷新闪烁的情况
 4      */
 5     public static DisplayImageOptions commOptionsCache  = new DisplayImageOptions.Builder()
 6             .showImageOnLoading(R.drawable.icon_no_photo)
 7             .showImageOnFail(R.drawable.icon_no_photo)
 8             .showImageForEmptyUri(R.drawable.icon_no_photo)//设置图片Uri为空或是错误的时候显示的图片
 9             .cacheInMemory(true)
10             .cacheOnDisk(true)
11             .bitmapConfig(Bitmap.Config.RGB_565)
12             .considerExifParams(true)
13             .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
14             .resetViewBeforeLoading(false)
15             .displayer(new FadeInBitmapDisplayer(0))
16             .build();
原文地址:https://www.cnblogs.com/chq3272991/p/5581563.html