Как программно повторно применить изображение с 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);
 }

  ....

5 ответов

Решение

РЕДАКТИРОВАТЬ: После некоторых исследований, я понял это. Вместо того, чтобы просто манипулировать растровым изображением, мне нужно также включить блок из 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: Для тех, кто смотрит на мое решение здесь, также посмотрите на предложения Кая ниже относительно управления памятью. Очень полезная информация

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

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

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

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

Также другое решение состоит в том, чтобы установить изображение программно как ImageResource и установить scaleType

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

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

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

Другие вопросы по тегам