Я видел, как несколько человек спрашивают, как увеличить всю группу ViewGroup (например, RelativeLayout) за один раз. На данный момент это то, что мне нужно достичь. Самый очевидный подход, для меня, заключался бы в том, чтобы удерживать масштабный коэффициент масштабирования как одну переменную где-то; и в каждом из методов дочернего вида onDraw() этот масштабный коэффициент будет применяться к холсту до рисования графики.
Однако, прежде чем делать это, я попытался быть умным (ха - обычно плохая идея) и расширить RelativeLayout, в класс под названием ZoomableRelativeLayout. Моя идея заключается в том, что любое преобразование масштаба может быть применено только один раз к Canvas в переопределенной функции dispatchDraw(), так что совершенно не нужно отдельно применять масштаб в любом из дочерних представлений.
Вот что я сделал в моем ZoomableRelativeLayout. Это просто простое расширение RelativeLayout, при этом dispatchDraw() переопределяется:
protected void dispatchDraw(Canvas canvas){
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScaleFactor, mScaleFactor);
super.dispatchDraw(canvas);
canvas.restore();
}
mScaleFactor управляется ScaleListener в том же классе.
Это действительно работает. Я могу ущипнуть, чтобы увеличить ZoomableRelativeLayout, и все просмотры, проведенные в правильном масштабировании вместе.
За исключением проблемы. Некоторые из этих дочерних просмотров анимированы, и поэтому я периодически вызываю invalidate() на них. Когда масштаб равен 1, эти дочерние представления, как видно, периодически перерисовываются отлично. Когда масштаб отличается от 1, эти анимированные дочерние представления видны только для обновления в части их области просмотра - или вообще не - в зависимости от масштаба масштабирования.
Мое первоначальное мышление состояло в том, что при вызове отдельного дочернего представления invalidate() он может быть перерисован индивидуально системой, а не передан Canvas из родительского RelativeLayout dispatchDraw(), что означает, что дочерний вид заканчивается вверх, освежая себя без примененной шкалы масштабирования. Но странно, что элементы просмотров ребенка, которые перерисовываются на экране, соответствуют правильной шкале масштабирования. Это почти так, как если бы область, которую система решает фактически обновить в базовом растровом файле, остается немасштабированной - если это имеет смысл. Иначе говоря, если у меня есть один анимированный дочерний вид, и я постепенно увеличиваю все дальше и дальше от начального масштаба 1, и если мы разместим воображаемое поле в области, где это дочернее представление, когда масштаб масштабирования равен 1, то вызовы invalidate() только вызывают обновление графики в этом мнимом поле. Но графика, которую, как видно, обновляет, выполняется в правильном масштабе. Если вы увеличиваете масштаб до тех пор, пока детское представление теперь полностью отодвинуто от того места, где оно было со шкалой 1, тогда никакая часть его вообще не будет обновлена. Я приведу еще один пример: представьте, что мой ребенок - это шар, который оживляет, переключаясь между желтым и красным. Если я увеличусь немного, чтобы мяч двигался вправо и вниз, в определенный момент вы увидите только верхнюю левую четверть шара.
Если я постоянно увеличиваю и уменьшаю масштаб изображения, я вижу, как ребенок просматривает анимацию правильно и полностью. Это происходит потому, что вся ViewGroup перерисовывается.
Надеюсь, это имеет смысл; Я пытался объяснить как можно лучше. Могу ли я проиграть с моей масштабируемой стратегией ViewGroup? Есть ли другой способ?
Спасибо,
Трев