效果图:

瀑流流实现涉及的知识点

1.ScrollView滚动视图,我们这里用的是自定义ScrollView

/**
* Created by Spring on 2015/11/2.
* 自定义ScrollView
*/
public class CustomScrollView extends ScrollView { public CustomScrollView(Context context) {
super(context);
} public CustomScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
} public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} /**
* 获得由垂直方向滚动条代表的所有垂直范围,缺省的范围是当前视图的画图高度。
*/
public int getComputeVerticalScrollRange() {
//滚动视图的可滚动范围是所有子元素的高度。
return super.computeVerticalScrollRange();
} /**
* 获得滚动条的滑块垂直方向的偏移。
*/
public int getComputeVerticalScrollOffSet() {
//计算垂直方向滚动条的滑块的偏移。此值用来计算滚动条轨迹的滑块的位置。
return super.computeVerticalScrollOffset();
} /**
*
* getScrollY()获得ScrollView滑动的距离
* getHeight是获得控件的显示的大小,如果控件大小超出的屏幕,那他的大小就是屏幕的大小。
* 详情见:http://www.cnblogs.com/qinghuaideren/p/3186990.html
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) { if (t + getHeight() >= computeVerticalScrollRange()) {
//ScrollView滑动到底部了
onScrollListener.onBottom(); } else if (getScrollY() == 0) {
//ScrollView滑动到顶部了
onScrollListener.onTop();
} else {
//ScrollView滑动中
onScrollListener.onScroll();
} } /**
* 定义接口
*
* @author admin
*/
public interface OnScrollListener {
void onBottom(); void onTop(); void onScroll();
} private OnScrollListener onScrollListener; public void setOnScrollListener(OnScrollListener onScrollListener) {
this.onScrollListener = onScrollListener;
}
}

2.AsyncTask,异步加载图片

package com.jingling.practice.waterfall;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.ImageView; import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference; /**
* Created by Spring on 2015/11/4.
* 图片异步加载任务
*/
public class ImageLoaderTask extends AsyncTask<TaskParam, Void, Bitmap> {
private TaskParam param;
private final WeakReference<ImageView> imageViewReference; // 防止内存溢出 public ImageLoaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView); } /**
* 完成实际的下载任务
* @param params
* @return
*/
@Override
protected Bitmap doInBackground(TaskParam... params) {
param = params[0];
return loadImageFile(param.getFilename(),param.getAssetManager());
} private Bitmap loadImageFile(final String filename, final AssetManager assetManager) {
InputStream is = null;
try {
Bitmap bmp = BitmapCache.getInstance().getBitmap(filename,
param.getAssetManager());
return bmp;
} catch (Exception e) {
Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null; } /**
* 当下载完成后,显示出下载的图片
* @param bitmap
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
int width = bitmap.getWidth();// 获取真实宽高
int height = bitmap.getHeight();
ViewGroup.LayoutParams lp = imageView.getLayoutParams();
lp.height = (height * param.getItemWidth()) / width;// 调整高度
imageView.setLayoutParams(lp); imageView.setImageBitmap(bitmap); } }
}
} }

3.MainActivity

package com.jingling.practice.waterfall;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class MainActivity extends Activity {
/**
* 滚动视图
*/
private CustomScrollView waterfall_scroll;
/**
* 布局内容框架
*/
private LinearLayout waterfall_container;
/**
* 布局内容item
*/
private ArrayList<LinearLayout> waterfall_items;
/**
* 图片文件名
*/
private List<String> image_filenames;
/**
* 图片路径前缀
*/
private final String image_path = "images";
/**
* 提供关于屏幕尺寸和分辨率的信息
*/
private Display display;
/**
* 访问assets目录下的文件
*/
private AssetManager assetManager; /**
* 每个item的宽度
*/
private int itemWidth;
/**
* 显示列数
*/ private int column_count = 3;
/**
* 每次加载15张图片
*/
private int page_count = 15;
/**
* 当前页数
*/
private int current_page = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取手机默认的屏幕尺寸和分辨率的信息
display = this.getWindowManager().getDefaultDisplay();
//根据屏幕计算每列的大小
itemWidth = display.getWidth() / column_count;
//获取asset目录下的文件
assetManager = this.getAssets(); initLayout();
} public void initLayout() {
waterfall_scroll = (CustomScrollView) findViewById(R.id.waterfall_scroll);
//设置滚动监听
waterfall_scroll.setOnScrollListener(new CustomScrollView.OnScrollListener() {
@Override
public void onBottom() {
// 滚动到最低端
AddItemToContainer(++current_page, page_count);
Log.d("Scroll", "Scroll to bottom");
} @Override
public void onTop() {
// 滚动到最顶端
Log.d("Scroll", "Scroll to top");
} @Override
public void onScroll() {
// 滚动中
Log.d("Scroll", "Scrolling");
}
}); waterfall_container = (LinearLayout) findViewById(R.id.waterfall_container);
waterfall_items = new ArrayList<LinearLayout>();
for (int i = 0; i < column_count; i++) {
LinearLayout itemLayout = new LinearLayout(this);
LinearLayout.LayoutParams itemParams = new LinearLayout.LayoutParams(itemWidth, ViewGroup.LayoutParams.WRAP_CONTENT);
itemLayout.setPadding(2, 2, 2, 2);
itemLayout.setOrientation(LinearLayout.VERTICAL);
itemLayout.setLayoutParams(itemParams);
waterfall_items.add(itemLayout);
waterfall_container.addView(itemLayout);
} // 加载所有图片路径
try {
image_filenames = Arrays.asList(assetManager.list(image_path));
} catch (IOException e) {
e.printStackTrace();
}
// 第一次加载
AddItemToContainer(current_page, page_count);
} private void AddItemToContainer(int pageindex, int pagecount) {
int j = 0;
int images_count = image_filenames.size();
for (int i = pageindex * pagecount; i < pagecount * (pageindex + 1)
&& i < images_count; i++) { j = j >= column_count ? j = 0 : j;
AddImage(image_filenames.get(i), j++);
} } private void AddImage(String filename, int columnIndex) {
ImageView item = (ImageView) LayoutInflater.from(this).inflate(
R.layout.waterfall_item, null);
waterfall_items.get(columnIndex).addView(item); TaskParam param = new TaskParam();
param.setAssetManager(assetManager);
param.setFilename(image_path + "/" + filename);
param.setItemWidth(itemWidth);
ImageLoaderTask task = new ImageLoaderTask(item);
task.execute(param);
}
}

