效果图:

瀑流流实现涉及的知识点

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. jQuery简单导航示例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 嵌入式 python之str操作

    1.字符串的对齐方式:①:center(int[,str])>>> string = 'Fishhat'>>> string.center(55)'         ...

  3. DOM&BOM笔记

    day01正课:1. DOM概述2. ***DOM树3. *查找 1. DOM概述: DHTML:动态网页技术的统称 DHTML=HTML+CSS+JS 鄙视题: HTML XHTML DHTML X ...

  4. HTML 基础元素

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. -_-#【React】

    React Native 用于构建用户界面的JAVASCRIPT库 | ReactReact 入门实例教程颠覆式前端UI开发框架:Reactzhihu1zhihu2 React.js编程思想 < ...

  6. 【模拟】HDU 5752 Sqrt Bo

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5752 题目大意: 定义f(n)=⌊√n⌋,fy(n)=f(fy-1(n)),求y使得fy(n)=1. ...

  7. HDOJ 1097 A hard puzzle(循环问题)

    Problem Description lcy gives a hard puzzle to feng5166,lwg,JGShining and Ignatius: gave a and b,how ...

  8. 《SDN核心技术剖析和实战指南》3.1控制器核心技术读书笔记

    在SDN的架构中,控制器可以说是SDN的核心,它负责对底层转发设备的控制以及向上层应用提供可编程性的北向接口.从实现上看,主要分三个层面来考虑,南向接口技术,北向接口技术以及东西向的可扩展性能力.下面 ...

  9. linux有用网址

    正则表达式在线测试 http://tool.oschina.net/regex

  10. java里遍历map的常见方式

    public static void main(String[] args) { Map<String, String> map = new HashMap<String, Stri ...