Cómo reasignar una imagen de 9 parches mediante programación a un ImageView?

Tengo una actividad que tiene un ImageView definido dentro de un HorizontalScrollView. El origen de la imagen es un archivo de 9 parches que está limitado a estirar sólo el borde derecho para llenar la pantalla. He implementado una función de zoom simple que permite al usuario pulsar dos veces para acercar y alejar, redimensionando el mapa de bits y asignando el nuevo mapa de bits a la vista. Mi problema actual es que cuando se duplica tocando para retroceder, el 9-patch no se aplica cuando asigno el nuevo mapa de bits redimensionado a la vista. En otras palabras, en lugar de estirar sólo el borde derecho como se define en el archivo de 9 parches, estiró toda la imagen.

Aquí está mi 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> 

Esta es la parte relevante de mi código, dentro de la llamada 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; } 

EDIT : Después de hacer algunas investigaciones, lo he averiguado. En lugar de simplemente manipular el mapa de bits, necesito incluir también el trozo de 9 parches, que no forma parte de la imagen de mapa de bits, para reconstruir un nuevo 9-parcheable. Vea el siguiente código de ejemplo:

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

EDIT : Después de hacer algunas investigaciones, lo he averiguado. En lugar de simplemente manipular el mapa de bits, necesito incluir también el trozo de 9 parches, que no forma parte de la imagen de mapa de bits, para reconstruir un nuevo 9-parcheable. Vea el siguiente código de ejemplo:

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

EDIT # 2 : Para aquellos que mira mi solución aquí, también echar un vistazo a las sugerencias de Kai a continuación sobre la gestión de memoria. Información muy útil.

¿Por qué no incluye sólo dos imágenes escaladas diferentes y cambia entre ellas usando imgResultMap.setImageResource(resId) al hacer zoom? También tenga en cuenta que está cargando y creando mapas de bits en UIThread que no es una buena manera de proporcionar una experiencia de usuario fluida, por lo menos precargar el mapa de bits sólo una vez durante onCreate () y caché que.

Mover esto: ImageView imgResultMap = (ImageView)findViewById(R.id.imgResultMap); A un global intialized en el método onCreate. De lo contrario, el dispositivo tiene que buscar la vista y encontrarla cada vez que se pulsa.

Y trate de llamar a imgResultMap.invalidate(); Antes de volver del método onDoubleTap ( http://developer.android.com/reference/android/view/View.html#invalidate () )

Las imágenes de 9 parches parecen funcionar sólo cuando están configuradas como una imagen de fondo de View . Asi que:

  • En lugar de android:src , set android:background en su XML de disposición, y
  • Llame a setBackgroundResource() cuando desee cambiar la imagen.

También puede utilizar una View sencilla en lugar de una ImageView si lo desea; En realidad no importa mucho.

También otra solución es establecer la imagen mediante programación como ImageResource y establecer scaleType

 imageView.setImageResource(R.drawable.favorite_driver_icon); imageView.setScaleType(ScaleType.FIT_XY); 
  • Facebook-esque Popup ¿Cómo?
  • Android: la imagen de 9 parches no se estira como se esperaba
  • 9-patch no funciona
  • Android: compilación de 9 archivos de parche para ser utilizado fuera de la carpeta de dibujo?
  • ¿Por qué la imagen de nueve parches en RelativeLayour oculta todos los elementos internos?
  • Cómo utilizar 9 imágenes de parche en android para diferentes-2 densidades (como mdpi, ldpi, hdpi).?
  • Dibujo de nueve parche sobre lienzo (Android)
  • Android Lollipop 5.1: Señal fatal 11 (SIGSEGV), código 2, error addr 0x9e985ff8 en tid 4093 (RenderThread) / cuando se usa un lote de nueve gráficos de parche
  • Definir un estilo personalizado (tema) en un componente de conmutador Android
  • Android nueve patch no se reconoce en el dispositivo
  • Cómo funciona un png 9patch en aplicaciones Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.