android - View 转换后图像越界

标签 android view rotation imageview bounds

我在显示图像时遇到问题。

我有一张图片,我想全屏显示。所以我有这个带有 match_parent 和 20dp 填充的 Imageview。

enter image description here

它看起来不错,但是当我对其应用旋转时, View 的边界似乎没有改变,并且图像可能会被剪切出屏幕!完全不想发生这种事!如何重新缩放图像,使图像在旋转 90 度时也适合 ImageView。

enter image description here

这是我的带有旋转的 XML。

enter image description here

编辑:

如何固定图像的边界,使文本恰好在图像上方对齐? enter image description here

最佳答案

测量 View 和计算比例时不考虑旋转。一个可能的解决方案是自己做:

public class RotatedImageView extends ImageView {

    ...
    constructors
    ...


    private double mRotatedWidth;
    private double mRotatedHeight;

    private boolean update() {
        Drawable d = getDrawable();

        if (d == null) {
            return false;
        }

        int drawableWidth = d.getIntrinsicWidth();
        int drawableHeight = d.getIntrinsicHeight();

        if (drawableWidth <= 0 || drawableHeight <= 0) {
            return false;
        }

        double rotationRad = getRotation() / 180 * Math.PI;

        // calculate intrinsic rotated size
        // see diagram

        mRotatedWidth = (Math.abs(Math.sin(rotationRad)) * drawableHeight
                + Math.abs(Math.cos(rotationRad)) * drawableWidth);
        mRotatedHeight = (Math.abs(Math.cos(rotationRad)) * drawableHeight
                + Math.abs(Math.sin(rotationRad)) * drawableWidth);

        return true;
    }


    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        if (update()) {
            double ratio = mRotatedWidth / mRotatedHeight;

            int wMax = Math.min(getDefaultSize(Integer.MAX_VALUE, widthMeasureSpec), getMaxWidth());
            int hMax = Math.min(getDefaultSize(Integer.MAX_VALUE, heightMeasureSpec), getMaxHeight());

            int w = (int) Math.min(wMax, hMax * ratio);
            int h = (int) Math.min(hMax, wMax / ratio);

            setMeasuredDimension(w, h);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }

    }

    private final float[] values = new float[9];

    protected void onDraw(Canvas canvas) {

        if (update()) {
            int availableWidth = getMeasuredWidth();
            int availableHeight = getMeasuredHeight();

            float scale = (float) Math.min(availableWidth / mRotatedWidth, availableHeight / mRotatedHeight);

            getImageMatrix().getValues(values);

            setScaleX(scale / values[Matrix.MSCALE_X]);
            setScaleY(scale / values[Matrix.MSCALE_Y]);
        }

        super.onDraw(canvas);
    }

    @Override
    public void setRotation(float rotation) {
        super.setRotation(rotation);
        requestLayout();
    }
}

adjustViewBounds 必须为真:

<com.mypackage.RotatedImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    android:adjustViewBounds="true"
    android:rotation="90"
    android:maxWidth="100dp"
    android:maxHeight="100dp"
    android:scaleType="fitCenter"
    android:src="@drawable/test" />

对计算的一个很好的解释,由 Cheticamp 提供:

enter image description here

rotation="0"

rotation="45"

rotation="90"

更新:现在正在尝试调整边界。 wrap_contentmatch_parent 之间没有区别(两者都尽可能地增长,基于图像方面)。您应该改为使用 maxWidth 和/或 maxHeight,或者将其放在尺寸和权重为 0 的 LinearLayout 中。

它也不是可动画的,在动画时调整边界需要为每一帧进行布局传递,这是非常低效的。请参阅可与 View.animate()

一起使用的版本的其他答案

关于android - View 转换后图像越界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43414865/

相关文章:

android - 如果我在 mp4parser 中合并更多视频,音频和视频无法正确同步

mysql - 如何获取 View 之间的mysql依赖关系?

javascript - asp.net mvc,以 JSON 形式返回多个 View

android - 旋转后找不到 fragment 的 id 0x View ?

jquery - 获取元素-moz-transform :rotate value in jQuery

java - 不幸的是,应用程序已使用 eclipse 在 webview 中停止

java - 无法解析方法 getChildFragmentManager()

C++ AI 轮换问题

java - JRE 或 JDK 必须... Java - Eclipse 问题

ios - 表格 View 在 iPhone 上放错了位置