效果图:

瀑流流实现涉及的知识点

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. python -- 函数传参

    一.参数传入规则 可变参数允许传入0个或任意个参数,在函数调用时自动组装成一个tuple: 关键字参数允许传入0个或任意个参数,在函数调用时自动组装成一个dict: 1. 传入可变参数: def ca ...

  2. 简化的nginx多进程模型demo

    //version 1:以下代码仅演示nginx多进程模型[test@vm c]$ cat mynginx.c#include <stdio.h> #include <string. ...

  3. Scut:GameWebSocketHost 解析

    想使用 Scut 做的是一个短连接项目,所以先直接看 GameWebSocketHost 了. 先来看下 GameWebSocketHost 的成员: protected bool EnableHtt ...

  4. 机器学习(1)之梯度下降(gradient descent)

    机器学习(1)之梯度下降(gradient descent) 题记:最近零碎的时间都在学习Andrew Ng的machine learning,因此就有了这些笔记. 梯度下降是线性回归的一种(Line ...

  5. 转:如何查看linux版本 如何查看LINUX是多少位

    原文来自于:http://blog.csdn.net/hongweigg/article/details/7192471 一.如何得知自己正在使用的linux是什么版本呢,下面的几种方法将给你带来答案 ...

  6. PKUSC2016滚粗记

    Day0 坐飞机来北京,地铁上接到电话,以为是诈骗电话马上就挂了,然后看了一下是北京的电话,赶脚有点不对...打回去居然是报到处老师的电话..走了几个小时,到勺园和其他学校的神犇合住.TAT,感觉第二 ...

  7. SPRING-MVC访问静态文件,如jpg,js,css

    如何你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题.如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg ...

  8. Qt中添加背景图片的方法

    工作似乎走上正轨了,上周五的工作是做一个界面,用到QFrame和QPushButton,QFrame做主面板,QPushButton为其子控件,需要在主面板上贴背景图片,还需要在QPushButton ...

  9. word页面不对齐,如何解决?

    http://blog.163.com/haibianfeng_yr/blog/static/34572620201157105439516/

  10. Nodejs in Visual Studio Code 02.学习Nodejs

    1.开始 源码下载:https://github.com/sayar/NodeMVA 在线视频:https://mva.microsoft.com/en-US/training-courses/usi ...