9

I still don't know if this is a bug report or a feature request, so bear with me.

I'm using Picasso and I've noticed that the sample application always fades in from the previous image (see here for a demo of what I mean). However, I would like it to always fade in from a given placeholder.

My guess for this behaviour is that the views of the grid are recycled and Picasso does not set the placeholder before fading in to the actual image.

Is this on purpose? How would I be able to always fade in from a placeholder?

Sebastiano
  • 12,289
  • 6
  • 47
  • 80
  • I +1-ed to counterbalance an unexplained -1. – Nicola Miotto Feb 28 '14 at 15:46
  • 1
    What version of Picasso? – Jake Wharton Feb 28 '14 at 16:58
  • I'm using the 2.2.1 version. Actually, I've forked the original project in order to add support for rounded drawables (using Romain Guy's technique), but this "issue" occurs with the standard PicassoDrawable implementation. – Sebastiano Mar 01 '14 at 18:06
  • @JakeWharton Should I open a ticket on Picasso's GitHub page or is this more of a feature request? – Sebastiano Mar 04 '14 at 15:48
  • I cannot reproduce this behavior on `master`. Are you sure that your modifications have not caused this behavior? – Jake Wharton Mar 04 '14 at 17:20
  • all thats needed is a Transformation class which does the transformation for you. https://gist.github.com/julianshen/5829333 (CircleTransformation) https://gist.github.com/aprock/6213395 (RoundedCorner Transformation) – Lalith B Mar 07 '14 at 05:03
  • 2.2.1 has not been released yet. Perhaps this was an intermittent development issue. The sample app does not exhibit this behavior. Do you still have a problem? – dnkoutso Apr 18 '14 at 15:53
  • @dnkoutso I truly hadn't the time to merge with `master` and try again. I will update this post ASAP. – Sebastiano Apr 21 '14 at 14:23
  • @JakeWharton I don't think so, but as I wrote in my previous comment, I will try again when I have some spare time. – Sebastiano Apr 21 '14 at 14:23
  • @dextor any updates / conclusions ? – Ovidiu Latcu Aug 18 '14 at 09:53

2 Answers2

2

Picasso suport some fade animation in specific case. However, it was not working for me because I'me using a custom Target with picasso which allow me to set background drawable.

I've copied PicassocDrawable which have a nice fade animation and add public constructor.

/* Copyright (C) 2013 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example.app;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.SystemClock;
import android.widget.ImageView;

/**
 * Changelog :
 * - Modified from Picasso 2.5.0 to allow public instantiation
 */
public class CustomPicassoDrawable extends BitmapDrawable{
    // Only accessed from main thread.
    private static final Paint DEBUG_PAINT = new Paint();
    private static final float FADE_DURATION = 200f; //ms

    /**
     * Create or update the drawable on the target {@link android.widget.ImageView} to display the supplied bitmap
     * image.
     */
    static void setBitmap(ImageView target, Context context, Bitmap bitmap) {
        Drawable placeholder = target.getDrawable();
        if (placeholder instanceof AnimationDrawable) {
            ((AnimationDrawable) placeholder).stop();
        }
        CustomPicassoDrawable drawable =
                new CustomPicassoDrawable(context, bitmap, placeholder);
        target.setImageDrawable(drawable);
    }

    /**
     * Create or update the drawable on the target {@link ImageView} to display the supplied
     * placeholder image.
     */
    static void setPlaceholder(ImageView target, Drawable placeholderDrawable) {
        target.setImageDrawable(placeholderDrawable);
        if (target.getDrawable() instanceof AnimationDrawable) {
            ((AnimationDrawable) target.getDrawable()).start();
        }
    }

    private final float density;

    Drawable placeholder;

    long startTimeMillis;
    boolean animating;
    int alpha = 0xFF;

    public CustomPicassoDrawable(Context context, Bitmap bitmap, Drawable placeholder) {
        super(context.getResources(), bitmap);

        this.density = context.getResources().getDisplayMetrics().density;

        this.placeholder = placeholder;
        animating = true;
        startTimeMillis = SystemClock.uptimeMillis();
    }

    @Override public void draw(Canvas canvas) {
        if (!animating) {
            super.draw(canvas);
        } else {
            float normalized = (SystemClock.uptimeMillis() - startTimeMillis) / FADE_DURATION;
            if (normalized >= 1f) {
                animating = false;
                placeholder = null;
                super.draw(canvas);
            } else {
                if (placeholder != null) {
                    placeholder.draw(canvas);
                }

                int partialAlpha = (int) (alpha * normalized);
                super.setAlpha(partialAlpha);
                super.draw(canvas);
                super.setAlpha(alpha);
                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
                    invalidateSelf();
                }
            }
        }
    }

    @Override public void setAlpha(int alpha) {
        this.alpha = alpha;
        if (placeholder != null) {
            placeholder.setAlpha(alpha);
        }
        super.setAlpha(alpha);
    }

    @Override public void setColorFilter(ColorFilter cf) {
        if (placeholder != null) {
            placeholder.setColorFilter(cf);
        }
        super.setColorFilter(cf);
    }

    @Override protected void onBoundsChange(Rect bounds) {
        if (placeholder != null) {
            placeholder.setBounds(bounds);
        }
        super.onBoundsChange(bounds);
    }
}

You can use it with

Picasso
.with(this)
.load("http://yourimage")
.into(new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        CustomPicassoDrawable drawable = new CustomPicassoDrawable(
                FullscreenActivity.this, bitmap, myBackground);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
            myView.setBackground(drawable);
        } else {
            myView.setBackgroundDrawable(drawable);
        }
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {}

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {}
});
Hugo Gresse
  • 17,195
  • 9
  • 77
  • 119
  • ViewUtils.setBackground(mNativeVideoLayout, drawable); What is ViewUtils and mNativeVideoLayout – Android Dec 28 '15 at 06:29
-1
Picasso.with(this).load(image URL)
.placeholder(place_holder_bitmap).error(place_holder_bitmap)
.resize(call resize method here to pass new pixels constraint, getPixels(30))
.transform(transformation).into(imageView);

Here Transformation is applied to make circular image view in my case, ignore this part of code if not important in your project.

peter_budo
  • 1,748
  • 4
  • 26
  • 48