Подтвердить что ты не робот

Как получить правильные границы представления после преобразования Матрица

У меня есть пользовательский вид, где я использую преобразования. До сих пор такая хорошая работа, как setRotationY(), setScaleX(), setTranslationY() или даже getMatrix() работали, как и ожидалось, Im умеет манипулировать моим представлением, и он отображается нормально. Там, где я попал в стену, после этого несколько стран ведут себя странно. Например, функция типа getHitRect() возвращает совершенно странные значения! Это не помогает моим событиям касания.

Я попытался перегрузить функцию, но она все еще далека от работы, особенно при использовании вращения или масштабирования (Перевод выполняется нормально). Я думаю, что это как-то связано с тем, что матрица выражается в дочерней координате, так как я могу ее получить в координатах родителей?

@Override
    public void getHitRect(Rect outRect){

        RectF rect = new RectF(); 
        rect.top = (float) this.getTop(); 
        rect.bottom = (float) this.getBottom(); 
        rect.left = (float) this.getLeft(); 
        rect.right = (float) this.getRight();      

    this.getMatrix().mapRect(rect);
        rect.round(outRect);
    }

Можно ли получить прямое значение из некоторой функции? Как и новая высота, ширина, верх или низ.

4b9b3361

Ответ 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());
    }
}