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