码迷,mamicode.com
首页 > 其他好文 > 详细

图片轮播_支持显示网络图片及下载图片至SD后再显示

时间:2014-08-22 17:58:49      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:des   android   style   http   color   使用   os   io   文件   

现在的移动应用, 很常见的一个交互效果就是在首页顶部添加图片轮播的控件, 焦点图可以放入广告, 也可以放入文章的内容图片, 它们不断自动切换, 点击焦点图即跳至对应的界面. 交互效果很棒. 做图片轮播的效果, 方法并不少. 本文使用了常见的viewpager 去实现. 支持显示网络图片下载在缓存显示, 如果有SD卡则默认将图片下载至SD卡中再显示本地的图片.

其实网上这类代码已经很多,  应该也有很多写得比我好. 今天有点时间, 就做了个来练手, 顺便写下自己第一篇原创文章. 敲代码之前也参考了一些网上的例子, 感谢那些大神!

好了,不多说别的, 直接上代码.(为了减少类的数量,  将一些方法直接写在主类中, 多多见谅哈~)


MainActivity:

/**
 * 图片轮播器<br>支持显示网络图片以及将网络图片下载至本地显示
 * @author Mr.ET
 *
 */
public class MainActivity extends Activity{
	
	private List<ImageView> mImageViewList = null;
	private List<View> mViewList = null;
	private TextView mArticleTitle = null;
	private ViewPager mViewPager = null;
	private Handler mHandler = null;
	private LinearLayout mCustomSpace = null;
	private MyPagerAdapter adapter = null;
	private boolean loopPlayState = false;
	private View view;
	
