DodoWaterFall实现了类似于迷尚android和蘑菇街android的瀑布流布局。
项目如图:
效果如图:
项目总共五个目标文件!~
LazyScrollView类:可以上下滚动的视图。
MainActivity类:主界面类。
FlowTag类:图片信息标识。
FlowView类:图片视图 ,可以使用线程加载图片或ImageLoaderTask加载图片。
ImageLoaderTask类:同步任务方式加载图片。
主要成员:
//上下滚动的视图 private LazyScrollView waterfall_scroll; //容器 private LinearLayout waterfall_container; //包含容器的队列 private ArrayList<LinearLayout> waterfall_items;
//图片视图对应的哈希表 private HashMap<Integer, FlowView> iviews;
//初始化布局 把循环加入图片,然后加入到容器、最后加入到容器队列 private void InitLayout() { waterfall_scroll = (LazyScrollView) findViewById(R.id.waterfall_scroll); waterfall_scroll.getView(); waterfall_scroll.setOnScrollListener(new OnScrollListener() { @Override public void onTop() { // 滚动到最顶端 Log.d("LazyScroll", "Scroll to top"); } @Override public void onScroll() { } @Override public void onBottom() { // 滚动到最低端 AddItemToContainer(++current_page, page_count); } @Override public void onAutoScroll(int l, int t, int oldl, int oldt) { // Log.d("MainActivity", // String.format("%d %d %d %d", l, t, oldl, oldt)); // Log.d("MainActivity", "range:" + range); // Log.d("MainActivity", "range-t:" + (range - t)); scroll_height = waterfall_scroll.getMeasuredHeight(); Log.d("MainActivity", "scroll_height:" + scroll_height); if (t > oldt) {// 向下滚动 if (t > 2 * scroll_height) {// 超过两屏幕后 for (int k = 0; k < column_count; k++) { LinearLayout localLinearLayout = waterfall_items .get(k); if (pin_mark[k].get(Math.min(bottomIndex[k] + 1, lineIndex[k])) <= t + 3 * scroll_height) {// 最底部的图片位置小于当前t+3*屏幕高度 ((FlowView) waterfall_items.get(k).getChildAt( Math.min(1 + bottomIndex[k], lineIndex[k]))).Reload(); bottomIndex[k] = Math.min(1 + bottomIndex[k], lineIndex[k]); } Log.d("MainActivity", "headIndex:" + topIndex[k] + " footIndex:" + bottomIndex[k] + " headHeight:" + pin_mark[k].get(topIndex[k])); if (pin_mark[k].get(topIndex[k]) < t - 2 * scroll_height) {// 未回收图片的最高位置<t-两倍屏幕高度 int i1 = topIndex[k]; topIndex[k]++; ((FlowView) localLinearLayout.getChildAt(i1)) .recycle(); Log.d("MainActivity", "recycle,k:" + k + " headindex:" + topIndex[k]); } } } } else {// 向上滚动 if (t > 2 * scroll_height) {// 超过两屏幕后 for (int k = 0; k < column_count; k++) { LinearLayout localLinearLayout = waterfall_items .get(k); if (pin_mark[k].get(bottomIndex[k]) > t + 3 * scroll_height) { ((FlowView) localLinearLayout .getChildAt(bottomIndex[k])).recycle(); bottomIndex[k]--; } if (pin_mark[k].get(Math.max(topIndex[k] - 1, 0)) >= t - 2 * scroll_height) { ((FlowView) localLinearLayout.getChildAt(Math .max(-1 + topIndex[k], 0))).Reload(); topIndex[k] = Math.max(topIndex[k] - 1, 0); } } } } } }); waterfall_container = (LinearLayout) this .findViewById(R.id.waterfall_container); handler = new Handler() { @Override public void dispatchMessage(Message msg) { super.dispatchMessage(msg); } @Override public void handleMessage(Message msg) { // super.handleMessage(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); waterfall_items.get(columnIndex).addView(v); lineIndex[columnIndex]++; pin_mark[columnIndex].put(lineIndex[columnIndex], column_height[columnIndex]); bottomIndex[columnIndex] = lineIndex[columnIndex]; break; } } @Override public 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 imagecount = 10000;// image_filenames.size(); for (int i = currentIndex; i < pagecount * (pageindex + 1) && i < imagecount; i++) { loaded_count++; Random rand = new Random(); int r = rand.nextInt(image_filenames.size()); AddImage(image_filenames.get(r), (int) Math.ceil(loaded_count / (double) column_count), loaded_count); } } //加入图片 private void AddImage(String filename, int rowIndex, int id) { FlowView item = new FlowView(context); // 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); }
学习的目标是成熟!~~