5

我有一个在 Horizo​​ntalScrollView 中定义的 ImageView 的活动。图像源是一个 9-patch 文件,它被限制为仅拉伸右边缘以填充屏幕。我已经实现了一个简单的缩放功能,它允许用户通过调整位图大小并将新位图分配给视图来放大和缩小。我当前的问题是,当我双击以缩小时,当我将新的调整大小的位图分配给视图时,不会应用 9-patch。换句话说,它不是仅拉伸 9-patch 文件中定义的右边缘,而是拉伸了整个图像。

这是我的 XML:

<HorizontalScrollView
            android:id="@+id/hScroll"
            android:fillViewport="true"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:fadingEdge="none" >

            <RelativeLayout
                android:id="@+id/rlayoutScrollMap"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" >

                <ImageView
                    android:id="@+id/imgResultMap"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    android:scaleType="fitXY"
                    android:src="@drawable/map_base"/>

            </RelativeLayout>
        </horizontalScrollView>

这是我的代码的相关部分,在 onDoubleTap() 调用中:

public boolean onDoubleTap(MotionEvent e)  
                {  
                    if (zoom == 1) {
                        zoom = 2; // zoom out
                    } else {
                        zoom = 1; // zoom in
                    }
                    Bitmap image = BitmapFactory.decodeResource(getResources(),R.drawable.map_base);            
                    Bitmap bmp = Bitmap.createScaledBitmap(image, image.getWidth() * zoom, image.getHeight() * zoom, false);
                    ImageView imgResultMap = (ImageView)findViewById(R.id.imgResultMap);
                    imgResultMap.setImageBitmap(bmp);

                    return false; 
                } 

编辑:在做了一些研究之后,我想通了。我不仅需要操作位图,还需要包含 9-patch 块,它不是位图图像的一部分,以重新构造一个新的 9-patch 可绘制对象。请参阅下面的示例代码:

    ...
 else {
        // Zoom out
        zoom = 1;
        Bitmap mapBitmapScaled = mapBitmap; 
        // Load the 9-patch data chunk and apply to the view
        byte[] chunk = mapBitmap.getNinePatchChunk();
        NinePatchDrawable mapNinePatch = new NinePatchDrawable(getResources(), 
            mapBitmapScaled, chunk, new Rect(), null);
        imgResultMap.setImageDrawable(mapNinePatch);
 }

  ....
4

5 回答 5

10

编辑:在做了一些研究之后,我想通了。我不仅需要处理位图,还需要包含 9-patch 块,它不是位图图像的一部分,以重新构造一个新的 9-patch 可绘制对象。请参阅下面的示例代码:

    ...
 else {
        // Zoom out
        zoom = 1;
        Bitmap mapBitmapScaled = mapBitmap; 
        // Load the 9-patch data chunk and apply to the view
        byte[] chunk = mapBitmap.getNinePatchChunk();
        NinePatchDrawable mapNinePatch = new NinePatchDrawable(getResources(), 
            mapBitmapScaled, chunk, new Rect(), null);
        imgResultMap.setImageDrawable(mapNinePatch);
 }

  ....

编辑#2:对于那些在此处查看我的解决方案的人,还请查看 Kai 下面关于内存管理的建议。非常有用的信息。

于 2012-05-17T16:45:54.223 回答
1

为什么不只包含两个不同的缩放图像并imgResultMap.setImageResource(resId)在缩放时在它们之间切换?另请注意,您正在 UIThread 中加载和创建位图,这不是提供流畅用户体验的好方法,至少在 onCreate() 期间仅预加载位图一次并缓存它。

于 2012-05-17T02:01:32.027 回答
0

将 this: 移动 ImageView imgResultMap = (ImageView)findViewById(R.id.imgResultMap); 到 onCreate 方法中的全局初始化。否则,设备必须在每次点击时搜索视图并找到它。

并尝试imgResultMap.invalidate();在从 onDoubleTap 方法返回之前调用(http://developer.android.com/reference/android/view/View.html#invalidate()

于 2012-05-16T17:53:21.260 回答
0

另一种解决方案是以编程方式将图像设置为 ImageResource 并设置 scaleType

imageView.setImageResource(R.drawable.favorite_driver_icon);
imageView.setScaleType(ScaleType.FIT_XY);
于 2013-12-19T11:40:08.713 回答
0

9-patch 图片似乎只在设置为 aView的背景图片时才有效。所以:

  • 而不是android:src,android:background在您的布局 XML 中设置,并且
  • setBackgroundResource()当您想更改图像时调用。

如果你愿意,你也可以使用 plainView而不是 an ;ImageView这并不重要。

于 2013-04-01T18:42:12.107 回答