android瀑布流简单实现原理

标签: android 瀑布流 原理 | 发表时间:2013-03-26 15:29 | 作者:
出处:http://www.iteye.com

网上关于android瀑布流的例子一大堆,但是很多都是很复杂,对于新手来说有一定的难度。

原理很简单,就是异步下载图片,把图片addView到ScrollView(因为可以上下一直拖动)中,你需要屏幕显示几列就在ScrollView中放置几个LinearLayout,

下面我就一个简单的例子来讲解android瀑布流的用法,样子很丑就不上图了。。

 

1、在xml布局文件:很简单就是

 

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/scrollview">
    <LinearLayout 
        android:orientation="horizontal"
         android:layout_width="fill_parent"
   		 android:layout_height="wrap_content">
       <LinearLayout 
         android:id="@+id/left"
         android:orientation="vertical"
         android:layout_width="fill_parent"
   		 android:layout_height="wrap_content"
        >
   		</LinearLayout>
	    <LinearLayout 
	        android:id="@+id/right"
	        android:orientation="vertical"
	        android:layout_width="fill_parent"
	   		android:layout_height="wrap_content">
	    </LinearLayout>
    </LinearLayout>
</ScrollView>

 

 

2、在java代码中:

 

先声明几个变量,其中imagePathStr数组用来存图片的链接

 

private LinearLayout leftLayout;
	private LinearLayout rightLayout;
	private String[] imagePathStr = { "http://www.cf69.com/Upfiles/BeyondPic/2010-08/20108175740983313.jpg",
             "http://www.syfff.com/UploadFile/pic/2008122163204.jpg", "http://pic.newssc.org/0/10/34/32/10343297_564251.jpg",
             "http://ent.hangzhou.com.cn/images/20090311/zym2009031323.jpg", "http://a4.att.hudong.com/86/60/01300000013093119087608457965.jpg",
             "http://file.sdteacher.gov.cn/upload/gz0901/images/0907/22/110437191.jpg",
             "http://www.fun9.cn/uploadfile/starpic/uploadpics/200910/20091008090155126.jpg",
             "http://img3.yxlady.com/yl/UploadFiles_5361/20110820/20110820120609469.jpg",
             "http://news.sznews.com/content/images/site3/20070827/001558d90baa083c6da20d.jpg", "http://henan.sinaimg.cn/cr/2010/0824/2297073692.jpg",
             "http://www.cf69.com/Upfiles/BeyondPic/2010-08/20108175740983313.jpg", "http://www.syfff.com/UploadFile/pic/2008122163204.jpg",
             "http://pic.newssc.org/0/10/34/32/10343297_564251.jpg", "http://ent.hangzhou.com.cn/images/20090311/zym2009031323.jpg",
             "http://a4.att.hudong.com/86/60/01300000013093119087608457965.jpg", "http://file.sdteacher.gov.cn/upload/gz0901/images/0907/22/110437191.jpg",
             "http://www.fun9.cn/uploadfile/starpic/uploadpics/200910/20091008090155126.jpg",
             "http://img3.yxlady.com/yl/UploadFiles_5361/20110820/20110820120609469.jpg",
             "http://news.sznews.com/content/images/site3/20070827/001558d90baa083c6da20d.jpg", "http://henan.sinaimg.cn/cr/2010/0824/2297073692.jpg" };
	

 

 

其次,在oncreate()中采用异步加载图片的方法把获取到的Drawable添加到左右两栏的LinearLayout中:

 

 

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		leftLayout=(LinearLayout) findViewById(R.id.left);
		rightLayout=(LinearLayout) findViewById(R.id.right);
		int j=0;
		for (int i = 0; i < imagePathStr.length; i++) {
			addToAsynLoadImage(imagePathStr[i],j,i);
			j++;
			if(j<=2){
				j=0;
			}
		}
		
	}

 

 

addToAsynLoadImage() 方法如下,每次加载一个图片就创建一个ImageView,然后把ImageView加到LinearLayout中:

 

 

private void addToAsynLoadImage(String imageUrl, int j, int i) {
		ImageView imageView=new ImageView(this);
		imageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
		imageView.setTag(i);
		new ImageDownloadAsynTask(MainActivity.this,imageUrl,imageView).execute(null);
		if(j==0){
			leftLayout.addView(imageView);
		}else if(j==1){
			rightLayout.addView(imageView);
		}
	}

 

 

ImageDownloadAsynTask()方法继承自AsyncTask<Params, Progress, Result>,

这个类有三个参数,4个步骤(begin,doinbackground,processProgress,end)

最后一个参数是在doinbackground()中返回的结果,另外还有onPreExecute()、onPostExecute()

 

public class ImageDownloadAsynTask extends AsyncTask<Void, Void, Drawable>{

	private Context context;
	private String imageUrl;
	private ImageView imageView;
	private String sdPath="/sdcard/netImages";
	ProgressDialog progressDialog;
	
	public ImageDownloadAsynTask(Context context, String imageUrl,ImageView imageView) {
		this.context=context;
		this.imageUrl=imageUrl;
		this.imageView=imageView;
	}

