¿Cómo mantener una imagen en una actividad de Android durante un cambio de orientación?
Soy muy nuevo en la programación de Android y he estado experimentando con la construcción de una aplicación. En mi nueva aplicación tengo el usuario presione un botón que les permite elegir una aplicación en su dispositivo como "Galería" para seleccionar una imagen. Esta imagen se muestra en una ventana de vista de imagen en la pantalla de actividad. Lamentablemente, cuando cambio el teléfono y los cambios de orientación, la imagen se pierde y tienen que ir a seleccionar de nuevo.
¿Cómo guardo la imagen de mapa de bits y la vuelvo a mostrar después del cambio de orientación?
- El video de Android no mantiene la orientación cuando se sube al sitio web.
- Cómo ajustar la página web al ancho de la webview cuando se cambia el tamaño de la vista web (sin recargar)
- Problema del ciclo de vida con cambio de orientación en otra actividad
- La orientación de la pantalla de Android difiere entre los dispositivos
- ¿La orientación de Android como dirección - rollo de tono de corrupción?
Aquí está la función de código que utilizo para permitir al usuario escoger una aplicación de imagen, seleccionar una imagen y mostrar la imagen en la ventana de vista de imagen.
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK){ Uri targetUri = data.getData(); textTargetUri.setText(targetUri.toString()); Bitmap bitmap; try { bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri)); targetImage.setImageBitmap(bitmap); } catch (FileNotFoundException e){ e.printStackTrace(); } } }
La función anterior se inicializa en mi onCreate en respuesta a un clic de botón que se muestra en este código:
Button buttonLoadImage = (Button)findViewById(R.id.loadimage); textTargetUri = (TextView)findViewById(R.id.targeturi); targetImage = (ImageView)findViewById(R.id.targetimage); buttonLoadImage.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View arg0) { Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, 0); }});
Esencialmente, sólo necesito poner este booleano en mi onCreate y ponerlo de nuevo en la ventana. También muestra texto que muestra dónde estaba ubicada la imagen en el dispositivo, pero eso no es tan importante para mí como poder tener la imagen en la pantalla.
if (savedInstanceState != null) { }
Pero parece borrar los datos después del cambio de orientación? No tengo ni idea de cómo guardar los datos y restaurar que se utilice dentro de ese booleano. ¡Aprecio cualquier consejo, código o enlaces que pueda proporcionar!
ACTUALIZAR:
Gracias Vishal Vijay y rajahsekar por sus respuestas rápidas y útiles. Usando tanto de su codificación aconsejada, así como algún código que había encontrado de la investigación anterior, pude compilar una solución. Sin embargo, mientras resolvió el primer problema, generó otro que describiré después de mostrar el código que usé para solucionar el problema inicial.
Me pareció que tenía 2 opciones disponibles para la porción de restauración.
O bien podría colocar esto en el onCreate:
if (savedInstanceState != null) { //if there is a bundle, use the saved image resource (if one is there) image = savedInstanceState.getParcelable("BitmapImage"); targetImage.setImageBitmap(image); textTargetUri.setText(savedInstanceState.getString("path_to_picture"));R.drawable.camera_button); }
Esto me permitió tener la imagen, así como la ruta a ella en el dispositivo para volver a mostrar en mi actividad.
O podría tener esto después de la onCreate
@Override protected void onRestoreInstanceState(Bundle savedInstanceState){ image = savedInstanceState.getParcelable("BitmapImage"); targetImage.setImageBitmap(image); textTargetUri.setText(savedInstanceState.getString("path_to_picture")); }
Y la función de ahorro que usé fue
@Override public void onSaveInstanceState(Bundle savedInstanceState){ super.onSaveInstanceState(savedInstanceState); savedInstanceState.putParcelable("BitmapImage", bitmap); savedInstanceState.putString("path_to_picture", picture_location); }
Para aclarar de dónde vino picture_location, en mi función onActivityResult añadí una línea y cambié otra para guardar la cadena de ruta
if (resultCode == RESULT_OK){ Uri targetUri = data.getData(); picture_location = targetUri.toString(); textTargetUri.setText(picture_location);
En cuanto a las variables inicializadas antes de la onCreate,
Bitmap image; Bitmap bitmap; String picture_location;
Ahora, me doy cuenta de que esto ha llegado bastante largo, pero espero que ayude a otros que pueden tener un problema similar. En cuanto a la nueva edición que mencioné anterior, cuando hago girar mi dispositivo del androide, guarda de hecho los datos y lo vuelvo a exhibir mientras que intentaba hacer. Sin embargo, cuando vuelvo a girar la pantalla, surge la cuestión original; Los datos parecen estar perdidos y no se muestran en la pantalla.
Espero que haya una solución mucho más simple para que las funciones de guardar y restaurar seguir trabajando no importa cuántas veces cambia la orientación de la pantalla?
Gracias de nuevo chicos!
- A veces no obtiene la devolución de llamada onCreateLoader después de llamar a initLoader
- El diseño de Xml cambia al cambiar la orientación
- Centrar una imagen de fondo en Android
- ¿Cómo puedo bloquear el diseño de mi programa Android a una orientación
- Android - SensorManager comportamiento extraño de getOrientation
- Diseño diferente para la orientación "Paisaje" y "Orientación horizontal"
- Cambiar la configuración de Android en el cambio de orientación
- Bloquear la orientación del dispositivo - React Native (Android)
Bitmap image; public void onCreat(..){ if (savedInstanceState != null) { image = (Bitmap) savedInstanceState.getParcelableExtra("BitmapImage");; } else { image = yourBitmapImage; } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putExtra("BitmapImage", bitmap); }
Creo que cuesta mucho si guarda un Bitmap
en onSaveInstanceState
, ya que onSaveInstanceState
se llamará antes onStop
cada vez, y Bitmap
es una gran cosa.
Creo que es mejor guardar un URI
en onSaveInstanceState
.
Uri mUri; ImageView mImageView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... if (savedInstanceState != null){ mUri = savedInstanceState.getParcelable("uri"); mImageView.setImageURI(mUri); } } protected void onActivityResult( int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK){ Uri targetUri = data.getData(); ... mUri = targetUri; } } public void onSaveInstanceState(Bundle outState) { if (mURI !=null) { outState.putParcelable("uri", mUri); } }
Nunca debemos utilizar la forma anterior para guardar nuestros objetos pesados como imagen o mapa de bits siempre es recomendable utilizar los fragmentos. Echa un vistazo a esto una implementación fácil de cómo conservar el fragmento https://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject
Utilice onSaveInstanceState para guardar la imagen
if (savedInstanceState == null) { image = R.drawable.default; } else { // if there is a bundle, use the saved image resource (if one is there) image = savedInstanceState.getInt(IMAGE_RESOURCE, R.drawable.default); } @Override public void onSaveInstanceState(Bundle outState) { // Make sure you save the current image resource outState.putInt(IMAGE_RESOURCE, image); super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Parcelable state) { outState.getInt(IMAGE_RESOURCE,image); super.onRestoreInstanceState(state); }
Añadir android:configChanges="keyboardHidden|orientation"
para su actividad en el archivo de manifiesto.
- ¿La pantalla negra vino cuando la aplicación comienza en phonegap en androide antes de la pantalla de bienvenida?
- ¿Cómo detectar si RecyclerView está vacío?