How to pass drawable between activities

2019-01-03 09:43发布

How can I pass an image, drawable type between activities?

I try this:

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

But it reports me an execption:

java.lang.ClassCastException: android.graphics.drawable.BitmapDrawable

7条回答
叛逆
2楼-- · 2019-01-03 09:47

Drawable objects are not inherently serializable, so they cannot be passed directly in Intent extras. You must find another way to serialize or persist the image data and retrieve it in the new Activity.

For example, if you are working with BitmapDrawable instances, the underlying Bitmap could be written out to a file and read back, or serialized into a byte array (if its small enough) and the byte array could be passed via extras of an Intent.

HTH

查看更多
叼着烟拽天下
3楼-- · 2019-01-03 09:55

1) Passing in intent as extras

In the Activity A you decode your image and send it via intent:

  • Using this method (extras) image is passed in 162 milliseconds time interval
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);

In Activity B you receive intent with byte array (decoded picture) and apply it as source to 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) Saving image file and passing its reference to another activity

"The size limit is: keep it as small as possible. Definitely don't put a bitmap in there unless it is no larger than an icon (32x32 or whatever).

  • In *Activity A* save the file (Internal Storage)
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();
}
  • Pass location as String to Activity B
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("picname", fileName);
  • In *Activity B* retrieve the file
Bundle extras = getIntent().getExtras();
String fileName = extras.getString("picname");
  • Make *drawable* out of the picture
File filePath = getFileStreamPath(fileName);
Drawable d = Drawable.createFromPath(filePath.toString());
  • Apply it to the ImageView resource
someImageView.setBackgroundDrawable(d);
查看更多
仙女界的扛把子
4楼-- · 2019-01-03 09:59

You can simply use a native buildDrawingCache method:

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

then get it at your ImageActivity:

    Bundle bundle = getIntent ().getExtras ();

    if (bundle != null) {

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

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

    }
查看更多
做个烂人
5楼-- · 2019-01-03 10:05

You can tag each image (in the xml, or programmaticlly) with the image resource name (like "img1.png"), then retrieve the image name using the getTag();

Then use getResources().getIdentifier(image name,"drawable", .getPackageName()) to get the drawable resource id.

And just pass the resource id through the intent -

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

Lastly the result Activity can create the image from the resource using:

getResources().getDrawable(intent.getIntExtra("img 1",-1));    
查看更多
放我归山
6楼-- · 2019-01-03 10:06

Much much much better not to pass (or serialize) Drawables around among Activities. Very likely your are getting the drawable out of a resource. Hence there's a resource ID. Pass that around instead, that's just an int. And re-hydrate the Drawable in the other Activity.

If the Drawable is not coming from a resource, but it's built at runtime in memory ... well let's speak about it. @Devunwired has a nice suggestion in that case.

查看更多
倾城 Initia
7楼-- · 2019-01-03 10:06

I don't know if this is the case, but if the reason why you are trying to pass a drawable is because you are using an Imageview, just put the resource id in the imageview's tag, pass the tag as an Integer instead of the drawable in the intent's extra and use the following line in the receiving activity: imageView.setImageDrawable(getResources().getDrawable(getIntent().getIntExtra("image_id",0)));

Hope it will help someone.

查看更多
登录 后发表回答