	//private final String mySign = "url";
	private List<String> tList,pList,nList;
	private List<Bitmap> bList;
	//private int p1 = -1,p2 = -1,p3 = -1,p4 = -1;
	private String name;
	//图片总数
	private final int pAccount = 4;
	//控制图片变量
	private int pNum = 0;
	private int readStyle = -1;
	private final static int readInNet = 0;
	private final static int readInSD = 1;
	private final static int readInCache = 2;
	
	
	private Handler handler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			if(msg.what == 0x111){
				if(bList != null && bList.size() > 0 && readStyle != readInNet) bList.clear();
				if(mImageViewList != null && mImageViewList.size() > 0) mImageViewList.clear();
				//图片已备齐,可以设置pager图片
				for(int i=0;i<pList.size();i++){
					ImageView imageView = new ImageView(MainActivity.this);
					imageView.setLayoutParams(new LayoutParams(
							LayoutParams.MATCH_PARENT,
							LayoutParams.MATCH_PARENT));
					imageView.setScaleType(ScaleType.FIT_XY);
					imageView.setOnClickListener(new ClickListener(i));
					mImageViewList.add(imageView);
					view = new View(MainActivity.this);
					LayoutParams layoutParams = new LayoutParams(14, 14);
					layoutParams.setMargins(3, 0, 3, 0);
					view.setLayoutParams(layoutParams);
					view.setBackgroundResource(R.drawable.dot_normal);
					mViewList.add(view);
					mCustomSpace.addView(view);
					if(readStyle != readInNet){
						BitmapFactory.Options options = new BitmapFactory.Options();
						options.inSampleSize = 2;
						Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/demo/"+nList.get(i)+".jpg", options);
						bList.add(bm);
					}
				}
				adapter = new MyPagerAdapter();
				mViewPager.setAdapter(adapter);
				mViewPager.setOnPageChangeListener(new MyPageChangeListener());
				
				if (!loopPlayState) {
					mArticleTitle.setText(tList.get(0));
					mViewPager.setCurrentItem(0);
					mHandler.postDelayed(loopPlay, 3000);
					loopPlayState = true;
				}
			}
			super.handleMessage(msg);
		}
	};
	
	
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mViewPager = (ViewPager)findViewById(R.id.viewpager);
		mArticleTitle = (TextView)findViewById(R.id.article_title);
		mCustomSpace = (LinearLayout)findViewById(R.id.custom_space);
		mHandler = new Handler();
		mImageViewList = new ArrayList<ImageView>();
		mViewList = new ArrayList<View>();
		
		
		tList = new ArrayList<String>();
		pList = new ArrayList<String>();
		nList = new ArrayList<String>();
		bList = new ArrayList<Bitmap>();
		for(int i=0;i<4;i++){ tList.add("这是标题"+i); }
		pList.add("http://b.hiphotos.baidu.com/image/pic/item/203fb80e7bec54e767710215bb389b504fc26a1f.jpg");
		pList.add("http://d.hiphotos.baidu.com/image/pic/item/32fa828ba61ea8d37e6f6c0f950a304e251f586f.jpg");
		pList.add("http://g.hiphotos.baidu.com/image/pic/item/e1fe9925bc315c605aeb75e48fb1cb13495477ba.jpg");
		pList.add("http://h.hiphotos.baidu.com/image/pic/item/d000baa1cd11728bd0359429cafcc3cec3fd2ca4.jpg");
		
		
		readyToImage();
		
	}
	
	/**
	 * 下载图片前的准备 <br>主要根据有无SD卡来准备图片是下载在本地还是放在内存中
	 */
	public void readyToImage(){
		if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){	//有SD卡
			String folderPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/demo";
			File demoFile = new File(folderPath);
			if(!demoFile.exists()){ //不存在这个文件夹,即不存在所需的图片. 就启动线程去下载图片
				readStyle = readInSD;
				for(int p=0;p<pList.size();p++){
					DLPThread mythread = new DLPThread(pList.get(p));
					mythread.start();
				}
			}else{
				File[] files = demoFile.listFiles();
				if(files.length >= 4 && isImage(getFileType(files[0].getName())) && isImage(getFileType(files[1].getName()))
						&& isImage(getFileType(files[2].getName())) && isImage(getFileType(files[3].getName()))){
					readStyle = readInCache;
					for(int i=0;i<4;i++){ nList.add(files[i].getName()); }
					mainSetImage();
				}else{	//下载图片
					readStyle = readInSD;
					for(int p=0;p<pList.size();p++){
						DLPThread mythread = new DLPThread(pList.get(p));
						mythread.start();
					}
				}
			}
		}else{	//无SD卡
			readStyle = readInNet;
			for(int p=0;p<pList.size();p++){
				DLPThread mythread = new DLPThread(pList.get(p));
				mythread.start();
			}
		}
	}
	
	
	/**
	 * 线程下载图片至本地
	 * @author Mr.ET
	 *
	 */
	class DLPThread extends Thread{
		private String url;
		
		public DLPThread(String url){
			this.url = url;
		}
		
		public void run(){
			try {
				Looper.prepare();
				Bitmap bitmap = (Bitmap)utils.requestGet(this.url, Bitmap.class);
				name = String.valueOf(System.currentTimeMillis());
				nList.add(name);	//存放文件名
				if(readStyle != readInNet){
					File folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/demo");
					if(!folder.exists()){
						folder.mkdir();
					}
					String path = folder + "/"+name+".jpg";
					File file = new File(path);
					FileOutputStream fileOutputStream = new FileOutputStream(file);
					bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileOutputStream);
					fileOutputStream.flush();
					fileOutputStream.close();
				}else{	//无SD卡
					bList.add(bitmap);
				}
				
				pNum ++;
				setImage();
				Looper.loop();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	} 
	
	
	public void setImage(){
		if(pNum == pAccount){
			handler.sendEmptyMessage(0x111);
		}
	}
	
	
	private final class MyPagerAdapter extends PagerAdapter {

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

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			((ViewPager) container).removeView(mImageViewList.get(position));
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			ImageView temp = mImageViewList.get(position);
			temp.setImageBitmap(bList.get(position));
			
			((ViewPager) container).addView(temp);
			return temp;
		}

		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}

	}
	
	
	
	/**
	 * 当ViewPager中页面的状态发生改变时调用
	 * 
	 * @author Mr.ET
	 * 
	 */
	private class MyPageChangeListener implements OnPageChangeListener {

		private int historyPosition = 0;

		/**
		 * 当ViewPager中页面的状态发生改变时调用
		 */
		public void onPageSelected(int position) {
			mArticleTitle.setText(tList.get(position));
			mViewList.get(historyPosition).setBackgroundResource(
					R.drawable.dot_normal);
			mViewList.get(position).setBackgroundResource(
					R.drawable.dot_focused);
			historyPosition = position;
		}

		public void onPageScrollStateChanged(int arg0) {
		}

		public void onPageScrolled(int arg0, float arg1, int arg2) {
		}
	}
	
	/**
	 * 设置自动间隔3秒自动切换图片
	 */
	Runnable loopPlay = new Runnable() {
		@Override
		public void run() {
			int position = mViewPager.getCurrentItem();
			if(position == (pList.size()-1)){
				position = 0;
				mViewPager.setCurrentItem(position);
			}
			else{
				Log.i("position++", "position++="+position++);
				mViewPager.setCurrentItem(position++);
			}
			mHandler.postDelayed(loopPlay, 3000);
			
		}
	};
	
	
	private class ClickListener implements OnClickListener{
		private int location;
		public ClickListener(int location){
			this.location = location;
		}
		
		@Override
		public void onClick(View v){
			Toast.makeText(MainActivity.this, "你点击了第"+this.location+"张的图片", 1000).show();
		}
	}
	
	
	/**
	 * 获取文件类型
	 * @param fileName
	 * @return
	 */
	public static String getFileType(String fileName) {
        if (fileName != null) {
                int typeIndex = fileName.lastIndexOf(".");
                if (typeIndex != -1) {
                        String fileType = fileName.substring(typeIndex + 1)
                                        .toLowerCase();
                        return fileType;
                }
        }
        return "";
	}
	
	/**
	 * 判断是否图片
	 * @param type
	 * @return
	 */
	public static boolean isImage(String type) {
        if (type != null
                        && (type.equals("jpg") || type.equals("gif")
                                        || type.equals("png") || type.equals("jpeg")
                                        || type.equals("bmp") || type.equals("wbmp")
                                        || type.equals("ico") || type.equals("jpe"))) {
                return true;
        }
        return false;
	}
	
	
	/**
	 * 直接从SD获取图片显示
	 */
	public void mainSetImage(){
		if(bList != null && bList.size() > 0) bList.clear();
		if(mImageViewList != null && mImageViewList.size() > 0) mImageViewList.clear();
		//图片已备齐,可以设置pager图片
		for(int i=0;i<4;i++){
			ImageView imageView = new ImageView(MainActivity.this);
			imageView.setLayoutParams(new LayoutParams(
					LayoutParams.MATCH_PARENT,
					LayoutParams.MATCH_PARENT));
			imageView.setScaleType(ScaleType.FIT_XY);
			imageView.setOnClickListener(new ClickListener(i));
			mImageViewList.add(imageView);
			view = new View(MainActivity.this);
			LayoutParams layoutParams = new LayoutParams(14, 14);
			layoutParams.setMargins(3, 0, 3, 0);
			view.setLayoutParams(layoutParams);
			view.setBackgroundResource(R.drawable.dot_normal);
			mViewList.add(view);
			mCustomSpace.addView(view);
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inSampleSize = 2;
			Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/demo/"+nList.get(i), options);
			bList.add(bm);
		}
		adapter = new MyPagerAdapter();
		mViewPager.setAdapter(adapter);
		mViewPager.setOnPageChangeListener(new MyPageChangeListener());
		
		if (!loopPlayState) {
			mArticleTitle.setText(tList.get(0));
			mViewPager.setCurrentItem(0);
			mHandler.postDelayed(loopPlay, 3000);
			loopPlayState = true;
		}
	}
	
	
	
}

