ListView图片优化(三)---练习

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.myasynctask.MainActivity" >

    <ListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</RelativeLayout>
每个条目的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="4dp" >

    <ImageView
        android:id="@+id/iv_imageview"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="26.45"
        android:gravity="center"
        android:orientation="vertical"
        android:paddingLeft="4dp" >

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="title" />

        <TextView
            android:id="@+id/tv_content"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="content" />
    </LinearLayout>

</LinearLayout>
NewsBean

package com.example.asynctask;

public class NewsBean {

	public String title;
	public String content;
	public String imageViewUrl;
	public NewsBean(String title, String content, String imageViewUrl) {
		super();
		this.title = title;
		this.content = content;
		this.imageViewUrl = imageViewUrl;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getImageViewUrl() {
		return imageViewUrl;
	}
	public void setImageViewUrl(String imageViewUrl) {
		this.imageViewUrl = imageViewUrl;
	}
	public NewsBean() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	
}

MainActivity

package com.example.asynctask;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;

public class MainActivity extends Activity {

	//获取listview控件
	private ListView listView;
	//慕课网的Json字符串
	private String jsonUrl = "http://www.imooc.com/api/teacher?type=4&num=30";
	//加载Json字符串到本地,并且解析为本地对象数组
	private List<NewsBean> newBeanlist;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//初始化listview控件
		listView = (ListView) findViewById(R.id.listview);
		//开启异步任务,传递慕课网jsonUrl进行网络异步加载任务
		new MyAsyncTask().execute(jsonUrl);
	}

	/**
	 * 创建异步任务,
	 * 参数:慕课网的jsonHttp地址
	 * Void没有进度显示为Void
	 * 返回本地对象集合
	 *
	 */
	class MyAsyncTask extends AsyncTask<String, Void, List<NewsBean>> {

		@Override
		protected List<NewsBean> doInBackground(String... params) {
			//构建一个方法,进行网络json字符串获取,并且解析为本地对象集合
			return getJsonData(jsonUrl);
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(List<NewsBean> result) {
			super.onPostExecute(result);
			//解析完毕后,进行适配器的数据设置填充
			JsonAdapter adapter = new JsonAdapter(MainActivity.this, newBeanlist);
			listView.setAdapter(adapter);
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			
		}

	}

