android 瀑布流(图片浏览)
效果图:

瀑流流实现涉及的知识点
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 瀑布流(图片浏览)的更多相关文章
- 转载—— android 瀑布流的实现详解,附源码
介绍 参考自:https://github.com/dodola/android_waterfall,因为原来的代码封装不好,所以,我根据源码的思路,重新写了一遍,所以有了现在这个项目:https:/ ...
- 用原生JavaScript实现图片瀑布流的浏览效果
学习JS,活跃思维,灵活运用的一个较为典型的学习案例.同一个瀑布流的效果但实现方式却很多,利用递归.冒泡等等手法都可以达到你想要的目的.这次要说的就是利用类似递归来实现此效果的原创方案.此方案个人认为 ...
- Android瀑布流优化,解决Recyclerview展示大批量图片时Item自动切换、闪烁、空白等问题
本文涉及的代码案例可以在下方的链接中找到,如果对你有帮助,请给个Star(#^.^#) https://github.com/CodeTillDoom/StaggeredRcl 问题分析 这段时间业务 ...
- Android瀑布流照片墙实现,体验不规则排列的美感
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/10470797 传统界面的布局方式总是行列分明.坐落有序的,这种布局已是司空见惯,在 ...
- RecyclerView 制作瀑布流图片
这是瀑布流的效果图 RecyclerView(ListView的升级版) 加载图片用的是第三方图片加载框架 ------------------------------------- 在Xml中 &l ...
- android 瀑布流
我们还是来看一款示例: 看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出现了圆角.下面我简单介绍下实现 ...
- android瀑布流效果(仿蘑菇街)
Android 转载分享(10) 我们还是来看一款示例:(蘑菇街) 看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此. ...
- android 瀑布流效果(仿蘑菇街)
我们还是来看一款示例:(蘑菇街) 看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出 ...
- Android瀑布流照片
http://blog.csdn.net/guolin_blog/article/details/10470797 记得我在之前已经写过一篇关于如何在Android上实现照片墙功能的文章了,但那个时候 ...
随机推荐
- HDU 1005(周期问题)
HDU 1005 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descript ...
- 禁用ios7 手势滑动返回功能
禁用ios7 手势滑动返回功能 版权声明:本文为博主原创文章,未经博主允许不得转载. 在有的时候,我们不需要手势返回功能,那么可以在页面中添加以下代码: - (void)viewDidAppear:( ...
- C#程序设计基础——转义字符
\’ 单引号 \” 双引号 \\ 反斜杠 \0 空字符 \a 感叹号 \b 退格 \f 换页 \n 换行 \r 回车 \t 水平Tab \v 垂直Tab
- INDEX RANG SCAN无需回表的情况
create table a3 as select * from dba_objects create index a3_idx1 on a3(owner); select owner from a3 ...
- Hadoop InputFormat
Hadoop可以处理不同数据格式(数据源)的数据,从文本文件到(非)关系型数据库,这很大程度上得益于Hadoop InputFormat的可扩展性设计,InputFormat层次结构图如下:
- 【二分】XMU 1587 中位数
题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1587 题目大意: 求两个长度为n(n<=109)的有序序列合并后的中位数.序列中 ...
- HDOJ 2114 Calculate S(n)(找周期)
Problem Description Calculate S(n). S(n)=1^3+2^3 +3^3 +--+n^3 . Input Each line will contain one int ...
- Java学习日记-2.3 基本数据类型和对象所占内存空间大小
转自:http://www.newsmth.net/nForum/#!article/Java/324167
- TreeSet具体应用
知识是用来运用的,一辈子用不上的等于没学,学了忘了的等于没学,学了不会用的等于没学 //TreeSetDemo2.java package saturday2; import java.util.Ha ...
- jquery and js 判断一个元素是否存在
一.javascript中判断一个元素是否存在 if(document.getElementById('example')){ // do sth } 二.jquery中判断一个元素是否存在 < ...