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

现在的移动应用, 很常见的一个交互效果就是在首页顶部添加图片轮播的控件, 焦点图可以放入广告, 也可以放入文章的内容图片, 它们不断自动切换, 点击焦点图即跳至对应的界面. 交互效果很棒. 做图片轮播的效果, 方法并不少. 本文使用了常见的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请求. 当你的应用第一次安装, 这个时候就去下载这四个图片放在本地,  这是必须的,  因为这时候本地一张图片都没有嘛. 然后当用户继续操作应用, 比如继续看新闻看别的文章的时候,  可以在后台启动个线程 去 检查这四张图片的接口有无更新,  如果有更新, 再启动线程将图片悄悄的下载在本地中
, 并更新图片轮播的内容. 这样, 当用户下次再启动应用的时候, 图片轮播加载图片的速度就快了哦. 这是其中之一的思路. 具体还要看应用的需求,  在实现上有所变化.

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

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

代码下载

时间: 2024-10-06 00:29:25

图片轮播_支持显示网络图片及下载图片至SD后再显示的相关文章

lightSlider 好图片轮播插件 支持移动端

http://jquery-plugins.net/jquery-lightslider-lightweight-responsive-content-slider https://github.com/sachinchoolur/lightslider api : http://sachinchoolur.github.io/lightslider/settings.html demo: <!DOCTYPE html> <html lang="en"> <

15款jQuery带缩略图的图片轮播切换特效代码

JQuery宽屏电影大图幻灯片轮播切换代码 jquery带文字缩略图的图片轮播切换代码 jQuery OwlCarousel图片滚动插件世界杯图片轮播滚动代码 jQuery仿中国建设银行带缩略图控制滚动图片轮播切换 jquery图片滑动切换效果左右按钮控制图片滑动轮播切换效果 jQuery幻灯片插件可自动轮播和暂停的图片幻灯片代码 jQuery带缩略图的焦点图代码_带标题的焦点图代码 jquery图片轮播插件带小缩略图片的焦点图切换效果代码 原生js图片插件缩略图片控制大图淡出淡进切换支持图片轮

UISCrollView —— 图片轮播器封装实现(三)——(第三讲)

1.分析 利用xib布局,然后自定义一个UIView,解析xib,然后利用控制器传入数据,将其加载到控制器的view上展示即可 2. 程序结构 3. 代码具体实现 1>  xib文件 2>  创建类 XMGPageView,然后将其与xib文件关联,选中xib文件,然后设置下文中 " custom class " 为定义的类,让其来管理xib 1>    (如图,设置xib与类关联) 2>  XMGPageView.h 文件中,声明分页图片数组属性,及其一个快速

【JavaScript】使用Bootstrap来编写 图片轮播Carousel

图片轮播组件是一个在网页中很常见的技术,但是如果直接编写的话,需要很长的JavaScript编码,同时也不好控制大小. 如果使用Bootstrap来编写图片轮播组件Carousel,则能够节约很多时间. 同时说一下,Carousel这个词的本义是回旋木马. 一.基本目标 在网页编写多张图片的轮播组件Carousel,鼠标放在上面自带悬停效果,并且在每张图片下面配有图片说明. 由于笔者的电脑视频录制软件比较渣,也觉得没必要画太多时间在这上面,觉得只要能说明问题就行,所以下面的GIF失色比较严重,但

走马灯图片轮播控件----------WinForm控件开发系列

/// <summary> /// 走马灯图片轮播控件 /// </summary> [ToolboxItem(true)] [DefaultProperty("Images")] [Description("走马灯图片轮播控件")] public partial class ImageCarouselExt : Control { #region private bool barShow = true; /// <summary>

图片轮播控件----------WinForm控件开发系列

   public partial class ImageCarouselDevelopExt : Control { #region /// <summary> /// 动画播放定时器 /// </summary> private Timer carouselTimer = new Timer(); /// <summary> /// 轮播的五个PictureBox /// </summary> private List<PictureBox>

Javascript和jQuery WordPress 图片轮播插件, 内容滚动插件,前后切换幻灯片形式显示

用于在有限的网页空间内展示一组产品图片或者照片,同时还有非常吸引人的动画效果.本文向大家推荐12款实用的 jQuery 图片轮播效果插件,帮助你在你的项目中加入一些效果精美的图片轮播效果,希望这些插件能够帮助到你.Nivo Slider首先推荐的这款插件号称世界上最棒的图片轮播插件,有独立的 jQuery 插件和 WordPress 插件两个版本.目前下载量已经突破 1,800,000 次!jQuery 独立版本的插件主要有如下特色:? 16个独特的过渡效果? 简洁和有效的标记? 加载参数设置?

使用Ajax+jQuery来实现前端收到的数据在console上显示+简单的主页设计与bootstrap插件实现图片轮播

1.实现前端输入的数据在console上显示 上一篇是解决了在前端的输入信息在cygwin上显示,这次要给前台们能看见的数据,因为数据库里插入的数据少,所以写的语句翻来覆去就那几个词,emmm···当然实现了个不靠谱的,在前台还能看见用户密码 ·····功能是这个意思hhhh 在register也就是注册界面部分的代码: <script> $('#submit').on("click ", function () { var a = $('#login input[name

基于bootstrap的图片轮播效果展示

<!DOCTYPE html><html lang="zh-CN"> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,