	/**
	 * //构建一个方法,进行网络json字符串获取,并且解析为本地对象集合
	 * @param jsonUrl
	 * @return
	 */
	public List<NewsBean> getJsonData(String jsonUrl) {
		try {
			//创建url http地址
			URL httpUrl = new URL(jsonUrl);
			//打开http 链接
			HttpURLConnection connection = (HttpURLConnection) httpUrl
					.openConnection();
			//设置参数  请求为get请求
			connection.setReadTimeout(5000);
			connection.setRequestMethod("GET");

			//connection.getInputStream()得到字节输入流,InputStreamReader从字节到字符的桥梁,外加包装字符流
			BufferedReader bufferedReader = new BufferedReader(
					new InputStreamReader(connection.getInputStream()));
			//创建字符串容器
			StringBuffer sb = new StringBuffer();
			String str = "";
			//行读取
			while ((str = bufferedReader.readLine()) != null) {
				// 当读取完毕,就添加到容器中
				sb.append(str);
			}
			//测试是否得到json字符串
			Log.e("TAG", ""+sb.toString());
			//创建本地对象的集合
			 newBeanlist = new ArrayList<NewsBean>();
			// 整体是一个jsonObject
			JSONObject jsonObject = new JSONObject(sb.toString());
			// 键是jsonArray数组
			JSONArray jsonArray = jsonObject.getJSONArray("data");
			for (int i = 0; i < jsonArray.length(); i++) {
				//获取jsonArray中的每个对象
				 JSONObject jsonObject2 = jsonArray.getJSONObject(i);
				//创建本地的newsBean对象
				NewsBean newsBean = new NewsBean();
				//为该对象进行属性值的设置操作
				newsBean.imageViewUrl = jsonObject2
						.getString("picSmall");
				newsBean.title = jsonObject2.getString("name");
				newsBean.content = jsonObject2.getString("description");
				//添加对象,组建集合
				newBeanlist.add(newsBean);

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return newBeanlist;
	}
}

JsonAdapter

package com.example.asynctask;

import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class JsonAdapter extends BaseAdapter {

	List<NewsBean> data = new ArrayList<NewsBean>();
	LayoutInflater inflater;
	private ImageLoaderAsyncTask imageLoaderAsyncTask;
	
	public JsonAdapter(Context context,List<NewsBean> data) {
		super();
		this.data = data;
		inflater = LayoutInflater.from(context);
		imageLoaderAsyncTask = new ImageLoaderAsyncTask();
	}

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

	@Override
	public Object getItem(int position) {
		return data.get(position);
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewHolder = null;
		if (convertView == null) {
			viewHolder = new ViewHolder();
			convertView = inflater.inflate(R.layout.listview_item, null);
			viewHolder.title = (TextView) convertView
					.findViewById(R.id.tv_title);
			viewHolder.content = (TextView) convertView
					.findViewById(R.id.tv_content);
			viewHolder.imageView = (ImageView) convertView
					.findViewById(R.id.iv_imageview);
			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) convertView.getTag();
		}
		String imageViewUrl = data.get(position).imageViewUrl;
		//进行绑定--不会出现图片错位现象--因为viewholder是复用的,会显示复用的那个itme的图片
		viewHolder.imageView.setTag(imageViewUrl);
		
		viewHolder.title.setText(data.get(position).title);
		viewHolder.content.setText(data.get(position).content);
		/**
		 * 这个方式是通过分线程进行图片下载
		 */
//		new ImageLoaderThread().showImageByThread(viewHolder.imageView, data.get(position).imageViewUrl);
		/**
		 * 这个方式是进行异步任务方式进行图片加载
		 */
		imageLoaderAsyncTask.showImageAsyncTask(viewHolder.imageView, data.get(position).imageViewUrl);
		return convertView;
	}

	class ViewHolder{
		public TextView title,content;
		public ImageView imageView;
	}
}
ImageLoaderAsyncTask

package com.example.asynctask;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.R.integer;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.LruCache;
import android.widget.ImageView;

public class ImageLoaderAsyncTask {
	private LruCache<String, Bitmap> mCache;
	/**构造方法初始化一个缓存*/
	public ImageLoaderAsyncTask() {
		super();
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory/4;
		mCache = new LruCache<String, Bitmap>(cacheSize){
			@Override
			protected int sizeOf(String key, Bitmap value) {
				//通过这个方法,获取存储的内存的大小
				return value.getByteCount();
			}
		};
	}
	/**向缓存中添加图片*/
	public void addBitmapToCache(String url ,Bitmap bitmap){
		if (getBitmapFromCache(url) == null) {
			mCache.put(url, bitmap);
		}
	}
	/**从缓存中获取bitmap*/
	public Bitmap getBitmapFromCache(String url){
		return mCache.get(url);
	}
	/**
	 * 使用异步任务进行加载图片
	 * 
	 */
	public void showImageAsyncTask(ImageView imageView, final String url) {
		Bitmap bitmap = getBitmapFromCache(url);
		//如果缓存中没有图片,就进行下载操作
		if (bitmap == null) {
			//讲adapter传过来的imageview和url 通过构造方法传递到异步任务中
			new ImageAsyncTask(imageView,url).execute(url);
		}else {
			//如果缓存中有图片,就直接进行图片的设置操作
			imageView.setImageBitmap(bitmap);
		}
	}

	/**
	 * 开启异步任务进行下载图片
	 * 参数:
	 * 是图片的地址信息
	 * 没有进度显示
	 * 返回一个图片
	 * @author wyf
	 *
	 */
	class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {

		/**
		 * 这里需要设置属性的原因是
		 * imageview是因为需要判断是不是绑定url,以及更新ui操作
		 * url需要
		 */
		private ImageView imageView;
		private String url;
		public ImageAsyncTask(ImageView imageView, String url) {
			super();
			this.imageView = imageView;
			this.url = url;
		}

		@Override
		protected Bitmap doInBackground(String... params) {
			//多留意parm[0],因为只传过来一个url,所以就取出第一个索引值
			Bitmap bitmap = getBitmapFromUrl(params[0]);
			//将bitmap保存到缓存中
			if (bitmap!=null) {
				addBitmapToCache(params[0], bitmap);
				
			}
			return bitmap;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			super.onPostExecute(bitmap);
			//判断是不是绑定的特定的url地址,防止出现图篇错乱
			if (imageView.getTag().equals(url)) {
				//更新ui
				imageView.setImageBitmap(bitmap);
			}
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			super.onProgressUpdate(values);
		}

	}

