为什么我的图像在缩放后会被剪裁?

时间:2014-04-21 02:49:34

标签: android-layout imageview scrollview android-imageview

我遇到了一个奇怪的问题。我缩放图像,并且在缩放正常工作时,图像总是被剪裁。我尝试了不同的比例类型 - 事情发生了变化,但我从来没有让它发挥作用。

为了清楚起见,这就是我需要解决的问题: 1. HorizontalScrollView附近有ImageViewScrollView附近有HorizontalView。 2.我滚动(使用两个滚动视图的scrollTo),并在某个事件时放大。 3.我想要发生的是ImageView围绕我当前的滚动位置缩放。

这是布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none"
        android:overScrollMode="never">

        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            android:overScrollMode="never">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="3dp"
                android:scaleType="fitCenter" />
        </HorizontalScrollView>
    </ScrollView>
</FrameLayout>

以下是缩放代码(originalWidth / originalHeight1; targetView指向ImageView的比例计算:

public synchronized void changeScale(float newScaleFactor) {
    this.scaleFactor = Math.max(min_zoom, Math.min(newScaleFactor, max_zoom));
    if (targetView != null && originalWidth > 0) {
        int newWidth = (int)(originalWidth * scaleFactor);
        int newHeight = (int)(originalHeight * scaleFactor);
        onScaleChanged(targetView, scaleFactor, newWidth, newHeight);
    }
}


public void onScaleChanged(View targetView, float scaleFactor, int newWidth, int newHeight) {
    ViewGroup.LayoutParams layoutParams = targetView.getLayoutParams();
    layoutParams.width = newWidth;
    layoutParams.height = newHeight;

    // This is needed to increase the pane size (rather than zoom within the initial layout)
    targetView.setLayoutParams(layoutParams);
    // Tell the system to recalculate the layout
    targetView.requestLayout();

    // This is needed to specify the center of scaling
    HorizontalScrollView horizontalScrollView = (HorizontalScrollView)targetView.getParent();
    ScrollView vertScrollView = (ScrollView)horizontalScrollView.getParent();
    // ~~~ the pivot points are probably wrong 
    targetView.setPivotX(horizontalScrollView.getScrollX() * scaleFactor);
    targetView.setPivotY(vertScrollView.getScrollY() * scaleFactor);

    // This is needed for actual zooming
    targetView.setScaleX(scaleFactor);
    targetView.setScaleY(scaleFactor);
};


public void zoomIn(float scaleDelta) {
    changeScale(scaleFactor + scaleDelta);
}

public void zoomOut(float scaleDelta) {
    changeScale(scaleFactor - scaleDelta);
}

问题1:如何防止剪辑?我无法找到scaleType和布局大小调整的正确组合。

问题2:当我使用setScaleX / setScaleY时,应该在应用新的比例因子后计算我的数据,还是渲染器会自动处理?

2 个答案:

答案 0 :(得分:1)

更新比例后,您需要使invalid()和requestLayout()视图无效。

targetView.invalidate();
targetView.requestLayout();

我通常会为图像计算不同的比例。您可以尝试使用MATRIX比例类型缩放图像视图。您需要知道绑定DPI的大小。

// Get the scaled DPI
int boundBoxInDp = getResources().getDisplayMetrics().densityDpi * scaleFactor

// Determine how much to scale: the dimension requiring less scaling is
// closer to its side. This way the image always stays inside your
// bound AND either x/y axis touches the bound but neither will go over.
float xScale = ((float) boundBoxInDp) / newWidth;
float yScale = ((float) boundBoxInDp) / newHeight;
float scale = (xScale <= yScale) ? xScale : yScale;

// scale using our calculated scale
targetView.setScaleX(scale);
targetView.setScaleY(scale);

关于你关于枢轴的第二个问题。这可能需要设置为可见滚动区域的中心。当您使用FIT_CENTER;

时更改图像大小时,应该增加可滚动区域

答案 1 :(得分:0)

有关运行良好的代码,请参阅this article。我放弃了我的Horizo​​ntalScrollView和ScrollView,并将这个PanAndZoomListener附加到我的FrameLayout,从那时起它就是所有的彩虹和独角兽。

我试着和你做同样的事,但没有成功。看起来你可以在不使用Horizo​​ntalScrollView和ScrollView的情况下滚动ImageView。我还不清楚是什么让它发生,但我倾向于使用图像矩阵(如在ImageView上的setImageMatrix)或可能使用MarginLayoutParams。在查看Android上可用图片库中的Gallery源代码时,我看到了大量使用Matrix。不幸的是,关于这方面的文档在我的估计中似乎很轻松。

其他人已经弄明白了,所以请插入PanAndZoomListener并完成。这就是我所做的。