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


Android 轉載分享(10) 

我們還是來看一款示例:(蘑菇街)  

                

 看起來很像我們的gridview吧,不過又不像,因為item大小不固定的,看起來是不是別有一番風味,確實如此.就如我們的方角圖形,斯通見慣后也就出現了圓角.下面我簡單介紹下實現方法.

第一種:

我們在配置文件中定義好列數.如上圖也就是3列.我們需要定義三個LinearLayout,然后把獲取到的圖片add里面就ok了.

main.xml

 

[java]  view plain copy
 
 
 
  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 plain copy
 
 
 
  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 plain copy
 
 
 
  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 plain copy
 
 
 
  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 plain copy
 
 
 
  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 plain copy
 
 
 
  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 plain copy
 
 
 
  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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM