web-dev-qa-db-fra.com

Comment passer tirable entre les activités

Comment puis-je passer une image, type dessinable entre les activités?

J'essaye ceci:

private Drawable imagen;

Bundle bundle = new Bundle();
bundle.putSerializable("imagen", (Serializable) unaReceta.getImagen());
Intent myIntent = new Intent(v.getContext(), Receta.class);
myIntent.putExtras(bundle);
startActivityForResult(myIntent, 0);

Mais il me rapporte une exception:

Java.lang.ClassCastException: Android.graphics.drawable.BitmapDrawable
27
android iPhone

1) Transmettre l'intention en tant que extras

Dans la Activité A, vous décodez votre image et l'envoyez via l'intention:

  • En utilisant cette méthode (extras), l'image est transmise dans un intervalle de temps de 162 millisecondes
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);     
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); 
byte[] b = baos.toByteArray();

Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picture", b);
startActivity(intent);

Dans Activité B, vous recevez une intention avec tableau d'octets (image décodée) et vous l'appliquez comme source à ImageView:

Bundle extras = getIntent().getExtras();
byte[] b = extras.getByteArray("picture");

Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
ImageView image = (ImageView) findViewById(R.id.imageView1);

image.setImageBitmap(bmp);

2) Sauvegarde du fichier image et passage de sa référence à une autre activité

Msgstr "" "La taille limite est la suivante: gardez le plus petit possible. Evidemment, ne mettez pas un bitmap, sauf s'il ne dépasse pas une icône (32x32 ou Peu importe).

  • Dans * Activité A *, enregistrez le fichier (stockage interne)
String fileName = "SomeName.png";
try {
    FileOutputStream fileOutStream = openFileOutput(fileName, MODE_PRIVATE);
    fileOutStream.write(b);  //b is byte array 
                             //(used if you have your picture downloaded
                             // from the *Web* or got it from the *devices camera*)
                             //otherwise this technique is useless
    fileOutStream.close();
} catch (IOException ioe) {
    ioe.printStackTrace();
}
  • Passer l'emplacement en tant que chaîne à l'activité B
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picname", fileName);
  • Dans * Activité B *, récupérez le fichier
Bundle extras = getIntent().getExtras();
String fileName = extras.getString("picname");
  • Rendre * tirable * de la photo
File filePath = getFileStreamPath(fileName);
Drawable d = Drawable.createFromPath(filePath.toString());
  • Appliquez-le à la ressource ImageView
someImageView.setBackgroundDrawable(d);
50
user849998

Vous pouvez baliser chaque image (dans le xml ou par programme) avec le nom de la ressource d’image (comme "img1.png"), .__ puis récupérer le nom de l’image à l’aide de la fonction getTag();

Ensuite, utilisez getResources().getIdentifier(image name,"drawable", .getPackageName()) pour obtenir l'ID de ressource pouvant être dessiné.

Et passez simplement l'id de la ressource à travers l'intention - 

intent.putExtra("img 1",resource id);

Enfin, le résultat Activity peut créer l'image à partir de la ressource en utilisant: 

getResources().getDrawable(intent.getIntExtra("img 1",-1));    
4
user3782996

Les objets Drawable ne sont pas intrinsèquement sérialisables, ils ne peuvent donc pas être passés directement dans les extras Intent. Vous devez trouver un autre moyen de sérialiser ou de conserver les données d'image et de les récupérer dans la nouvelle activité.

Par exemple, si vous travaillez avec des instances BitmapDrawable, la Bitmap sous-jacente peut être écrite dans un fichier et relue, ou sérialisée dans un tableau d'octets (si sa taille est suffisante) et le tableau d'octets pourrait être transmis via des extras d'une Intent.

HTH

3
Devunwired

Mieux vaut beaucoup mieux ne pas passer (ou sérialiser) Drawables entre Activities. Très probablement, vous tirez le sort d’une ressource. Il existe donc un identifiant de ressource. Passez ça autour, c'est juste un int. Et réhydrater la Drawable dans l'autre Activity.

Si la Drawable ne provient pas d'une ressource, mais qu'elle est construite à l'exécution en mémoire ... eh bien, parlons-en. @Devunwired a une suggestion de Nice dans ce cas.

2
superjos

Vous pouvez simplement utiliser une méthode native buildDrawingCache:

    ImageView imageView = imageLayout.findViewById (R.id.img_thumb);
    imageView.buildDrawingCache ();

    Bundle extras = new Bundle ();
    extras.putParcelable ("image", imageView.getDrawingCache ());

    Intent intent = new Intent (this, ImageActivity.class);
    intent.putExtras (extras);

    startActivity (intent);

puis l'obtenir à votre ImageActivity:

    Bundle bundle = getIntent ().getExtras ();

    if (bundle != null) {

        ImageView imageView = findViewById (R.id.img_full);

        Bitmap image = bundle.getParcelable ("image");
        imageView.setImageBitmap (image);

    }
0
Acuna

Si vous extrayez ces images du Web et les chargez encore et encore, leur mise en cache serait une très bonne option car vous réduirez le trafic réseau et augmenterez la vitesse de chargement. Je suggère d'utiliser WebImageView from Droid-Fu . Très bonne solution, utilisée sur certains projets et j'en suis très satisfaite.

0
vbokan

Je ne sais pas si c'est le cas, mais si la raison pour laquelle vous essayez de transmettre un dessin est parce que vous utilisez un ImageView, il suffit de mettre l'ID de la ressource dans la balise de l'imageview, de passer la balise sous la forme d'un entier tirable dans le extra de l'intention et utilisez la ligne suivante dans l'activité de réception: imageView.setImageDrawable (getResources (). getDrawable (getIntent (). getIntExtra ("image_id", 0)));

J'espère que ça va aider quelqu'un.

0
Eran Katsav