Android瀑布流

来源:互联网 发布:移动卡无法访问网络 编辑:程序博客网 时间:2024/06/11 04:35

应朋友之邀,临时改个demo,大体就这个样子,图片上层想加什么加什么,加载的是本地图片,不是网络的,但也可以拿来参考。因为不是本人现在项目用到的,改完了就不深究了,还有更重要的要忙。

关键代码:

package com.dodowaterfall;import java.io.IOException;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.List;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.res.AssetManager;import android.graphics.Rect;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.Display;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup.LayoutParams;import android.widget.LinearLayout;import com.dodowaterfall.LazyScrollView.OnScrollListener;import com.dodowaterfall.widget.FlowTag;import com.dodowaterfall.widget.FlowView;import com.dodowaterfall.widget.ImageLoaderTask;public class MainActivity extends Activity {private LazyScrollView waterfall_scroll;private LinearLayout waterfall_container;private ArrayList<LinearLayout> waterfall_items;private Display display;private AssetManager asset_manager;private List<String> image_filenames;private final String image_path = "images";private Handler handler;private int item_width;private int column_count = 3;// 显示列数private int page_count = 6;// 每次加载15张图片private int current_page = 0;// 当前页数private int[] column_height;// 每列的高度private HashMap<Integer, String> pins;private int loaded_count = 0;// 已加载数量private HashMap<Integer, Integer>[] pin_mark = null;private Context context;private HashMap<Integer, FlowView> iviews;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);display = this.getWindowManager().getDefaultDisplay();item_width = display.getWidth() / column_count;// 根据屏幕大小计算每列大小asset_manager = this.getAssets();column_height = new int[column_count];context = this.getApplicationContext();iviews = new HashMap<Integer, FlowView>();pins = new HashMap<Integer, String>();pin_mark = new HashMap[column_count];InitLayout();}private void InitLayout() {waterfall_scroll = (LazyScrollView) findViewById(R.id.waterfall_scroll);waterfall_scroll.getView();waterfall_scroll.setOnScrollListener(new OnScrollListener() {@Overridepublic void onTop() {// 滚动到最顶端Log.d("LazyScroll", "Scroll to top");}@Overridepublic void onScroll() {}@Overridepublic void onBottom() {// 滚动到最低端AddItemToContainer(++current_page, page_count);}@Overridepublic void onAutoScroll() {// 暂时解决,需重写// 自动滚动Rect bounds = new Rect();Rect scrollBounds = new Rect(waterfall_scroll.getScrollX(),waterfall_scroll.getScrollY(), waterfall_scroll.getScrollX() + waterfall_scroll.getWidth(),waterfall_scroll.getScrollY()+ waterfall_scroll.getHeight());for (int i = 1; i < loaded_count; i++) {FlowView v = iviews.get(i);if (v != null) {v.getHitRect(bounds);if (Rect.intersects(scrollBounds, bounds)) {if (v.bitmap == null) {v.Reload();}} else {v.recycle();}}}}});waterfall_container = (LinearLayout) this.findViewById(R.id.waterfall_container);handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 1:FlowView v = (FlowView) msg.obj;int w = msg.arg1;int h = msg.arg2;Log.d("MainActivity",String.format("获取实际View高度:%d,ID:%d,columnIndex:%d,rowIndex:%d,filename:%s",v.getHeight(), v.getId(), v.getColumnIndex(), v.getRowIndex(),v.getFlowTag().getFileName()));String f = v.getFlowTag().getFileName();// 此处计算列值int columnIndex = GetMinValue(column_height);v.setColumnIndex(columnIndex);column_height[columnIndex] += h;pins.put(v.getId(), f);iviews.put(v.getId(), v);break;}}@Overridepublic boolean sendMessageAtTime(Message msg, long uptimeMillis) {return super.sendMessageAtTime(msg, uptimeMillis);}};waterfall_items = new ArrayList<LinearLayout>();for (int i = 0; i < column_count; i++) {LinearLayout itemLayout = new LinearLayout(this);LinearLayout.LayoutParams itemParam = new LinearLayout.LayoutParams(item_width, LayoutParams.WRAP_CONTENT);itemLayout.setPadding(2, 2, 2, 2);itemLayout.setOrientation(LinearLayout.VERTICAL);itemLayout.setLayoutParams(itemParam);waterfall_items.add(itemLayout);waterfall_container.addView(itemLayout);}// 加载所有图片路径try {image_filenames = Arrays.asList(asset_manager.list(image_path));} catch (IOException e) {e.printStackTrace();}// 第一次加载AddItemToContainer(current_page, page_count);}private void AddItemToContainer(int pageindex, int pagecount) {int currentIndex = pageindex * pagecount;// 将废弃:按照顺序排列图片,发现问题,如果图片不均匀则会出现有的列过长有的列短的情况// 将采用根据高度最小的那列添加图片的方式int j = currentIndex % column_count;int imagecount = image_filenames.size();for (int i = currentIndex; i < pagecount * (pageindex + 1)&& i < imagecount; i++) {loaded_count++;j = j >= column_count ? j = 0 : j;AddImage(image_filenames.get(i), j++,(int) Math.ceil(loaded_count / (double) column_count),loaded_count);}}private void AddImage(String filename, int columnIndex, int rowIndex, int id) {View v= LayoutInflater.from(this).inflate(R.layout.waterfallitem, null);/*FlowView item = (FlowView) LayoutInflater.from(this).inflate(R.layout.waterfallitem, null);*/FlowView item= (FlowView)v.findViewById(R.id.waterfall_image);item.setColumnIndex(columnIndex);item.setRowIndex(rowIndex);item.setId(id);item.setViewHandler(this.handler);// 多线程参数FlowTag param = new FlowTag();param.setFlowId(id);param.setAssetManager(asset_manager);param.setFileName(image_path + "/" + filename);param.setItemWidth(item_width);item.setFlowTag(param);item.LoadImage();//waterfall_items.get(columnIndex).addView(item);waterfall_items.get(columnIndex).addView(v);ImageLoaderTask task = new ImageLoaderTask(item);item.setTag(filename);item.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setClass(MainActivity.this, sActivity.class);Bundle b = new Bundle();b.putString("fileName", (String) v.getTag());intent.putExtras(b);startActivity(intent);}});task.execute(param);}private int GetMinValue(int[] array) {int m = 0;int length = array.length;for (int i = 0; i < length; ++i) {if (array[i] < array[m]) {m = i;}}return m;}}

package com.dodowaterfall.widget;import java.io.BufferedInputStream;import java.io.IOException;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.AnimationDrawable;import android.widget.ImageView;import android.widget.ScrollView;import android.widget.Toast;import android.os.Handler;import android.os.Message;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup.LayoutParams;public class FlowView extends ImageView implements View.OnClickListener,View.OnLongClickListener {private AnimationDrawable loadingAnimation;private FlowTag flowTag;private Context context;public Bitmap bitmap;private ImageLoaderTask task;private int columnIndex;// 图片属于第几列private int rowIndex;// 图片属于第几行private Handler viewHandler;public FlowView(Context c, AttributeSet attrs, int defStyle) {super(c, attrs, defStyle);this.context = c;Init();}public FlowView(Context c, AttributeSet attrs) {super(c, attrs);this.context = c;Init();}public FlowView(Context c) {super(c);this.context = c;Init();}private void Init() {setOnClickListener(this);this.setOnLongClickListener(this);setAdjustViewBounds(true);}@Overridepublic boolean onLongClick(View v) {Log.d("FlowView", "LongClick");Toast.makeText(context, "长按:" + this.flowTag.getFlowId(),Toast.LENGTH_SHORT).show();return true;}@Overridepublic void onClick(View v) {Log.d("FlowView", "Click");Toast.makeText(context, "单击:" + this.flowTag.getFlowId(),Toast.LENGTH_SHORT).show();}/** * 加载图片 */public void LoadImage() {if (getFlowTag() != null) {new LoadImageThread().start();}}/** * 重新加载图片 */public void Reload() {if (this.bitmap == null && getFlowTag() != null) {new LoadImageThread().start();}}/** * 回收内存 */public void recycle() {setImageBitmap(null);if ((this.bitmap == null) || (this.bitmap.isRecycled()))return;this.bitmap.recycle();this.bitmap = null;}public FlowTag getFlowTag() {return flowTag;}public void setFlowTag(FlowTag flowTag) {this.flowTag = flowTag;}public int getColumnIndex() {return columnIndex;}public void setColumnIndex(int columnIndex) {this.columnIndex = columnIndex;}public int getRowIndex() {return rowIndex;}public void setRowIndex(int rowIndex) {this.rowIndex = rowIndex;}public Handler getViewHandler() {return viewHandler;}public FlowView setViewHandler(Handler viewHandler) {this.viewHandler = viewHandler;return this;}class LoadImageThread extends Thread {LoadImageThread() {}public void run() {if (flowTag != null) {BufferedInputStream buf;try {buf = new BufferedInputStream(flowTag.getAssetManager().open(flowTag.getFileName()));bitmap = BitmapFactory.decodeStream(buf);} catch (IOException e) {e.printStackTrace();}// 此处不能直接更新UI,否则会发生异常:// CalledFromWrongThreadException: Only the original thread that// created a view hierarchy can touch its views.// 也可以使用Handler或者Looper发送Message解决这个问题((Activity) context).runOnUiThread(new Runnable() {public void run() {if (bitmap != null){// 此处在线程过多时可能为nullint width = bitmap.getWidth();// 获取真实宽高int height = bitmap.getHeight();LayoutParams lp = getLayoutParams();lp.height = (height * flowTag.getItemWidth())/ width;// 调整高度setLayoutParams(lp);setImageBitmap(bitmap);// 将引用指定到同一个对象,方便销毁Handler h = getViewHandler();Message m = h.obtainMessage(flowTag.what, width,height, FlowView.this);h.sendMessage(m);}}});}}}}

源码:http://download.csdn.net/detail/djun100/6023043