4

I have seen similar questions to that but most of them show passing bitmap between activities. Referring to this question, the accepted answer does not recommend using bundle while passing bitmap between two activities and suggest using intent extras instead. But since i am trying to pass bitmap between fragments, not activities, i cannot use intents and do not know what else to use other than bundle. Here is what i do to pass Bitmap between fragments: I pass bitmap to the activity through an interface, and then pass it to other fragment inside that interface.

//MyActivity.java

@Override
public void onMyFragmentFired(Bitmap bitmap) {
    FragmentTransaction ft=getSupportFragmentManager().beginTransaction();
    args=new Bundle();
    fragment = MyFragment.newInstance();

    if(bitmap != null){
        args.putParcelable("EXTRA_BITMAP", bitmap);
    }

    fragment.setArguments(args);

    ft.add(fragment, "com.example.myfragment");
    ft.commit();
}

I wonder whether i face any problems if bitmap is too large etc. Is there a better way to do this?

Thanks

Community
  • 1
  • 1
yrazlik
  • 10,411
  • 33
  • 99
  • 165
  • 3
    Why don't you keep the reference to your bitmap in `Activity` that hosts you fragments? And then you simply can create a getter for that bitmap, and get it in every fragment, attached to that activity, like this `((MyActivity) getActivity()).getBitmap()`. – romtsn Jun 11 '15 at 10:52
  • @rom4ek good idea, i will try it now – yrazlik Jun 11 '15 at 11:00

4 Answers4

2

Late answer. But could help others.

Another approach that could be tested is converting your Bitmap to a Base64 string. Then you send it to the fragment while you create it.

Encode the bitmap

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
    byte[] byteArray = byteArrayOutputStream .toByteArray();
    String encodedBitmap = Base64.encodeToString(byteArray, Base64.DEFAULT);

Above code will create a long string that you can use.

Then you can pass it as a bundle argument in the fragments newInstance() function.

Then you can decode the string again to get the Bitmap image

Decoding the image

byte[] decodedString = Base64.decode(encodedBitmap, Base64.DEFAULT);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
Jemil Riahi
  • 1,360
  • 5
  • 18
  • 38
  • 3
    Base64 encoded strings take more space on memory than the binary image itself. So please avoid this method. – Gunhan Feb 05 '19 at 15:45
1

You can add the bitmap to the newInstance function.

So you can have

Bitmap mBitmap;

public static newInstance(Bitmap b)
{
     mBitmap = b;
}

and call the

if(bitmap!=null)
{
     fragment = MyFragment.newInstance(bitmap);
}

Add a bitmap variable as well in the constructor of your fragment.

Hamilton
  • 152
  • 6
  • How do reference the non-static field `mBitmap` from a static method `newInstance()`? This will not work at all. – fahmy Mar 17 '16 at 10:09
1

I managed to pass the bitmap using Android Architecture Components and having a shared ViewModel between fragments as explained in the official docs about sharing data between fragments. I do not know if it is the best practice but for my use case it works.

dnhyde
  • 1,265
  • 2
  • 14
  • 24
0

I've had lots of issues about passing the data to acitvity or fragment mutually. As a result, I made DataCache pass any object anywhere.

but I've never tried passing Bitmap between Fragments. I think this will work for you. this is super easy example. Gihub : https://github.com/kimkevin/cachepot

Fragment for Sender

public class FragmentA {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DataCache.getInstance().push(yourBitmap);
    }
}

Fragment for Receiver

public class FragmentB {
    @Override
    public void onCreate(Bundle savedInstanceState) {           
        super.onCreate(savedInstanceState);
        Bitmap yourBitmap = DataCache.getInstance().pop(Bitmap.class);
    }
}

try it :D I hope you to help.

kimkevin
  • 2,202
  • 1
  • 26
  • 48