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

我们还是来看一款示例:(蘑菇街)

看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出现了圆角.下面我简单介绍下实现方法.
第一种:
我们在配置文件中定义好列数.如上图也就是3列.我们需要定义三个LinearLayout,然后把获取到的图片add里面就ok了.
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/background_light"
- android:orientation="vertical" >
- <include
- android:id="@+id/progressbar"
- layout="@layout/loading" />
- <com.jj.waterfall.LazyScrollView
- android:id="@+id/lazyscrollview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:scrollbars="@null" >
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/background_light"
- android:orientation="horizontal"
- android:padding="2dp" >
- <LinearLayout
- android:id="@+id/layout01"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:orientation="vertical" >
- </LinearLayout>
- <LinearLayout
- android:id="@+id/layout02"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:orientation="vertical" >
- </LinearLayout>
- <LinearLayout
- android:id="@+id/layout03"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:orientation="vertical" >
- </LinearLayout>
- </LinearLayout>
- </com.jj.waterfall.LazyScrollView>
- <TextView
- android:id="@+id/loadtext"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/loading_bg"
- android:gravity="center"
- android:padding="10dp"
- android:text="Loading..."
- android:textColor="@android:color/background_dark" />
- </LinearLayout>
在这里因为图片很多就把图片放在assets文件中,如果想从网上拉取数据,自己写额外部分.
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- InitView();
- assetManager = this.getAssets();
- // 获取显示图片宽度
- Image_width = (getWindowManager().getDefaultDisplay().getWidth() - 4) / 3;
- try {
- image_filenames = Arrays.asList(assetManager.list("images"));// 获取图片名称
- } catch (IOException e) {
- e.printStackTrace();
- }
- addImage(current_page, count);
- }
- /***
- * 加载更多
- *
- * @param current_page
- * 当前页数
- * @param count
- * 每页显示个数
- */
- private void addImage(int current_page, int count) {
- for (int x = current_page * count; x < (current_page + 1) * count
- && x < image_filenames.size(); x++) {
- addBitMapToImage(image_filenames.get(x), y, x);
- y++;
- if (y >= 3)
- y = 0;
- }
- }
- /***
- * 添加imageview 到layout
- *
- * @param imagePath 图片name
- * @param j 列
- * @param i 行
- */
- public void addBitMapToImage(String imagePath, int j, int i) {
- ImageView imageView = getImageview();
- asyncTask = new ImageDownLoadAsyncTask(this, imagePath, imageView,
- Image_width);
- asyncTask.setProgressbar(progressbar);
- asyncTask.setLoadtext(loadtext);
- asyncTask.execute();
- imageView.setTag(i);
- if (j == 0) {
- layout01.addView(imageView);
- } else if (j == 1) {
- layout02.addView(imageView);
- } else if (j == 2) {
- layout03.addView(imageView);
- }
- imageView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Toast.makeText(MainActivity.this,
- "您点击了" + v.getTag() + "个Item", Toast.LENGTH_SHORT)
- .show();
- }
- });
- }
注释已经很明确,相信大家都看的明白,我就不过多解释了.
因为瀑布流不是一个规则的试图,所以我们不可能用listview那种“底部加一个按钮试图,点击加载更多,这样看起来很难看”。因此我们最好滑动到低端自动加载.
我们这里用到的自定义ScrollView,因为我们要实现下滑分页,这里要判断是否要进行分页等操作.
LazyScrollView.Java (这个法很实用哦.)
- /***
- * 自定义ScrollView
- *
- * @author zhangjia
- *
- */
- public class LazyScrollView extends ScrollView {
- private static final String tag = "LazyScrollView";
- private Handler handler;
- private View view;
- public LazyScrollView(Context context) {
- super(context);
- }
- public LazyScrollView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public LazyScrollView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- // 这个获得总的高度
- public int computeVerticalScrollRange() {
- return super.computeHorizontalScrollRange();
- }
- public int computeVerticalScrollOffset() {
- return super.computeVerticalScrollOffset();
- }
- /***
- * 初始化
- */
- private void init() {
- this.setOnTouchListener(onTouchListener);
- handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // process incoming messages here
- super.handleMessage(msg);
- switch (msg.what) {
- case 1:
- if (view.getMeasuredHeight() <= getScrollY() + getHeight()) {
- if (onScrollListener != null) {
- onScrollListener.onBottom();
- }
- } else if (getScrollY() == 0) {
- if (onScrollListener != null) {
- onScrollListener.onTop();
- }
- } else {
- if (onScrollListener != null) {
- onScrollListener.onScroll();
- }
- }
- break;
- default:
- break;
- }
- }
- };
- }
- OnTouchListener onTouchListener = new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // TODO Auto-generated method stub
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- break;
- case MotionEvent.ACTION_UP:
- if (view != null && onScrollListener != null) {
- handler.sendMessageDelayed(handler.obtainMessage(1), 200);
- }
- break;
- default:
- break;
- }
- return false;
- }
- };
- /**
- * 获得参考的View,主要是为了获得它的MeasuredHeight,然后和滚动条的ScrollY+getHeight作比较。
- */
- public void getView() {
- this.view = getChildAt(0);
- if (view != null) {
- init();
- }
- }
- /**
- * 定义接口
- *
- * @author admin
- *
- */
- public interface OnScrollListener {
- void onBottom();
- void onTop();
- void onScroll();
- }
- private OnScrollListener onScrollListener;
- public void setOnScrollListener(OnScrollListener onScrollListener) {
- this.onScrollListener = onScrollListener;
- }
我们还需要一个类,异步加载实现,我想有开发经验的朋友一定用过好多次了,这里就不展示代码了,想看的朋友,可以点击下载(如果认为还不错的话,请您一定要表示一下哦.)
对了,忘记一点,我们还需要对MainActivity 中的lazyScrollView实现OnScrollListener接口,对滑动到底部进行监听.
效果图:

