您的位置:首页 > 理论基础 > 计算机网络

Android ListView异步加载网络图片出现位置错乱闪烁及优化ListView的加载

2017-09-19 10:42 671 查看
每次联网会从服务器端返回50条数据,每条数据包含一张jpg图片,一个String字符串,一个double类型数据。使用之前优化的listview加载图片会闪烁、错乱。后来查找资料发现需要给图片设置tag,然后加载的时候进行对比,tag相等再加载显示。同时需要给图片设置缓存,从网络加载的图片存入缓存中,第二次使用时就不再从网络端获取,而是从缓存中读取。代码如下:

解析从服务器端获取的50条数据:

JSONArray peopleArray;
List<String> scoreList = new ArrayList<>();
List<String> chineseNameList = new ArrayList<>();
List<String> englishNameList = new ArrayList<>();
List<String> peopleFaceList = new ArrayList<>();
private void parseCelebrityJsonResult(String response) {
JSONObject jsonObject = JSON.parseObject(response);
peopleArray = jsonObject.getJSONArray("people");
Log.e("peopleArray",peopleArray.toJSONString());
Double score;
String peopleId;
String chineseName;
String englishName;
JSONObject peopleJsonObj;
String peopleImgUrl;
String scoreStr;
if(peopleArray != null && peopleArray.size() > 0) {
for (int i = 0;i < peopleArray.size();i++){
peopleJsonObj = peopleArray.getJSONObject(i);

score = peopleJsonObj.getDouble("score");
scoreStr = doubleToPercent(score);
Log.e("相似度:",scoreStr);
scoreList.add(scoreStr);

chineseName = peopleJsonObj.getString("chinese_name");
Log.e("相似名字:",chineseName + i);
chineseNameList.add(chineseName);

englishName = peopleJsonObj.getString("english_name");
englishNameList.add(englishName);

peopleId = peopleJsonObj.getString("id");
peopleImgUrl = "http://facde.cn/static/img/celebrity/"+peopleId+".jpg";
Log.e("相似图片:",peopleImgUrl);
peopleFaceList.add(peopleImgUrl);
}
}

initAdapter();
}


private void initAdapter() {
if(celebAdapter == null) {
celebAdapter = new CelebrityAdapter(CelebrityDetectActivity.this);
}
celebAdapter.notifyDataSetChanged();
lvResult.setAdapter(celebAdapter);
}
public class CelebrityAdapter extends BaseAdapter{
Context mContext;
LayoutInflater mInflater;
ViewHolder viewHolder;
String name;
LruCache<String,Bitmap> lruCache;

public CelebrityAdapter(Context context){
mContext = context;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//获取应用程序最大可用内存
int maxMemory = (int) Runtime.getRuntime().maxMemory();
//初始化LruCache并为其分配最大的缓存值
lruCache = new LruCache<String, Bitmap>(maxMemory/4){
@Override
protected int sizeOf(String key, Bitmap value) {
//返回存进缓存的bitmap的大小
return value.getByteCount();
}
};
}

@Override
public int getCount() {
return peopleArray.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

if(convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_listview_celebrity_detect,null);
viewHolder.ivCelebrityFace = (ImageView) convertView.findViewById(R.id.iv_celebrity_face);

viewHolder.tvCelebrityName = (TextView) convertView.findViewById(R.id.tv_celebrity_name);
viewHolder.tvCelebrityScore = (TextView) convertView.findViewById(R.id.tv_celebrity_score);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}

progressDialog.dismiss();

viewHolder.ivCelebrityFace.setTag(peopleFaceList.get(position));
if(chineseNameList.get(position).equals("") || chineseNameList.get(position) == null) {
name = englishNameList.get(position);
} else {
name = chineseNameList.get(position);
}

viewHolder.tvCelebrityName.setText("相似人:" + name);
viewHolder.tvCelebrityScore.setText("相似度:" + scoreList.get(position));
new ImageLoaderByLrucache(position,peopleFaceList,peopleFaceList.get(position),viewHolder.ivCelebrityFace,lruCache).imageloadAsyncTask();

return convertView;
}

}
public class ViewHolder{
ImageView ivCelebrityFace;
TextView tvCelebrityName,tvCelebrityScore;
}
/**
* 从缓存中加载图片
* Created by D.bj on 2017/9/6.
*/

public class ImageLoaderByLrucache{
int position;
ImageView imageView;
LruCache<String,Bitmap> lruCache;
String url;
List<String> urlList;

public ImageLoaderByLrucache(){}

public ImageLoaderByLrucache(int position,List<String> urlList,String url,ImageView imageView,LruCache<String,Bitmap> lruCache){
this.position = position;
this.urlList = urlList;
this.url = url;
this.imageView = imageView;
this.lruCache = lruCache;
}

//通过URL从缓存中获取对应的bitmap
private Bitmap getBitmapFromLruCache(String url){
return lruCache.get(url);
}

//将bitmap设置进缓存中
private void setBitmapIntoLruCache(String url,Bitmap bitmap){
Bitmap bitmap1 = getBitmapFromLruCache(url);
if(bitmap1 == null) {
lruCache.put(url,bitmap);
}
}

public void imageloadAsyncTask(){
//加载图片之前先判断缓存中是否有该图片,如果有直接使用缓存中的,如果没有通过网络加载
Bitmap bitmap = getBitmapFromLruCache(url);
if(bitmap != null) {
if(imageView.getTag().equals(url)) {
imageView.setImageBitmap(bitmap);
}
} else {
new LoadBitmapFromUrl(position,imageView).execute(urlList.get(position));
}
}

public class LoadBitmapFromUrl extends AsyncTask<String,Void,Bitmap> {
int position;
ImageView imageView;

public LoadBitmapFromUrl(){}

public LoadBitmapFromUrl(int position,ImageView imageView){
this.position = position;
this.imageView = imageView;
}

@Override
protected Bitmap doInBackground(String... params) {
Log.e("params-0:",params[0]);
return loadImageFromNetwork(params[0]);
}

@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if(imageView.getTag().equals(urlList.get(position))) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageBitmap(null);
}
}
}

private Bitmap loadImageFromNetwork(String url) {
Bitmap bitmap = simpleNetworkImage(url);
if(bitmap == null) {
Log.i("","");
}
return bitmap;
}

private Bitmap simpleNetworkImage(String url) {
Bitmap imgBitmap = null;
try {
URL picUrl = new URL(url);
imgBitmap = BitmapFactory.decodeStream(picUrl.openStream());
//判断缓存中是否存在该数据
if(getBitmapFromLruCache(url) == null) {
//将通过网络加载的图片放入缓存中
setBitmapIntoLruCache(url,imgBitmap);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return imgBitmap;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