package me.xiaopan.sketchsample.widget; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.LinearLayout; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class DoubleFinsEmptyView extends LinearLayout{ public DoubleFinsEmptyView(Context context) { super(context); init(context); } public DoubleFinsEmptyView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context context) { Rect boundsRect = new Rect(0, 0, 100, 100); ArrayList<Rect> fullRectList = new ArrayList<Rect>(); fullRectList.add(new Rect(0, 0, 25, 25)); fullRectList.add(new Rect(25, 0, 50, 25)); fullRectList.add(new Rect(50, 0, 75, 25)); fullRectList.add(new Rect(75, 0, 100, 25)); fullRectList.add(new Rect(0, 25, 25, 50)); fullRectList.add(new Rect(25, 25, 50, 50)); fullRectList.add(new Rect(50, 25, 75, 50)); fullRectList.add(new Rect(75, 25, 100, 50)); fullRectList.add(new Rect(0, 50, 25, 75)); fullRectList.add(new Rect(25, 50, 50, 75)); fullRectList.add(new Rect(50, 50, 75, 75)); fullRectList.add(new Rect(75, 50, 100, 75)); fullRectList.add(new Rect(0, 75, 25, 100)); fullRectList.add(new Rect(25, 75, 50, 100)); fullRectList.add(new Rect(50, 75, 75, 100)); fullRectList.add(new Rect(75, 75, 100, 100)); setOrientation(VERTICAL); FindEmptyView originView = new FindEmptyView(context); originView.setBoundsRect(boundsRect); originView.setFullRectList(fullRectList); FindEmptyView findEmptyView = new FindEmptyView(context); findEmptyView.setBoundsRect(boundsRect); ArrayList<Rect> newFullRectList = new ArrayList<Rect>(fullRectList.size()); for (Rect fullRect : fullRectList) { newFullRectList.add(fullRect); } List<Rect> emptyRectList = findEmptyRect(boundsRect, newFullRectList); findEmptyView.setFullRectList(newFullRectList); findEmptyView.setEmptyRectList(emptyRectList); addView(originView, new LayoutParams(500, 500)); addView(findEmptyView, new LayoutParams(500, 500)); } public static List<Rect> findEmptyRect(Rect rect, List<Rect> childRectList) { if (rect.isEmpty()) { return null; } List<Rect> emptyRectList = null; if (childRectList == null || childRectList.size() == 0) { emptyRectList = new LinkedList<Rect>(); emptyRectList.add(rect); return emptyRectList; } // 按离左上角的距离排序 Collections.sort(childRectList, new Comparator<Rect>() { @Override public int compare(Rect o1, Rect o2) { if (o1.top >= o2.bottom || o2.top >= o1.bottom) { return o1.top - o2.top; } else { return o1.left - o2.left; } } }); int left = rect.left, top = rect.top, right = 0, bottom = -1; Rect lastRect = null; Rect childRect; Iterator<Rect> rectIterator = childRectList.iterator(); while (rectIterator.hasNext()) { childRect = rectIterator.next(); boolean newLine = lastRect == null || (childRect.top >= bottom); if (newLine) { // 首先要处理上一行的最后一个 if (lastRect != null) { if (lastRect.right < rect.right) { Rect rightEmptyRect = new Rect(lastRect.right, top, rect.right, bottom); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(rightEmptyRect); } } // 然后要更新top和bottom top = bottom != -1 ? bottom : top; bottom = childRect.bottom; // 左边有空隙 if (childRect.left > left) { Rect leftEmptyRect = new Rect(left, childRect.top, childRect.left, childRect.bottom); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(leftEmptyRect); } // 顶部有空隙 if (childRect.top > top) { Rect topEmptyRect = new Rect(left, top, childRect.right, childRect.top); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(topEmptyRect); } right = childRect.right; lastRect = childRect; } else { boolean available = childRect.bottom == lastRect.bottom; if (available) { // 左边有空隙 if (childRect.left > right) { Rect leftEmptyRect = new Rect(right, top, childRect.left, bottom); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(leftEmptyRect); } // 顶部有空隙 if (childRect.top > top) { Rect topEmptyRect = new Rect(childRect.left, top, childRect.right, childRect.top); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(topEmptyRect); } right = childRect.right; lastRect = childRect; } else { rectIterator.remove(); } } } // 最后的结尾处理 if (right < rect.right) { Rect rightEmptyRect = new Rect(right, top, rect.right, bottom); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(rightEmptyRect); } if (bottom < rect.bottom) { Rect bottomEmptyRect = new Rect(rect.left, bottom, rect.right, rect.bottom); if (emptyRectList == null) { emptyRectList = new LinkedList<Rect>(); } emptyRectList.add(bottomEmptyRect); } return emptyRectList; } }