utils, 里面也简单的封装一下httpclient. 

public class utils {
	private static DefaultHttpClient httpClient;
	
	
	
	static{
		if(null == httpClient){
			HttpParams httpParams = new BasicHttpParams();
			
			HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
			HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);
			HttpProtocolParams.setUseExpectContinue(httpParams, true);
			
			
	        ConnManagerParams.setMaxTotalConnections(httpParams, 10);  
	        ConnManagerParams.setTimeout(httpParams, 60000);  
	        ConnPerRouteBean connPerRoute = new ConnPerRouteBean(8);
	        ConnManagerParams.setMaxConnectionsPerRoute(httpParams,connPerRoute);  
	        HttpConnectionParams.setConnectionTimeout(httpParams, 20000);
	        HttpConnectionParams.setSoTimeout(httpParams, 30000);
			
			SchemeRegistry schreg = new SchemeRegistry();
			schreg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
			schreg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
			
			ClientConnectionManager connManager = new ThreadSafeClientConnManager(httpParams, schreg);
			
			httpClient = new DefaultHttpClient(connManager, httpParams);
			
		}
	}
	
	
	public static HttpClient getHttpClient(){
		return httpClient;
	}
	
	
	public static Object requestGet(String url,Class<?>c){
		try {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);
			if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
				byte[] b = readInputStream(response.getEntity().getContent());
				if(c == String.class){
					String resultStr = new String(b);
					return resultStr;
				}
				if(c == Bitmap.class){
					Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
//					BitmapFactory.Options options = new BitmapFactory.Options();
//					options.inSampleSize = 10;
//					Bitmap bitmap = BitmapFactory.decodeStream(response.getEntity().getContent(), null, options);
					return bitmap;
				}
				
			}else{
				//sorry, can not ask for the http server......
			}
			
			
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	
	
	private static byte[] readInputStream(InputStream in) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] b = new byte[1024];
		int len = 0;
		while ((len = in.read(b)) != -1) {
			baos.write(b, 0, len);
		}
		in.close();
		return baos.toByteArray();
	}
	
	
	
	
}

