Как программно повторно применить 9-образное изображение к ImageView?

У меня есть активность, которая имеет ImageView, определенную внутри HorizontalScrollView. Источник изображения представляет собой файл с 9 патчами, который ограничен, чтобы растянуть только правый край, чтобы заполнить экран. Я реализовал функцию простого масштабирования, которая позволяет пользователю дважды увеличивать и уменьшать масштаб, изменяя размер растрового изображения и назначая новое растровое изображение для представления. Моя текущая проблема заключается в том, что при удвоении нажатия, чтобы уменьшить масштаб, 9-патч не применяется, когда я назначаю новое изменение размера растрового изображения в представление. Другими словами, вместо растяжения только правого края, как определено в файле с 9 патчами, он растягивал все изображение.

Вот мой 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-патча, который не является частью изображения растрового изображения, для повторной сборки нового 9-патча. См. Пример кода ниже:

    ...
 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);
 }

  ....

Ответ 1

РЕДАКТИРОВАТЬ. Проведя некоторое исследование, я понял. Вместо того, чтобы просто манипулировать растровым изображением, мне нужно также включить фрагмент 9-патча, который не является частью изображения растрового изображения, для повторной сборки нового 9-патча. См. Пример кода ниже:

    ...
 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 ниже относительно управления памятью. Очень полезная информация.

Ответ 2

Почему бы вам просто не включить два разных масштабированных изображения и переключиться между ними, используя imgResultMap.setImageResource(resId) при масштабировании? Также обратите внимание, что вы загружаете и создаете растровые изображения в UIThread, что не является хорошим способом обеспечить плавный пользовательский интерфейс, по крайней мере предварительно загружать растровое изображение только один раз во время onCreate() и кешировать.

Ответ 3

Переместите это: ImageView imgResultMap = (ImageView)findViewById(R.id.imgResultMap); к глобальному intialized в методе onCreate. В противном случае устройство должно искать представление и находить его каждый раз, когда он прослушивается.

и попробуйте позвонить imgResultMap.invalidate();, прежде чем вы вернетесь из метода onDoubleTap (http://developer.android.com/reference/android/view/View.html#invalidate())

Ответ 4

9-патч-изображения, похоже, работают только тогда, когда они установлены как фоновое изображение View. Итак:

  • вместо android:src, установите android:background в вашем макете XML и
  • вызов setBackgroundResource(), если вы хотите изменить изображение.

Вы также можете использовать простой View вместо ImageView, если хотите; это не имеет большого значения.

Ответ 5

Еще одно решение - установить изображение программно как ImageResource и установить scaleType

imageView.setImageResource(R.drawable.favorite_driver_icon);
imageView.setScaleType(ScaleType.FIT_XY);