/**************************************************************************/
下面我介绍另外一种做法:(相对上面更灵活)
我们动态添加列.
配置文件就不贴了,和上面那例子一样,只不过里面值包含一个LinearLayout布局.
在这里我们动态添加列布局.
- /***
- * init view
- */
- public void initView() {
- setContentView(R.layout.main);
- lazyScrollView = (LazyScrollView) findViewById(R.id.waterfall_scroll);
- lazyScrollView.getView();
- lazyScrollView.setOnScrollListener(this);
- waterfall_container = (LinearLayout) findViewById(R.id.waterfall_container);
- progressbar = (LinearLayout) findViewById(R.id.progressbar);
- loadtext = (TextView) findViewById(R.id.loadtext);
- item_width = getWindowManager().getDefaultDisplay().getWidth() / column;
- linearLayouts = new ArrayList<LinearLayout>();
- // 添加列到waterfall_container
- for (int i = 0; i < column; i++) {
- LinearLayout layout = new LinearLayout(this);
- LinearLayout.LayoutParams itemParam = new LinearLayout.LayoutParams(
- item_width, LayoutParams.WRAP_CONTENT);
- layout.setOrientation(LinearLayout.VERTICAL);
- layout.setLayoutParams(itemParam);
- linearLayouts.add(layout);
- waterfall_container.addView(layout);
- }
- }
- /***
- * 获取imageview
- *
- * @param imageName
- * @return
- */
- public ImageView getImageview(String imageName) {
- BitmapFactory.Options options = getBitmapBounds(imageName);
- // 创建显示图片的对象
- ImageView imageView = new ImageView(this);
- LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.FILL_PARENT);
- imageView.setLayoutParams(layoutParams);
- //
- imageView.setMinimumHeight(options.outHeight);
- imageView.setMinimumWidth(options.outWidth);
- imageView.setPadding(2, 0, 2, 2);
- imageView.setBackgroundResource(R.drawable.image_border);
- if (options != null)
- options = null;
- return imageView;
- }
- /***
- *
- * 获取相应图片的 BitmapFactory.Options
- */
- public BitmapFactory.Options getBitmapBounds(String imageName) {
- int h, w;
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;// 只返回bitmap的大小,可以减少内存使用,防止OOM.
- InputStream is = null;
- try {
- is = assetManager.open(file + "/" + imageName);
- } catch (IOException e) {
- e.printStackTrace();
- }
- BitmapFactory.decodeStream(is, null, options);
- return options;
- }
在这里我稍微修改了下,为要显示的iamgeview添加一个边框,这样看起来效果不错,我们动态滑动的同时, 然后图片陆续的填充边框.蘑菇街就是这种效果哦.
效果图:

显示成4列,因此图片有点小,仔细看的话,你应该可以看到有好多边框,然后图片陆续的填充边框.这种效果感觉对上面那个用户体验更友好些.
最后简单总结下:针对瀑布流最好使用第二种方法,这种可扩展性比较大,哪天老大说四列太丑了,改成三列,那么我们只需要把column改成3就ok了,简单吧。
注意:由于图片量太多,占用空间太大,因此我将图片上传到网上,获取源码的同学下载该文件放到项目的assets文件夹下,然后运行就ok了.
如果有不足之处,请留言指出,
想要源码请留邮箱.Thanks for you 。
由于比较繁忙,我将源码上传网上,如有需要,自行下载,如有问题,请留言.(记得下载图片导入项目里面)
哈哈,如果对您又帮助的话,记得赞一个哦.
原帖地址:http://blog.csdn.net/jj120522/article/details/8022545
另一个开源框架(EOE):http://www.eoeandroid.com/thread-157448-1-1.html
android瀑布流效果(仿蘑菇街)的更多相关文章
- android 瀑布流效果(仿蘑菇街)
我们还是来看一款示例:(蘑菇街) 看起来很像我们的gridview吧,不过又不像,因为item大小不固定的,看起来是不是别有一番风味,确实如此.就如我们的方角图形,斯通见惯后也就出 ...
- android 瀑布流效果 保存地址
http://tech.ddvip.com/2013-09/1379785198203013_2.html
- Android UI 之WaterFall瀑布流效果
所谓瀑布流效果,简单说就是宽度相同但是高度不同的一大堆图片,分成几列,然后像水流一样向下排列,并随着用户的上下滑动自动加载更多的图片内容. 语言描述比较抽象,具体效果看下面的截图: ...
- [Android Pro] RecyclerView实现瀑布流效果(二)
referece to : http://blog.csdn.net/u010687392 在上篇中我们知道RecyclerView中默认给我们提供了三种布局管理器,分别是LinearLayoutMa ...
- RecylerView完美实现瀑布流效果
RecylerView包含三种布局管理器,分别是LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager,对应实现单行列表,多行 ...
- RecyclerView实现瀑布流效果(图文详解+源码奉送)
最近有时间研究了一下RecyclerView,果然功能强大啊,能实现的效果还是比较多的,那么今天给大家介绍一个用RecyclerView实现的瀑布流效果. 先来一张效果图: 看看怎么实现吧: 整体工程 ...
- 【前端】用jQuery实现瀑布流效果
jQuery实现瀑布流效果 何为瀑布流: 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早 ...
- javascript瀑布流效果
javascript瀑布流效果 其实javascript瀑布流 前几年都已经很流行了(特别是美丽说,蘑菇街),最近看到网上有人问这个瀑布流效果,所以自己有空的时候就研究了下,其实也是研究别人的代码,研 ...
- 实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性、网格、瀑布流效果演示
实现RecyclerView下拉刷新和上拉加载更多以及RecyclerView线性.网格.瀑布流效果演示 效果预览 实例APP 小米应用商店 使用方法 build.gradle文件 dependenc ...
随机推荐
- 【转】用 SVN Importer 实现 CSVNT 到 SVN 的转换
转载地址:http://www.blogjava.net/yongbing/archive/2007/03/04/101761.html 用 SVN Importer 实现 CSVNT 到 SVN 的 ...
- Zend Studio集成Xdebug断点调试详解
转自:http://www.softown.cn/post/115.html Xdebug是PHP开发中两个常用的断点调试工具之一(另一个为Zend Debugger). 现在,我们在Zend Stu ...
- libevent安装及使用
一.安装libevent 官网:http://libevent.org/ 选择最新版本下载,我选择的是libevent-2.0.22-stable.tar.gz,然后安装README文件中描述的方法编 ...
- Java中通过JDBC远程连接Oracle数据库
通过jdbc连接数据库,拢共分三步: 第一步:下载一个JDBC的驱动,然后把jar包扔到项目里并add to build path: 第二步:去本地oracle文件夹下找到“TNSNAMES.ORA” ...
- Java程序员必备的6款最佳开发工具
工欲善其事,必先利其器.每一个Java程序员都有其惯用的工具组件.对于Java程序员,各种有用的软件和工具泛滥成灾.初级开发人员要么找不到合适的工具,要么在寻找过程中浪费了大量的时间.下面,我将为大家 ...
- Session对象实例
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- FZU 2151 OOXX Game
OOXX Game Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit St ...
- 昂贵的聘礼 Dijkstra法
poj 1062 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 39437 Accepted: 11432 Descri ...
- Checking For User Permissions Before Updating or Inserting The Records in Oracle Forms
Suppose you want to check the user permissions on inserting or updating the records in Oracle Forms, ...
- [Python]解决python链式extend的技巧
众所周知python中的list是可以extend的,功能 旨在将两个list合并成一个.譬如[1,2,3].extend([4,5,6])=[1,2,3,4,5,6] 假如有一个list的list, ...