zoukankan      html  css  js  c++  java
  • android瀑布流效果(仿蘑菇街)

    Android 转载分享(10) 

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

                    

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

    第一种:

    我们在配置文件中定义好列数.如上图也就是3列.我们需要定义三个LinearLayout,然后把获取到的图片add里面就ok了.

    main.xml

    [java] view plaincopy
     
     
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="fill_parent"  
    5.     android:background="@android:color/background_light"  
    6.     android:orientation="vertical" >  
    7.   
    8.     <include  
    9.         android:id="@+id/progressbar"  
    10.         layout="@layout/loading" />  
    11.   
    12.     <com.jj.waterfall.LazyScrollView  
    13.         android:id="@+id/lazyscrollview"  
    14.         android:layout_width="fill_parent"  
    15.         android:layout_height="fill_parent"  
    16.         android:layout_weight="1"  
    17.         android:scrollbars="@null" >  
    18.   
    19.         <LinearLayout  
    20.             android:layout_width="fill_parent"  
    21.             android:layout_height="fill_parent"  
    22.             android:background="@android:color/background_light"  
    23.             android:orientation="horizontal"  
    24.             android:padding="2dp" >  
    25.   
    26.             <LinearLayout  
    27.                 android:id="@+id/layout01"  
    28.                 android:layout_width="fill_parent"  
    29.                 android:layout_height="fill_parent"  
    30.                 android:layout_weight="1"  
    31.                 android:orientation="vertical" >  
    32.             </LinearLayout>  
    33.   
    34.             <LinearLayout  
    35.                 android:id="@+id/layout02"  
    36.                 android:layout_width="fill_parent"  
    37.                 android:layout_height="fill_parent"  
    38.                 android:layout_weight="1"  
    39.                 android:orientation="vertical" >  
    40.             </LinearLayout>  
    41.   
    42.             <LinearLayout  
    43.                 android:id="@+id/layout03"  
    44.                 android:layout_width="fill_parent"  
    45.                 android:layout_height="fill_parent"  
    46.                 android:layout_weight="1"  
    47.                 android:orientation="vertical" >  
    48.             </LinearLayout>  
    49.         </LinearLayout>  
    50.     </com.jj.waterfall.LazyScrollView>  
    51.   
    52.     <TextView  
    53.         android:id="@+id/loadtext"  
    54.         android:layout_width="fill_parent"  
    55.         android:layout_height="wrap_content"  
    56.         android:background="@drawable/loading_bg"  
    57.         android:gravity="center"  
    58.         android:padding="10dp"  
    59.         android:text="Loading..."  
    60.         android:textColor="@android:color/background_dark" />  
    61.   
    62. </LinearLayout>  

    在这里因为图片很多就把图片放在assets文件中,如果想从网上拉取数据,自己写额外部分.

    [java] view plaincopy
     
     
     
    1. @Override  
    2.     public void onCreate(Bundle savedInstanceState) {  
    3.         super.onCreate(savedInstanceState);  
    4.         InitView();  
    5.   
    6.         assetManager = this.getAssets();  
    7.         // 获取显示图片宽度  
    8.         Image_width = (getWindowManager().getDefaultDisplay().getWidth() - 4) / 3;  
    9.         try {  
    10.             image_filenames = Arrays.asList(assetManager.list("images"));// 获取图片名称  
    11.         } catch (IOException e) {  
    12.             e.printStackTrace();  
    13.         }  
    14.   
    15.         addImage(current_page, count);  
    16.   
    17.     }  
    [java] view plaincopy
     
     
     
    1. /*** 
    2.      * 加载更多 
    3.      *  
    4.      * @param current_page 
    5.      *            当前页数 
    6.      * @param count 
    7.      *            每页显示个数 
    8.      */  
    9.     private void addImage(int current_page, int count) {  
    10.         for (int x = current_page * count; x < (current_page + 1) * count  
    11.                 && x < image_filenames.size(); x++) {  
    12.             addBitMapToImage(image_filenames.get(x), y, x);  
    13.             y++;  
    14.             if (y >= 3)  
    15.                 y = 0;  
    16.         }  
    17.   
    18.     }  



    [java] view plaincopy
     
     
     
    1. /*** 
    2.      * 添加imageview 到layout 
    3.      *  
    4.      * @param imagePath 图片name 
    5.      * @param j 列 
    6.      * @param i 行 
    7.      */  
    8.     public void addBitMapToImage(String imagePath, int j, int i) {  
    9.         ImageView imageView = getImageview();  
    10.         asyncTask = new ImageDownLoadAsyncTask(this, imagePath, imageView,  
    11.                 Image_width);  
    12.         asyncTask.setProgressbar(progressbar);  
    13.         asyncTask.setLoadtext(loadtext);  
    14.         asyncTask.execute();  
    15.   
    16.         imageView.setTag(i);  
    17.         if (j == 0) {  
    18.             layout01.addView(imageView);  
    19.         } else if (j == 1) {  
    20.             layout02.addView(imageView);  
    21.         } else if (j == 2) {  
    22.             layout03.addView(imageView);  
    23.         }  
    24.   
    25.         imageView.setOnClickListener(new OnClickListener() {  
    26.   
    27.             @Override  
    28.             public void onClick(View v) {  
    29.                 Toast.makeText(MainActivity.this,  
    30.                         "您点击了" + v.getTag() + "个Item", Toast.LENGTH_SHORT)  
    31.                         .show();  
    32.   
    33.             }  
    34.         });  
    35.     }  

    注释已经很明确,相信大家都看的明白,我就不过多解释了.

    因为瀑布流不是一个规则的试图,所以我们不可能用listview那种“底部加一个按钮试图,点击加载更多,这样看起来很难看”。因此我们最好滑动到低端自动加载.

    我们这里用到的自定义ScrollView,因为我们要实现下滑分页,这里要判断是否要进行分页等操作.

    LazyScrollView.Java (这个法很实用哦.)

    [java] view plaincopy
     
     
     
    1. /*** 
    2.  * 自定义ScrollView 
    3.  *  
    4.  * @author zhangjia 
    5.  *  
    6.  */  
    7. public class LazyScrollView extends ScrollView {  
    8.     private static final String tag = "LazyScrollView";  
    9.     private Handler handler;  
    10.     private View view;  
    11.   
    12.     public LazyScrollView(Context context) {  
    13.         super(context);  
    14.     }  
    15.   
    16.     public LazyScrollView(Context context, AttributeSet attrs) {  
    17.         super(context, attrs);  
    18.     }  
    19.   
    20.     public LazyScrollView(Context context, AttributeSet attrs, int defStyle) {  
    21.         super(context, attrs, defStyle);  
    22.     }  
    23.   
    24.     // 这个获得总的高度  
    25.     public int computeVerticalScrollRange() {  
    26.         return super.computeHorizontalScrollRange();  
    27.     }  
    28.   
    29.     public int computeVerticalScrollOffset() {  
    30.         return super.computeVerticalScrollOffset();  
    31.     }  
    32.   
    33.     /*** 
    34.      * 初始化 
    35.      */  
    36.     private void init() {  
    37.   
    38.         this.setOnTouchListener(onTouchListener);  
    39.         handler = new Handler() {  
    40.             @Override  
    41.             public void handleMessage(Message msg) {  
    42.                 // process incoming messages here  
    43.                 super.handleMessage(msg);  
    44.                 switch (msg.what) {  
    45.                 case 1:  
    46.                     if (view.getMeasuredHeight() <= getScrollY() + getHeight()) {  
    47.                         if (onScrollListener != null) {  
    48.                             onScrollListener.onBottom();  
    49.                         }  
    50.   
    51.                     } else if (getScrollY() == 0) {  
    52.                         if (onScrollListener != null) {  
    53.                             onScrollListener.onTop();  
    54.                         }  
    55.                     } else {  
    56.                         if (onScrollListener != null) {  
    57.                             onScrollListener.onScroll();  
    58.                         }  
    59.                     }  
    60.                     break;  
    61.                 default:  
    62.                     break;  
    63.                 }  
    64.             }  
    65.         };  
    66.   
    67.     }  
    68.   
    69.     OnTouchListener onTouchListener = new OnTouchListener() {  
    70.   
    71.         @Override  
    72.         public boolean onTouch(View v, MotionEvent event) {  
    73.             // TODO Auto-generated method stub  
    74.             switch (event.getAction()) {  
    75.             case MotionEvent.ACTION_DOWN:  
    76.                 break;  
    77.             case MotionEvent.ACTION_UP:  
    78.                 if (view != null && onScrollListener != null) {  
    79.                     handler.sendMessageDelayed(handler.obtainMessage(1), 200);  
    80.                 }  
    81.                 break;  
    82.   
    83.             default:  
    84.                 break;  
    85.             }  
    86.             return false;  
    87.         }  
    88.   
    89.     };  
    90.   
    91.     /** 
    92.      * 获得参考的View,主要是为了获得它的MeasuredHeight,然后和滚动条的ScrollY+getHeight作比较。 
    93.      */  
    94.     public void getView() {  
    95.         this.view = getChildAt(0);  
    96.         if (view != null) {  
    97.             init();  
    98.         }  
    99.     }  
    100.   
    101.     /** 
    102.      * 定义接口 
    103.      *  
    104.      * @author admin 
    105.      *  
    106.      */  
    107.     public interface OnScrollListener {  
    108.         void onBottom();  
    109.   
    110.         void onTop();  
    111.   
    112.         void onScroll();  
    113.     }  
    114.   
    115.     private OnScrollListener onScrollListener;  
    116.   
    117.     public void setOnScrollListener(OnScrollListener onScrollListener) {  
    118.         this.onScrollListener = onScrollListener;  
    119.     }  
    我们还需要一个类,异步加载实现,我想有开发经验的朋友一定用过好多次了,这里就不展示代码了,想看的朋友,可以点击下载(如果认为还不错的话,请您一定要表示一下哦.)

    对了,忘记一点,我们还需要对MainActivity 中的lazyScrollView实现OnScrollListener接口,对滑动到底部进行监听.

    效果图:

    /**************************************************************************/

    下面我介绍另外一种做法:(相对上面更灵活)

    我们动态添加列.

    配置文件就不贴了,和上面那例子一样,只不过里面值包含一个LinearLayout布局.

    在这里我们动态添加列布局.

    [java] view plaincopy
     
     
     
    1. /*** 
    2.      * init view 
    3.      */  
    4.     public void initView() {  
    5.         setContentView(R.layout.main);  
    6.         lazyScrollView = (LazyScrollView) findViewById(R.id.waterfall_scroll);  
    7.         lazyScrollView.getView();  
    8.         lazyScrollView.setOnScrollListener(this);  
    9.         waterfall_container = (LinearLayout) findViewById(R.id.waterfall_container);  
    10.         progressbar = (LinearLayout) findViewById(R.id.progressbar);  
    11.         loadtext = (TextView) findViewById(R.id.loadtext);  
    12.   
    13.         item_width = getWindowManager().getDefaultDisplay().getWidth() / column;  
    14.         linearLayouts = new ArrayList<LinearLayout>();  
    15.   
    16.         // 添加列到waterfall_container  
    17.         for (int i = 0; i < column; i++) {  
    18.             LinearLayout layout = new LinearLayout(this);  
    19.             LinearLayout.LayoutParams itemParam = new LinearLayout.LayoutParams(  
    20.                     item_width, LayoutParams.WRAP_CONTENT);  
    21.             layout.setOrientation(LinearLayout.VERTICAL);  
    22.             layout.setLayoutParams(itemParam);  
    23.             linearLayouts.add(layout);  
    24.             waterfall_container.addView(layout);  
    25.         }  
    26.   
    27.     }  
    [java] view plaincopy
     
     
     
    1. /*** 
    2.      * 获取imageview 
    3.      *  
    4.      * @param imageName 
    5.      * @return 
    6.      */  
    7.     public ImageView getImageview(String imageName) {  
    8.         BitmapFactory.Options options = getBitmapBounds(imageName);  
    9.         // 创建显示图片的对象  
    10.         ImageView imageView = new ImageView(this);  
    11.         LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,  
    12.                 LayoutParams.FILL_PARENT);  
    13.         imageView.setLayoutParams(layoutParams);  
    14.         //  
    15.         imageView.setMinimumHeight(options.outHeight);  
    16.         imageView.setMinimumWidth(options.outWidth);  
    17.         imageView.setPadding(2, 0, 2, 2);  
    18.         imageView.setBackgroundResource(R.drawable.image_border);  
    19.         if (options != null)  
    20.             options = null;  
    21.         return imageView;  
    22.     }  
    23.   
    24.     /*** 
    25.      *  
    26.      * 获取相应图片的 BitmapFactory.Options 
    27.      */  
    28.     public BitmapFactory.Options getBitmapBounds(String imageName) {  
    29.         int h, w;  
    30.         BitmapFactory.Options options = new BitmapFactory.Options();  
    31.         options.inJustDecodeBounds = true;// 只返回bitmap的大小,可以减少内存使用,防止OOM.  
    32.         InputStream is = null;  
    33.         try {  
    34.             is = assetManager.open(file + "/" + imageName);  
    35.         } catch (IOException e) {  
    36.             e.printStackTrace();  
    37.         }  
    38.         BitmapFactory.decodeStream(is, null, options);  
    39.         return options;  
    40.   
    41.     }  

    在这里我稍微修改了下,为要显示的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

     
  • 相关阅读:
    第三次作业
    第二次作业
    第一次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    随笔
    第五次作业
    第四次作业
  • 原文地址:https://www.cnblogs.com/xgjblog/p/5461129.html
Copyright © 2011-2022 走看看