	/* 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI
	 * 不需要传入什么参数,返回一个Drawable
	 */
	@Override
	protected Drawable doInBackground(Void... params) {
		String filename=sdPath+imageUrl.substring(imageUrl.lastIndexOf("/"));
		File file=new File(filename);
		if(file.exists()==true){
			Bitmap bitmap=BitmapFactory.decodeFile(filename);
			BitmapDrawable bitmapDrawable=new BitmapDrawable(bitmap);
			return bitmapDrawable;
		}else{
			try {
				URL url=new URL(imageUrl);
				URLConnection connection=url.openConnection();
				connection.setDoInput(true);// 使用 URL 连接进行输入
				connection.connect();
				InputStream is = connection.getInputStream();
				Bitmap b=BitmapFactory.decodeStream(is);
				BitmapDrawable bd=new BitmapDrawable(b);
				saveFile(bd,filename);
//				connection.getContent();
				return bd;
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	
	/**通过outPutStream、bitmap.compress(),flush()把图片保存到指定路径
	 * @param bd
	 * @param filename
	 */
	private void saveFile(BitmapDrawable bd, String filename) {
		File file = new File(sdPath);
		if(!file.exists()){
			file.mkdir();
		}
		File f=new File(filename);
		try {
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f));
			Bitmap b=bd.getBitmap();
			b.compress(Bitmap.CompressFormat.JPEG, 80, bos);
			bos.flush();
			bos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		progressDialog.show(context, "","正在下载图片。。。");
	}
	
	
	/**
	 * 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。
	 * 此方法在主线程执行,任务执行的结果作为此方法的参数返回
	 */
	@Override
	protected void onPostExecute(Drawable result) {
		super.onPostExecute(result);
		if(result!=null){//如果doInBackground()获取的结果不为空
			imageView.setBackgroundDrawable(result);//那么就在这一步更新UI
		}
		progressDialog.dismiss();
	}


}

 

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [android 瀑布流 原理] 推荐:

android瀑布流简单实现原理

- - ITeye博客
网上关于android瀑布流的例子一大堆,但是很多都是很复杂,对于新手来说有一定的难度. 原理很简单,就是异步下载图片,把图片addView到ScrollView(因为可以上下一直拖动)中,你需要屏幕显示几列就在ScrollView中放置几个LinearLayout,. 下面我就一个简单的例子来讲解android瀑布流的用法,样子很丑就不上图了.

Android中BaseAdapter原理

- - 移动开发 - ITeye博客
            Android ListView理解,BaseAdapter ListView是Android开发过程中较为常见的组件之一,它将数据以列表的形式展现出来. 一般而言,一个ListView由以下三个元素组 成:. 1.View,用于展示列表,通常是一个xml所指定的. 大家都知道Android的界面基本上是由xml文件负责完成的,所以ListView的界 面也理所应当的使用了xml定义.

【Android】消息机制原理

- - CSDN博客推荐文章
Android 消息机制涉及到的类主要有. 下面结合 Android API 22 的源码分析上面几个类的内部实现细节,以窥探其中的原理一二. Looper 是一个循环处理消息的类,Looper内部维护一个消息队列,循环的从消息队列中取出消息并处理,如果队列为空则等待新消息. Looper 必须关联到某个线程中,这样其才能获得操作系统的调度而执行消息循环处理,默认情况下,通过 Thread 类创建的线程是没有 Looper 的,如果需要该线程拥有消息循环的功能,需要像下面这样在 Runnable 接口实现方法 run() 中创建Looper.

瀑布流布局浅析

- 郑小东 - Taobao UED Team
如果你经常网上冲浪,这样参差不齐的多栏布局,是不是很眼熟啊. 类似的布局,似乎一夜之间出现在国内外大大小小的网站上,比如 Pinterest (貌似是最早使用这种布局的网站了),Mark之,蘑菇街,点点网,以及淘宝最新上线的“哇哦” 等等,倒是很流行哈~ 在淘宝即将上线的众多产品中,你还会大量看到这样的形式呢.

Android 的提权 (root) 原理是什么?

- - 知乎每日精选
Android的内核就是Linux,所以Android获取root其实和Linux获取root权限是一回事儿. 你想在Linux下获取root权限的时候就是执行sudo或者su,接下来系统会提示你输入root用户的密码,密码正确就获得root权限了. Android本身就不想让你获得Root权限,大部分手机出厂的时候根本就没有su这个程序.

Android 进程回收之LowMemoryKiller原理篇

- - CSDN博客移动开发推荐文章
在前面的文章 Android进程保活一文中,对于LowMemoryKiller的概念做了简单的提及. LowMemoryKiller简称低内存杀死机制. 在讲解LowMemoryKiller之前,先看另一个概念:OOMKiller. Linux下有一种OOM KILLER 的机制,它会在系统内存耗尽的情况下,启用自己算法有选择性的kill 掉一些进程.

各大瀑布流简析与建议

- - 博客园_Ruby's Louvre
很难说这东西是什么时候山寨到国内,反正现状就是一涌而上,到处是瀑布流. 瀑布流的鼻祖是Pinterest,图片网. 图片网令我想起了各种相册,如最著名的Flickr. 但区区Pinterest一小站,能够独行特立,引领潮流,可见创新的力量. snatchly.com 最棒的瀑布流 不解释. 瀑布流有两大元素,图片与无限拖.

Android上运行QT项目Necessitas的基本原理

- - CSDN博客推荐文章
by 宋宝华 <21cnbao@gmail.com>. 作者:21cnbao 发表于2012-1-18 16:25:46 原文链接. 阅读:11 评论:0 查看评论.