4.android-studio   assets目录的创建(这里的图片全部放在assets目录下的,studio的assets目录不像在eclipse中项目一创建完成就有的)

(1) 选择project

(2)选择你项目下src/main,右键鼠标选择new Directory,输入assets,即可创建成功。

源码已经上传:https://github.com/presCheng/WaterFall.git

android 瀑布流(图片浏览)的更多相关文章

  1. 转载—— android 瀑布流的实现详解,附源码

    介绍 参考自:https://github.com/dodola/android_waterfall,因为原来的代码封装不好,所以,我根据源码的思路,重新写了一遍,所以有了现在这个项目:https:/ ...

  2. 用原生JavaScript实现图片瀑布流的浏览效果

    学习JS,活跃思维,灵活运用的一个较为典型的学习案例.同一个瀑布流的效果但实现方式却很多,利用递归.冒泡等等手法都可以达到你想要的目的.这次要说的就是利用类似递归来实现此效果的原创方案.此方案个人认为 ...

  3. Android瀑布流优化,解决Recyclerview展示大批量图片时Item自动切换、闪烁、空白等问题

    本文涉及的代码案例可以在下方的链接中找到,如果对你有帮助,请给个Star(#^.^#) https://github.com/CodeTillDoom/StaggeredRcl 问题分析 这段时间业务 ...

  4. Android瀑布流照片墙实现,体验不规则排列的美感

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/10470797 传统界面的布局方式总是行列分明.坐落有序的,这种布局已是司空见惯,在 ...

  5. RecyclerView 制作瀑布流图片

    这是瀑布流的效果图 RecyclerView(ListView的升级版) 加载图片用的是第三方图片加载框架 ------------------------------------- 在Xml中 &l ...

  6. android 瀑布流

    我们还是来看一款示例: 看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出现了圆角.下面我简单介绍下实现 ...

  7. android瀑布流效果(仿蘑菇街)

    Android 转载分享(10)  我们还是来看一款示例:(蘑菇街)           看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此. ...

  8. android 瀑布流效果(仿蘑菇街)

    我们还是来看一款示例:(蘑菇街)           看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出 ...

  9. Android瀑布流照片

    http://blog.csdn.net/guolin_blog/article/details/10470797 记得我在之前已经写过一篇关于如何在Android上实现照片墙功能的文章了,但那个时候 ...

随机推荐

  1. Css 描点

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  2. 学习python——博客记录第一天

    HELLO WORLD!   今天第一次开立博客,专门记载学习编程语言中的点点滴滴.今日学习内容: 搭建vs code+ python3.5 "ide" 学习廖雪峰python教程 ...

  3. python执行shell获取硬件参数写入mysql

    最近要获取服务器各种参数,包括cpu.内存.磁盘.型号等信息.试用了Hyperic HQ.Nagios和Snmp,它们功能都挺强大的,但是于需求不是太符,亦或者太heavy. 于是乎想到用python ...

  4. ZOJ1074 (最大和子矩阵 DP)

    F - 最大子矩阵和 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u   Descri ...

  5. openssl 进行证书格式的转换

    各类证书由于存储的内容不同(如是否包含公钥/私钥是否加密存储/单一证书或多证书等).采用编码不同(DER/BASE64).标准不同(如PEM/PKCS),所以尽管X.509标准规定了证书内容规范,但证 ...

  6. 国内大学毕业论文LaTeX模板集合

    国内大学毕业论文LaTeX模板集合 薛瑞尼的清华大学学位论文LaTeX模板http://sourceforge.net/projects/thuthesis/ 北大论文文档 LaTeX 模板 pkut ...

  7. 常用SNS开源系统比较

    常用SNS开源系统比较 这 几天看了很多关于SNS(社交网络服务) 的东西..得到了不少启发..目前的IDEA是..可以在学校弄一个试试..主打的东西不能和现有的SNS冲突(如校内网).利用本地优势. ...

  8. 未能找到类型或命名空间名称“XXXX”(是否缺少 using 指令或程序集引用?) 转

    未能找到类型或命名空间名称“XXXX”(是否缺少 using 指令或程序集引用?)   项目中 App_Code 文件夹中的类的命名空间,在添加的页面的  using XXXX  时,提示 未能找到类 ...

  9. Robot Framework web测试demo

    1.Open RIDE: ride.py 2.New Project: "File" -> "New Project" ,click "OK&q ...

  10. Citrix 服务器虚拟化之十八 桌面虚拟化之部署MCS随机桌面池

    Citrix 服务器虚拟化之十八  桌面虚拟化之部署MCS随机桌面池 完成桌面模版的制作后,可以开始虚拟桌面池的发布 说明: 环境基于实验十七 1.登录DC服务器创建一个组织单位名为Citrix,然后 ...