Ответ 1
При переопределении метода getChildStaticTransformation в ViewGroup или даже с использованием функции преобразования, такой как setRotationY()
, setScaleX()
, setTranslationY()
, getMatrix()
(доступный из API 11), вы влияете только на рендеринг Matrix. В результате ваш пользовательский Child View вернет Bounds "Rect" далеко от того, где ваш ребенок получает ничью. Это не проблема большую часть времени, но когда вы начинаете желать нажимать на нее.. проблема начинается... Вот как я обхожу эту проблему. Я уверен, что могут быть лучшие способы, но поскольку я не нашел много вещей по этому вопросу, вот он.
В перегрузке ViewGroup:
public interface Itransformable {
public void setTransformationMatrix(Matrix trsMatrix);
}
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
if (child instanceof Itransformable){
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
...
// Do whatever transformation you want here
...
((Itransformable)child).setTransformationMatrix(t.getMatrix());
return true;
} else {
return false;
}
}
Вот пользовательский вид ребенка: Обратите внимание, что я не сохраняю непосредственно матрицу преобразования в пользовательском представлении, а вместо этого преобразован Rect. Если вы хотите сохранить матрицу (т.е. Для последующего преобразования, например, точки...), вам может потребоваться клонировать ее, поскольку матрица будет изменена каким-то странным образом, как если бы она была переработана или что-то в этом роде.
public class MyCustomView extends View implements MyViewGroup.Itransformable{
private Rect mViewRect = null;
public void setTransformationMatrix(Matrix trsMatrix){
if (trsMatrix!=null){
RectF rect = new RectF();
rect.top = 0;
rect.bottom = (float) this.getHeight();
rect.left = 0;
rect.right = (float) this.getWidth();
trsMatrix.mapRect(rect);
rect.offset((float) this.getLeft(), (float) this.getTop());
if (mViewRect == null) mViewRect = new Rect();
rect.round(mViewRect);
}
}
public Rect getTransformatedRect() {
if (mViewRect!=null){
// OutOfScreen WorkArround - As the view is not Displayed, mViewRect doesn't get updated.
if(getRight() < 0 || getLeft() > mParentWidth){
return new Rect(getLeft(),getTop(),getRight(),getBottom());
} else {
return mViewRect;
}
} else {
return new Rect(getLeft(),getTop(),getRight(),getBottom());
}
}
@Override
public void getHitRect(Rect outRect){
if (mViewRect == null){
super.getHitRect(outRect);
} else {
outRect.set(getTransformatedRect());
}
}