	/**
	 * 通过url获取网络图片
	 * 跟那个线程下载图片方式一样一样的
	 * @param urlString
	 * @return
	 */
	public Bitmap getBitmapFromUrl(String urlString) {
		Bitmap bitmap = null;
		InputStream inputStream = null;
		try {
			URL httpUrl = new URL(urlString);
			HttpURLConnection connection = (HttpURLConnection) httpUrl
					.openConnection();
			inputStream = new BufferedInputStream(connection.getInputStream());
			bitmap = BitmapFactory.decodeStream(inputStream);
			connection.disconnect();
			return bitmap;

		} catch (Exception e) {
		} finally {
			try {
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return bitmap;

	}
}


*****************************************************优化二*******************************************

主activity变化

JsonAdapter adapter = new JsonAdapter(MainActivity.this, newBeanlist,listView);

JsonAdapter

package com.example.asynctask;

import java.util.ArrayList;
import java.util.List;

import android.R.integer;
import android.R.menu;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class JsonAdapter extends BaseAdapter implements OnScrollListener {

	List<NewsBean> data = new ArrayList<NewsBean>();
	LayoutInflater inflater;
	private ImageLoaderAsyncTask imageLoaderAsyncTask;
	private int mStart;
	private int mEnd;
	private boolean myFirst;
	// 用来保存所有图片的url地址信息
	public static String[] URLS;

	public JsonAdapter(Context context, List<NewsBean> data, ListView listView) {
		super();
		myFirst = true;
		this.data = data;
		inflater = LayoutInflater.from(context);
		imageLoaderAsyncTask = new ImageLoaderAsyncTask(listView);

		URLS = new String[data.size()];
		for (int i = 0; i < data.size(); i++) {
			URLS[i] = data.get(i).imageViewUrl;
		}
		listView.setOnScrollListener(this);
	}

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

	@Override
	public Object getItem(int position) {
		return data.get(position);
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder viewHolder = null;
		if (convertView == null) {
			viewHolder = new ViewHolder();
			convertView = inflater.inflate(R.layout.listview_item, null);
			viewHolder.title = (TextView) convertView
					.findViewById(R.id.tv_title);
			viewHolder.content = (TextView) convertView
					.findViewById(R.id.tv_content);
			viewHolder.imageView = (ImageView) convertView
					.findViewById(R.id.iv_imageview);
			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewHolder) convertView.getTag();
		}
		String imageViewUrl = data.get(position).imageViewUrl;
		// 进行绑定--不会出现图片错位现象--因为viewholder是复用的,会显示复用的那个itme的图片
		viewHolder.imageView.setTag(imageViewUrl);

		viewHolder.title.setText(data.get(position).title);
		viewHolder.content.setText(data.get(position).content);
		/**
		 * 这个方式是通过分线程进行图片下载
		 */
		// new ImageLoaderThread().showImageByThread(viewHolder.imageView,
		// data.get(position).imageViewUrl);
		/**
		 * 这个方式是进行异步任务方式进行图片加载
		 */
		imageLoaderAsyncTask.showImageAsyncTask(viewHolder.imageView,
				data.get(position).imageViewUrl);
		return convertView;
	}

	class ViewHolder {
		public TextView title, content;
		public ImageView imageView;
	}

	/**
	 * 状态切换调用 初始化不调用
	 */
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if (scrollState == SCROLL_STATE_IDLE) {
			// 记载可见项目
			imageLoaderAsyncTask.loadImage(mStart, mEnd);
		} else {
			// 停止任务
			imageLoaderAsyncTask.cancelAllTasks();
		}
	}

	/**
	 * 滑动时候调用, 初始化调用
	 */
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		mStart = firstVisibleItem;
		mEnd = firstVisibleItem + visibleItemCount;
		// 初始化时候,itemcount为0 ,item还没有加载,需要2个方面判断
		if (myFirst && visibleItemCount > 0) {
			imageLoaderAsyncTask.loadImage(mStart, mEnd);
			myFirst = false;
		}

	}
}

ImageLoaderAsyncTask

package com.example.asynctask;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import android.R.integer;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.LruCache;
import android.widget.ImageView;
import android.widget.ListView;

public class ImageLoaderAsyncTask {
	private LruCache<String, Bitmap> mCache;
	private ListView listView;
	private Set<ImageAsyncTask> mTasks;