下面是用到的资源文件

dot_focused.xml :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#aaFFFFFF" />

    <corners android:radius="50dip" />

</shape>

dot_normal.xml :

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#33000000" />

    <corners android:radius="5dip" />

</shape>



主要思路:

先判断手机是否有SD卡: 1, 有SD卡. 将图片下载至SD卡中, 图片轮播将图片转为bitmap, 显示在imageview中.  2, 无SD卡. 将图片下载至缓存中, 直接转为bitmap并显示在imageview中.  

第二种方法很不好, 因为每次打开应用都要发HTTP请求去下载图片,再来显示, 而HTTP请求是相当耗资源的操作,  严重影响交互. 所以请尽量减少无谓的HTTP请求. 当你的应用第一次安装, 这个时候就去下载这四个图片放在本地,  这是必须的,  因为这时候本地一张图片都没有嘛. 然后当用户继续操作应用, 比如继续看新闻看别的文章的时候,  可以在后台启动个线程 去 检查这四张图片的接口有无更新,  如果有更新, 再启动线程将图片悄悄的下载在本地中 , 并更新图片轮播的内容. 这样, 当用户下次再启动应用的时候, 图片轮播加载图片的速度就快了哦. 这是其中之一的思路. 具体还要看应用的需求,  在实现上有所变化.

代码中有注释, 也很简单. 应该很容易看懂吧.

例子写的不够简洁, 也还有不少可以优化的地方, 奈何时间有限, 请多包涵. 咱们互相学习, 一起进步吧. ^^


代码下载



图片轮播_支持显示网络图片及下载图片至SD后再显示

标签:des   android   style   http   color   使用   os   io   文件   

原文地址:http://blog.csdn.net/stzy00/article/details/38758431

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!