瀑布流布局结构:
ScrollView
* ------------------------------------------------------------
* | LinearLayout (horizontal) |
* | -------------------------------------------------------- |
* | | LinearLayout LinearLayout LinearLayout | |
* | | ---------------- --------------- --------------- | |
* | | | | | | | | | |
* | | | | | | | | | |
* | | | | | | | | | |
* | | | Column1 | | Column2 | | Column3 | | |
* | | | Vertical | | Vertical | | Vertical | | |
* | | | | | | | | | |
* | | | | | | | | | |
* | | ---------------- --------------- --------------- | |
* | -------------------------------------------------------- |
* ------------------------------------------------------------
布局文件代码如下:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/scrollView" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/pool" android:orientation="horizontal" > </LinearLayout> </ScrollView>
功能实现代码如下:
1 package com.don.waterfall_test; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.ArrayList; 6 import java.util.Arrays; 7 import java.util.List; 8 9 import android.app.Activity; 10 import android.content.res.AssetManager; 11 import android.graphics.Bitmap; 12 import android.graphics.BitmapFactory; 13 import android.os.Bundle; 14 import android.view.Display; 15 import android.view.MotionEvent; 16 import android.view.View; 17 import android.view.View.OnTouchListener; 18 import android.widget.ImageView; 19 import android.widget.LinearLayout; 20 import android.widget.LinearLayout.LayoutParams; 21 import android.widget.ScrollView; 22 23 public class MainActivity extends Activity implements OnTouchListener { 24 private ScrollView scrollView; 25 private LinearLayout pool; 26 private List<LinearLayout> items_layout; //用于存放动态生成的线性布局 27 private AssetManager manager; //assets文件夹的管理器 28 private int screenWidth; //屏幕的宽度 29 private List<String> namesList; //用于存放所有图片文件的文件名 30 private int currentIndex = 0;; //表示当前页从第几 31 32 @Override 33 protected void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.activity_main); 36 37 scrollView = (ScrollView) findViewById(R.id.scrollView); 38 scrollView.setOnTouchListener(this); 39 pool = (LinearLayout) findViewById(R.id.pool); 40 41 manager = getAssets(); 42 43 Display display = getWindowManager().getDefaultDisplay(); 44 screenWidth = display.getWidth(); 45 46 createLayouts(); 47 48 getPicNameList(); 49 loadImage(currentIndex); 50 51 } 52 53 /** 54 * 动态生成三个垂直的线性布局 55 */ 56 public void createLayouts(){ 57 items_layout = new ArrayList<LinearLayout>(); 58 for(int i = 0; i < 3; i++){ 59 LinearLayout item_layout = new LinearLayout(this); 60 item_layout.setOrientation(LinearLayout.VERTICAL); 61 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth/3,android.view.ViewGroup.LayoutParams.WRAP_CONTENT); 62 item_layout.setLayoutParams(params); 63 //将该线性布局添加到pool中 64 pool.addView(item_layout); 65 //将该线性布局添加到集合中 66 items_layout.add(item_layout); 67 } 68 69 } 70 71 /** 72 * //将assets文件夹下的图片名存到集合中 73 */ 74 public void getPicNameList(){ 75 76 namesList = new ArrayList<String>(); 77 try { 78 //获取到images文件夹下所有图片的文件名数组 79 String[] names = manager.list("images"); 80 //将字符串数据转换为集合 81 namesList.addAll(Arrays.asList(names)); 82 } catch (IOException e) { 83 e.printStackTrace(); 84 } 85 86 } 87 /** 88 * 从指定索引位置处加载图片 89 * @param currentIndex 90 */ 91 public void loadImage(int index ){ 92 93 //用于一次加载的图片的文件名,一次加载9张 94 String[] paths = new String[9]; 95 for(int i = index ,j = 0; i < index +9;i++,j++){ 96 if(i >= namesList.size()){ 97 break; 98 } 99 paths[j] = namesList.get(i); 100 101 } 102 103 //获取到图片路径后,就开始加载图片 104 int count = 0; //用于计算加载的paths中的第几张图片 105 for(String fileName : paths){ 106 try { 107 //获得bitmap对象 108 InputStream is = manager.open("images/"+fileName); 109 Bitmap bitmap = BitmapFactory.decodeStream(is); 110 111 //动态创建ImageView 112 ImageView image = new ImageView(this); 113 //设置image的初始尺寸 114 LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(screenWidth/3,LinearLayout.LayoutParams.WRAP_CONTENT); 115 image.setLayoutParams(params1); 116 //为image设置默认图片 117 image.setImageResource(R.drawable.ic_launcher); 118 119 //根据bitmap的大小,重新设置image的高度 120 LayoutParams params2 = (LayoutParams) image.getLayoutParams(); 121 params2.height = params2.width * bitmap.getHeight()/bitmap.getWidth(); 122 image.setLayoutParams(params2); 123 image.setImageBitmap(bitmap); 124 125 //将image添加到垂直线性布局中 126 items_layout.get(count%3).addView(image); 127 count++; 128 129 } catch (IOException e) { 130 e.printStackTrace(); 131 } 132 } 133 } 134 135 /** 136 * 为scrollView添加触摸事件 137 */ 138 @Override 139 public boolean onTouch(View view , MotionEvent event) { 140 141 int action = event.getAction(); 142 if(action == MotionEvent.ACTION_UP){ //手指离开屏幕时加载图片 143 144 int sy = scrollView.getScrollY(); //滑出scrollView上边界的部分的高度 145 int sh = scrollView.getHeight(); //scrollView的高度 146 147 int ph = pool.getHeight(); //得到pool的高度 148 149 if(sy + sh >= ph){ 150 currentIndex += 9; 151 152 /** 153 * 方式一: 154 * 155 * 重复加载所有的图片,过多时,会发生OOM异常 156 * *//* 157 if(currentIndex >= namesList.size()){ 158 currentIndex = 0; 159 } 160 loadImage(currentIndex);*/ 161 162 163 /** 164 * 方式二: 165 * 将所有的图片只加载一次 166 */ 167 if(currentIndex < namesList.size()){ 168 loadImage(currentIndex); 169 } 170 } 171 172 } 173 return false; 174 } 175 176 }