標籤:android
效果是這個樣的:
布局思路:
最外層父表單是一個RelativeLayout(圖裡沒畫出來),從內層開始。
黑色:自訂ScrollView
紅色:LinearLayout,為了盛放內層三個布局,orientation為水平。
綠色:三個LinearLayout,用來實現散列的瀑布流效果。orientation為垂直。
間隙:實際不存在,這裡只是為了能看清結構。
布局代碼:
<com.example.stream.SV android:id="@+id/sv" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:id="@+id/ll1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" > </LinearLayout> <LinearLayout android:id="@+id/ll2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" > </LinearLayout> <LinearLayout android:id="@+id/ll3" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" > </LinearLayout> </LinearLayout> </com.example.stream.SV>
自訂ScrollView
用的是自訂ScrollView,因為原生的ScrollView沒有滑動監聽事件。用到上一篇部落格所講的自訂View,重寫onTouchEvent()方法。設定回調介面,用來分頁載入。
<span style="font-size:18px;">public class SV extends ScrollView{private OnScrollListener listener;public SV(Context context) {super(context);}public SV(Context context, AttributeSet attrs) {super(context, attrs);}<span style="color:#ff0000;">//傳進來一個介面對象public interface OnScrollListener{void loadMore();}</span><span style="color:#ff0000;">//設定滑動監聽public void setOnScrollListener(OnScrollListener listener){this.listener = listener;}</span>//手指對螢幕的觸摸事件---》監聽是否滑到底@Overridepublic boolean onTouchEvent(MotionEvent ev) {View childView = getChildAt(0);//擷取測量高度(總高度)int measuredHeight = childView.getMeasuredHeight();//擷取畫出螢幕高度int scrollY = getScrollY();//擷取可視地區int height = getHeight();<span style="white-space:pre"></span>//判斷位置if(measuredHeight==scrollY+height){Toast.makeText(getContext(), "到底了!", 0).show();listener.loadMore();}return super.onTouchEvent(ev);}}</span>
通過這樣計算來判斷ScrollView是否滑到了底部,是否可以繼續請求資料。
getHeight()+getScrollY()==getMeasureHeight();
MainActivity
注釋已經很清楚了
<span style="font-size:18px;">public class MainActivity extends Activity {private LinearLayout ll1, ll2, ll3;// 每一個ImageView的寬度,是螢幕寬度的1/3private int imgvWidth;// 每次載入多少個private int pageSize = 15;//載入次數,每載入一次,pageIndex++private int pageIndex = 0;private String[] imgName;//布局有三個,添加到數組裡,以便更新UI的時候使用。private LinearLayout lls[] = new LinearLayout[3];// 自訂ScrollView SVprivate SV sv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}private void init() {sv = (SV) findViewById(R.id.sv);// 用來盛放螢幕資訊DisplayMetrics outMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(outMetrics);//設定每個LinearLayout的寬度為整個螢幕的1/3imgvWidth = outMetrics.widthPixels / 3;ll1 = (LinearLayout) findViewById(R.id.ll1);ll2 = (LinearLayout) findViewById(R.id.ll2);ll3 = (LinearLayout) findViewById(R.id.ll3);lls[0] = ll1;lls[1] = ll2;lls[2] = ll3;try {//擷取所有檔案名稱imgName = getAssets().list("imgs");} catch (IOException e) {e.printStackTrace();}// 第一次載入圖片loadImage();//設定scrollView的滾動監聽sv.setOnScrollListener(new OnScrollListener() {@Overridepublic void loadMore() {if (pageIndex * pageSize >= imgName.length) {Toast.makeText(getApplicationContext(), "資料載入完成", 0).show();} else {loadImage();}}});}// 進行圖片載入private void loadImage() {//如果載入的數量比所有檔案個數少,每次載入15張for (int i = pageIndex * pageSize; i < pageIndex * pageSize + pageSize&& i < imgName.length; i++) {// 載入圖片,執行個體化一個ImageViewImageView imgv = new ImageView(MainActivity.this);// 寬度是螢幕的1/3LayoutParams lp = new LayoutParams(imgvWidth,LayoutParams.WRAP_CONTENT);imgv.setLayoutParams(lp);// 載入圖片資源LoadImageFromAssets.load(MainActivity.this, imgName[i], imgv);//每次往不同的LinearLayout放一個帶有圖片的ImageViewlls[i % 3].addView(imgv);}pageIndex++;}}</span>
從assets載入資料
<span style="font-size:18px;">public class LoadImageFromAssets {public static void load(final Activity activity,final String name,final ImageView iv){new Thread(){public void run(){try {//從assets/imgs裡擷取圖片資源,傳入圖片名字InputStream stream = activity.getAssets().open("imgs/"+name);final Bitmap bitmap = BitmapFactory.decodeStream(stream);//主線程更新UIactivity.runOnUiThread(new Runnable(){public void run(){//擷取圖片寬高int bitH = bitmap.getHeight();int bitW = bitmap.getWidth();//擷取LayoutParams設定寬高,使圖片填充整個ImageViewLayoutParams lp = (LayoutParams) iv.getLayoutParams();/** * 圖片的寬高比等於ImageView的寬高比,因為ImageView寬度已經確定(1/3父表單),通過計算 * 得到ImageView的高度 */lp.height = bitH*lp.width/bitW;//將參數設定到ImageViewiv.setLayoutParams(lp);iv.setImageBitmap(bitmap);}});} catch (IOException e) {e.printStackTrace();}}}.start();}}</span>
文筆不好,好多東西只有在代碼裡注釋才講的出來,部落格我會一直堅持,整理的過程中,也在思考如何寫好部落格。我在一直努力。
[android] 瀑布流布局——分頁載入(詳細代碼)