对于,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();