	/** 构造方法初始化一个缓存 */
	public ImageLoaderAsyncTask(ListView listView) {
		super();
		this.listView = listView;
		mTasks = new HashSet<ImageLoaderAsyncTask.ImageAsyncTask>();
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int cacheSize = maxMemory / 4;
		mCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap value) {
				// 通过这个方法,获取存储的内存的大小
				return value.getByteCount();
			}
		};
	}

	/** 向缓存中添加图片 */
	public void addBitmapToCache(String url, Bitmap bitmap) {
		if (getBitmapFromCache(url) == null) {
			mCache.put(url, bitmap);
		}
	}

	/** 从缓存中获取bitmap */
	public Bitmap getBitmapFromCache(String url) {
		return mCache.get(url);
	}

	public void loadImage(int start, int end) {
		for (int i = start; i < end; i++) {
			String url = JsonAdapter.URLS[i];
			Bitmap bitmap = getBitmapFromCache(url);
			if (bitmap == null) {
				// 如果缓存中没有去下载
				ImageAsyncTask task = new ImageAsyncTask(url);
				task.execute(url);
				mTasks.add(task);
			} else {
				ImageView imageView = (ImageView) listView.findViewWithTag(url);
				imageView.setImageBitmap(bitmap);
			}
		}
	}

	/**
	 * 使用异步任务进行加载图片
	 * 
	 */
	public void showImageAsyncTask(ImageView imageView, final String url) {
		Bitmap bitmap = getBitmapFromCache(url);
		// 如果缓存中没有图片,就进行下载操作
		if (bitmap == null) {
			// 如果缓存中没有图片,就设置默认图片即可
			imageView.setImageResource(R.drawable.ic_launcher);
		} else {
			// 如果缓存中有图片,就直接进行图片的设置操作
			imageView.setImageBitmap(bitmap);
		}
	}

	/**
	 * 开启异步任务进行下载图片 参数: 是图片的地址信息 没有进度显示 返回一个图片
	 * 
	 * @author wyf
	 * 
	 */
	class ImageAsyncTask extends AsyncTask<String, Void, Bitmap> {

		/**
		 * 这里需要设置属性的原因是 imageview是因为需要判断是不是绑定url,以及更新ui操作 url需要
		 */
		private String url;

		public ImageAsyncTask(String url) {
			super();
			this.url = url;
		}

		@Override
		protected Bitmap doInBackground(String... params) {
			// 多留意parm[0],因为只传过来一个url,所以就取出第一个索引值
			Bitmap bitmap = getBitmapFromUrl(params[0]);
			// 将bitmap保存到缓存中
			if (bitmap != null) {
				addBitmapToCache(params[0], bitmap);

			}
			return bitmap;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
		}

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			super.onPostExecute(bitmap);
			// 判断是不是绑定的特定的url地址,防止出现图篇错乱
			ImageView imageView = (ImageView) listView.findViewWithTag(url);
			if (imageView != null && bitmap != null) {
				imageView.setImageBitmap(bitmap);
			}
			// if (imageView.getTag().equals(url)) {
			// //更新ui
			// imageView.setImageBitmap(bitmap);
			// }
		}

		@Override
		protected void onProgressUpdate(Void... values) {
			super.onProgressUpdate(values);
		}

	}

	/**
	 * 通过url获取网络图片 跟那个线程下载图片方式一样一样的
	 * 
	 * @param urlString
	 * @return
	 */
	public Bitmap getBitmapFromUrl(String urlString) {
		Bitmap bitmap = null;
		InputStream inputStream = null;
		try {
			URL httpUrl = new URL(urlString);
			HttpURLConnection connection = (HttpURLConnection) httpUrl
					.openConnection();
			inputStream = new BufferedInputStream(connection.getInputStream());
			bitmap = BitmapFactory.decodeStream(inputStream);
			connection.disconnect();
			return bitmap;

		} catch (Exception e) {
		} finally {
			try {
				inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return bitmap;

	}

	/**
	 * ' 取消
	 */
	public void cancelAllTasks() {
		if (mTasks != null) {
			for (ImageAsyncTask task : mTasks) {
				// 取消
				task.cancel(false);

			}
		}
	}
}



利用 TensorFlow 训练自己的目标识别器。本文内容来自于我的毕业设计,基于 TensorFlow 1.15.0,其他 TensorFlow 版本运行可能存在问题。.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值