Android - нажмите на изображение, чтобы оно масштабировалось, и при желании поворачивайте, чтобы заполнить экран - PullRequest
2 голосов
/ 28 февраля 2012

У меня есть вид прокрутки, который содержит ImageViews. Я хочу, чтобы пользователь мог нажимать на одно из этих изображений, чтобы оживить его, чтобы заполнить весь экран (за исключением строки состояния вверху). Если изображение имеет альбомную ориентацию, я хочу, чтобы оно поворачивалось на 90 градусов во время анимации. Изображения в представлении прокрутки не обрезаются, но как только они масштабируются, я хочу обрезать изображения, чтобы заполнить доступный экран.

Я сделал попытку, которая добавляет второй ImageView прямо поверх оригинала. Это новое представление переопределяет метод onDraw для обработки поворота с помощью canvas.rotate(rotation, canvas.getWidth() / 2, canvas.getHeight() / 2);, а затем пользовательского класса Animation, который выполняет масштабирование путем вычисления новых LayoutParams. Он работает для портретных изображений и почти работает для пейзажных, но слишком сильно их масштабирует.

У меня проблемы с пониманием взаимосвязи между границами ImageView и нижележащего холста, который я вращаю. Обратите внимание, что я нацеливаюсь на Android 2.2, в противном случае я бы использовал методы view.setRotation().

Вот код:

public class ImageZoom extends ImageView
{
  float rotation = 0;

  // Constructors here...

  @Override
  protected void onDraw(Canvas canvas) {
    canvas.save();
    if(rotation != 0)
    {
      canvas.rotate(rotation, canvas.getWidth() / 2, canvas.getHeight() / 2);
    }
    super.onDraw(canvas);
    canvas.restore();
  }
}

И анимация:

public class ImageZoomAnimation extends Animation {
    public ImageZoomAnimation(View view, View parent) {
        this.view = (ImageZoom)view;
        this.parent = parent;

        RelativeLayout.LayoutParams initParams = (RelativeLayout.LayoutParams)view.getLayoutParams();
        this.startWidth = initParams.width;
        this.startHeight = initParams.height;
        isRotate = startWidth > startHeight;
        this.startLeftMargin = initParams.leftMargin;
        this.startTopMargin = initParams.topMargin;;
        this.endWidth = parent.getWidth();
        this.endHeight = parent.getHeight();
        this.setInterpolator(new LinearInterpolator());
        this.setDuration(2000);
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        int newWidth = (int) (startWidth + ((endWidth - startWidth) * interpolatedTime));
        int newHeight = (int) (startHeight + ((endHeight - startHeight) * interpolatedTime));
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(newWidth, newHeight);
        params.leftMargin = (int)(startLeftMargin * (1 - interpolatedTime));
        params.topMargin = (int)(startTopMargin * (1 - interpolatedTime));
        if(isRotate)
        {
            view.setRotation(90 * interpolatedTime);
        }
        view.setLayoutParams(params);
    }
}

У меня такое чувство, что я поступаю неправильно. Вращение холста в одном классе и изменение параметров макета в другом кажется неправильным. Заранее спасибо за любую помощь ...

...