我想采取任意矩阵并将其应用于android.views.View。
我发现的唯一可靠的方法就是这个黑客:
MyAnimation animation = new MyAnimation(matrix);
animation.setDuration(0);
animation.setFillAfter(true);
view.setAnimation(animation);
有更好的方法吗?我尝试利用getChildStaticTransformation并将其放在父母身上,但那还没有成功(也许我做错了?)
答案 0 :(得分:5)
最后,我基于AbsoluteLayout创建了自己的布局,在我的LayoutParams中添加了一个Matrix,利用了getChildStaticTransformation,并覆盖了dispatchTouchEvent,以便我的孩子在旋转时响应正确的边界。比我预想的要困难得多。
public class UIViewLayout extends ViewGroup {
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
if(child instanceof UIViewLayout) {
t.getMatrix().reset();
UIViewLayout.LayoutParams params = (UIViewLayout.LayoutParams)child.getLayoutParams();
t.setTransformationType(Transformation.TYPE_MATRIX);
t.getMatrix().set(params.matrix);
}
return true;
}
public UIViewLayout(android.content.Context context) {
super(context);
this.setClipChildren(false);
this.setClipToPadding(false);
this.setChildrenDrawingOrderEnabled(true);
this.setStaticTransformationsEnabled(true);
}
public UIViewLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UIViewLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
int maxHeight = 0;
int maxWidth = 0;
// Find out how big everyone wants to be
measureChildren(widthMeasureSpec, heightMeasureSpec);
// Find rightmost and bottom-most child
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
int childRight;
int childBottom;
UIViewLayout.LayoutParams lp
= (UIViewLayout.LayoutParams) child.getLayoutParams();
childRight = lp.x + child.getMeasuredWidth();
childBottom = lp.y + child.getMeasuredHeight();
maxWidth = Math.max(maxWidth, childRight);
maxHeight = Math.max(maxHeight, childBottom);
}
}
// Account for padding too
//maxWidth += mPaddingLeft + mPaddingRight;
//maxHeight += mPaddingTop + mPaddingBottom;
// Check against minimum height and width
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
}
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 0, 0);
}
@Override
protected void onLayout(boolean changed, int l, int t,
int r, int b) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
UIViewLayout.LayoutParams lp =
(UIViewLayout.LayoutParams) child.getLayoutParams();
int childLeft = lp.x;
int childTop = lp.y;
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(),
childTop + child.getMeasuredHeight());
}
}
}
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new UIViewLayout.LayoutParams(getContext(), attrs);
}
// Override to allow type-checking of LayoutParams.
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof UIViewLayout.LayoutParams;
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p);
}
@Override
public boolean shouldDelayChildPressedState() {
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
for(int i = 0; i < this.getChildCount(); i++) {
View child = getChildAt(i);
if(child instanceof UIViewLayout) {
UIViewLayout.LayoutParams params = (UIViewLayout.LayoutParams)child.getLayoutParams();
if(!params.matrix.isIdentity()) {
MotionEvent ev2 = MotionEvent.obtain(ev);
ev2.setLocation(ev2.getX() - params.x, ev2.getY() - params.y);
Matrix m = new Matrix();
params.matrix.invert(m);
ev2.transform(m);
if(child.dispatchTouchEvent(ev2)) {
return true;
}
ev2.recycle();
}
}
}
return super.dispatchTouchEvent(ev);
}
public static class LayoutParams extends ViewGroup.LayoutParams {
public int x;
public int y;
public Matrix matrix;
public LayoutParams(int width, int height, int x, int y) {
super(width, height);
this.x = x;
this.y = y;
this.matrix = new Matrix();
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
}