2010-12-16 15 views
17

Estoy usando un selector de fotos con la intención de elegir una imagen y escribirla en un archivo privado de la aplicación. La mayor parte de mi código fuente importante se muestra a continuación. Una vez que presiono un botón y realizo el primer intento de selección de imagen, entonces se actualiza con éxito la vista de la imagen. Sin embargo, una vez que presiono el botón de selección de imagen nuevamente (en la misma actividad), la vista de la imagen NO se actualiza, a menos que salga y reinicie la actividad. Así que sé que la imagen se está guardando con éxito, pero ¿por qué ImageView en el diseño no se actualiza o actualiza?ImageView no actualizar/reflejar cambios

public void onResume() { 
    super.onResume(); 
    ImageView myImageView = (ImageView)findViewById(R.id.contact_image); 
    if (hasImage) { 
     myImageView.setImageURI(Uri.fromFile(getFileStreamPath(TEMP_PHOTO_FILE))); 
    } 
    } 

    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
    case PHOTO_PICKED: 
     if (resultCode == RESULT_OK) { 
     if (data != null) { 
      Bundle extras = data.getExtras(); 
      if (extras != null) { 
      hasImage = true; 
      bmp = (Bitmap) extras.get("data"); 
      } 
     } 
     } 
     break; 
    } 
    } 

    private OnClickListener mChooseImage = new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     try { 
     // Launch picker to choose photo for selected contact 
     Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); 
     intent.setType("image/*"); 
     intent.putExtra("crop", "true"); 
     intent.putExtra("aspectX", 1); 
     intent.putExtra("aspectY", 1); 
     intent.putExtra("outputX", ICON_SIZE); 
     intent.putExtra("outputY", ICON_SIZE); 
     intent.putExtra("scale", true); 
     intent.putExtra("return-data", false); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile())); 
     intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); 
     startActivityForResult(intent, PHOTO_PICKED); 
     } catch (ActivityNotFoundException e) { 
     // LOG THIS 
     } 
    } 
    }; 

private File getTempFile() { 
    try { 
     if (!hasImage) { 
     FileOutputStream fos = openFileOutput(TEMP_PHOTO_FILE, MODE_WORLD_WRITEABLE); 
     fos.close(); 
     } 
     return getFileStreamPath(TEMP_PHOTO_FILE); 
    } catch (FileNotFoundException e) { 
     // To be logged later 
     return null; 
    } catch (IOException e) { 
     // To be logged later 
     return null; 
    } 
    } 

sobre el resultado de la actividad, configuré el URI de imagen de ImageView en este archivo.

Cuando se completa por primera vez, el ImageView cambia para reflejar esto. Sin embargo, si intento elegir la imagen nuevamente (misma actividad), ImageView no se actualizará hasta que salga y vuelva a ingresar la actividad. No estoy seguro de por qué sucede esto, ¿es porque estoy tratando de escribir en el temp.jpg cada vez? ¿O necesito actualizar mi diseño de alguna manera para reflejar los cambios en ImageView?

+0

¿Faltan algunos códigos? De lo que escribió, no debería ser necesario abrir flujos de salida a la imagen seleccionada. –

+0

He agregado la mayoría de mi código fuente. También me parece que si solo devuelvo el valor de la intención como un mapa de bits, la vista de la imagen se actualiza con éxito. Sin embargo, todavía quiero saber la fuente del problema. – damonkashu

+0

entonces, ¿hay algo que no sé sobre ImageViews o el intento del selector de imágenes? algo que no refleja el cambio hasta reiniciar la actividad? – damonkashu

Respuesta

1

Para forzar volver a dibujar el widget/Ver sólo llame View.invalidate();

+3

Llamo esto al ImageView, y no parece estar haciendo nada – damonkashu

+1

Tengo el mismo problema aquí. Invalidar no refresca mi vista de imagen personalizada –

18

A juzgar por el código fuente ImageView, el ImageView no se volverá a cargar la imagen si se llama setImageURI con el mismo URI. Puede intentar cambiar el URI escribiendo su imagen en otro archivo.

+4

¡Gracias! Pasé demasiadas horas tratando de resolver esto. Después de mirar la fuente yo mismo y probar view.requestLayout() y view.invalidate() que no funcionaron, he llegado a la conclusión de que configurar el uri para anular antes de volver a configurarlo es la mejor, si no la única, forma de usar setImageUri para un solo archivo de imagen cambiante. –

+3

Gracias a ambos por esto. Simplemente me ahorró algunas horas de confusión con respecto a la actualización de ImageView. En mi caso, quería una actualización de imagen en la actualización de la configuración regional, pero, al parecer, parece que, dado que el ID de residencia no cambia, ImageView simplemente ignora su solicitud, sin verificar si el recurso ha cambiado. Acabo de hacer un setImageDrawable (nulo) seguido por el setImageResource regular (R.drawable.image) y funciona. Debe haber sido una opción de implementación por motivos de rendimiento. – Toryu

+0

Gracias @ Pilot_51 y Toryu ... Definir la imagen como extraíble en nulo y luego configurar el ImageURi después me funcionó también. – Akshat

1

Tuve un problema similar cuando estaba usando la cámara de los dispositivos para tomar una foto y luego quería que el imageView en la pantalla original se actualizara cuando volví a él. La solución fue llamar a View.invalidate() en onResume().

11

ImageView no se volverá a dibujar si el "nuevo" URI es el mismo que el anterior. "View.invalidate()" no funcionará. Para "forzar" la actualización, puede hacerlo:

public void onResume() { 
    super.onResume(); 
    ImageView myImageView = (ImageView)findViewById(R.id.contact_image); 
    if (hasImage) { 
    myImageView.setImageDrawable(null); // <--- added to force redraw of ImageView 
    myImageView.setImageURI(Uri.fromFile(getFileStreamPath(TEMP_PHOTO_FILE))); 
    } 
} 
3

invalidar() no funcionó. Intenta hackear:

imageView.setImageURI(null); 
    imageView.setImageURI(newUri);