public static class CustomLayoutParams extends MarginLayoutParams { public static final int POSITION_MIDDLE = 0; // 中间 public static final int POSITION_LEFT = 1; // 左上方 public static final int POSITION_RIGHT = 2; // 右上方 public static final int POSITION_BOTTOM = 3; // 左下角 public static final int POSITION_RIGHTANDBOTTOM = 4; // 右下角
public int position = POSITION_LEFT; // 默认我们的位置就是左上角
public CustomLayoutParams(Context c, AttributeSet attrs) { super(c, attrs); TypedArray a = c.obtainStyledAttributes(attrs,R.styleable.CustomLayout ); //获取设置在子控件上的位置属性 position = a.getInt(R.styleable.CustomLayout_layout_position ,position );
a.recycle(); }
public CustomLayoutParams( int width, int height) { super(width, height); }
public CustomLayoutParams(ViewGroup.LayoutParams source) { super(source); }
public class TagLayout extends ViewGroup { private List<Rect> rects = new ArrayList<>();
public TagViewGroup(Context context) { super(context); }
public TagViewGroup(Context context, AttributeSet attrs) { super(context, attrs); }
public TagViewGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int lineUsedWidth = 0;//当前行的宽度 int lineUsedHeight = 0;//当前行的高度,取最大的 int usedWidth = 0;//一共使用了的宽度,取最大的 int usedHeight = 0;//一共使用了的高度 int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec);
@Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); }
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); Rect rect = rects.get(i); child.layout(rect.left, rect.top, rect.right, rect.bottom); } } }
public static int getChildMeasureSpec(int spec, int padding, int childDimension) { int specMode = MeasureSpec.getMode(spec); int specSize = MeasureSpec.getSize(spec);
int size = Math.max(0, specSize - padding);
int resultSize = 0; int resultMode = 0;
switch (specMode) { // Parent has imposed an exact size on us case MeasureSpec.EXACTLY: if (childDimension >= 0) { resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size. So be it. resultSize = size; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size. It can't be // bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } break;
// Parent has imposed a maximum size on us case MeasureSpec.AT_MOST: if (childDimension >= 0) { // Child wants a specific size... so be it resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size, but our size is not fixed. // Constrain child to not be bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } else if (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size. It can't be // bigger than us. resultSize = size; resultMode = MeasureSpec.AT_MOST; } break;
// Parent asked to see how big we want to be case MeasureSpec.UNSPECIFIED: if (childDimension >= 0) { // Child wants a specific size... let him have it resultSize = childDimension; resultMode = MeasureSpec.EXACTLY; } else if (childDimension == LayoutParams.MATCH_PARENT) { // Child wants to be our size... find out how big it should // be resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size; resultMode = MeasureSpec.UNSPECIFIED; } else if (childDimension == LayoutParams.WRAP_CONTENT) { // Child wants to determine its own size.... find out how // big it should be resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size; resultMode = MeasureSpec.UNSPECIFIED; } break; } //noinspection ResourceType return MeasureSpec.makeMeasureSpec(resultSize, resultMode); }
多点触控的两个重要成员分别是:index 和 id。index 用来遍历手指,通过 MotionEvent.findPointerIndex(int pointerId) 获取或者从 0...pointerCount 中选择一个 index 值。id 用来追踪手指,通过 MotionEvent.getPointerId(int pointerIndex) 获取。注意,一般的流程是:id 先得到 index 后,再通过 index 访问指定手指的 x , y 值,如getX(index)。