0

In my app the user can pick a image from the gallery and set it to the background of a RelativeLayout. But the image is never immediately set as to the background in my onActivityResult() method as supposed to when I load the bitmap of the choosen picture with picasso to my view.

Here is a screenrecord video of the problem: https://www.youtube.com/watch?v=jABnheTV0IU

But when this method inside my RecyclerView Adapter is called the image is set as background to the RelativeLayout immediately:

    @Override
    public void onClick(final View v) {

        int position = getLayoutPosition();
        String path = PreferenceManager.getDefaultSharedPreferences(context).getString(App.IMAGE_URI,"");

        /*
        This put the current selected image from the gallery as background
         */
        if (position == 0 && !path.isEmpty()) {

            Picasso.with(context).load(path).centerCrop().resize(view.getWidth(), view.getHeight()).into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    view.setBackground(new BitmapDrawable(bitmap));
                }

                @Override
                public void onBitmapFailed(Drawable errorDrawable) {

                }

                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {

                }
            });

the onActivityResult in my MainActivity class.

@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent data) {


    if (resultCode == RESULT_OK && requestCode == 1 && data.getData() !=null) {

        PreferenceManager.getDefaultSharedPreferences(this).edit().putString(App.IMAGE_URI, data.getData().toString()).apply();

        Picasso.with(this).load(data.getData()).centerCrop().resize(width, height).into(new Target() {
            @Override
            public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {

            //this is never called or dosn't work
            relativeLayout.setBackground(new BitmapDrawable(bitmap));


            }

            @Override
            public void onBitmapFailed(Drawable errorDrawable) {

            }

            @Override
            public void onPrepareLoad(Drawable placeHolderDrawable) {

            }
        });

    }
}
  • Just underneath here (if (resultCode == RESULT_OK && requestCode == 1 && data.getData() !=null) {) add (Log.i("Running", "Running");) and in the Logcat Search type (Running) -- do you see Running when you go back to the Main Activity?? if you dont then this is wrong (if (resultCode == RESULT_OK && requestCode == 1 && data.getData() !=null) – Tasos Aug 31 '16 at 20:00
  • @Tasos Yes "Running" appears in the logcat when I choose an image from gallary and it returns back. –  Aug 31 '16 at 20:04
  • then type picasso in the search -- any errors?? – Tasos Aug 31 '16 at 20:08
  • @Tasos No everything seems fine.. I think its the setbackground() method inside onBitmapLoaded, that dosn't update the background.. I don't think its picasso that the problem –  Aug 31 '16 at 20:15
  • Where is the recycler view? and where is startActivityForResult called? – Nick Cardoso Aug 31 '16 at 20:28
  • @NickCardoso the solution below works! But startActivityForResult is called in the recyclerview's adapter for button indeks 0 –  Aug 31 '16 at 20:31

1 Answers1

0

According this Picasso only keeps a weak reference to the Target object. Which mean that you need to make hard reference to it somewhere. Make Target as MainActivity class memeber. So call to load will look like so:

//Create Target right before it's needed
mTarget = new Target() {/*same as in your question*/};
Picasso.with(this).load(data.getData()).centerCrop().resize(width, height).into(mTarget);

Or you could declarate following inner class

private static ViewTarget implement Target {
    private View mView;
    public ViewTarget(View view) {
        mView = view;
    }

    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        mView.setBackground(new BitmapDrawable(bitmap));
    }
};

And use it like so:

mTarget = new ViewTarget(relativeLayout);
Picasso.with(this).load(data.getData()).centerCrop().resize(width, height).into(mTarget);
Community
  • 1
  • 1
j2ko
  • 2,479
  • 1
  • 16
  • 29
  • How would I load the Bitmap into my RelativeLayout.setbackground();? –  Aug 31 '16 at 20:06
  • Nice it worked! Could you give me a good explantion why this works and not the other? –  Aug 31 '16 at 20:29
  • 1
    Can't say precise but looks like for first case Picasso load image between GC calls so reference to `Target` survives. Actually I suggest you to update `onClick()` code in the same way to make it bullet proof. – j2ko Aug 31 '16 at 20:45