Search code examples
androidimageandroid-studiofresco

Fresco multiple images view


I'm trying to make a customview that displays multiple images into one view with Fresco. I've read the docs and went through some steps but my implementation doesn't seem to work. Here's the code:

public class MultiDraweeView extends View {

    private static final int MAX_COUNT = 4;

    private MultiDraweeHolder<GenericDraweeHierarchy> multiDraweeHolder;
    private ArrayList<GenericDraweeHierarchy> hierarchies;

    public MultiDraweeView(Context context) {
        super(context);
        init();
    }

    public MultiDraweeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MultiDraweeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        multiDraweeHolder = new MultiDraweeHolder<>();
        hierarchies = new ArrayList<>();
        for (int i = 0; i < MAX_COUNT; i++) {
            hierarchies.add(new GenericDraweeHierarchyBuilder(getResources())
                    .build());
        }
    }

    public void setImageUris(Uri... uris) {
        multiDraweeHolder.clear();
        for (int i = 0; i < (uris.length < MAX_COUNT ? uris.length : MAX_COUNT); i++) {
            final int j = i;
            final DraweeHolder<GenericDraweeHierarchy> draweeHolder = DraweeHolder.create(hierarchies.get(i), getContext());
            DraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setUri(Uri.parse("http://www.thewrap.com/wp-content/uploads/2015/11/Donald-Trump.jpg"))
                    .setOldController(draweeHolder.getController())
                    .setControllerListener(new ControllerListener<ImageInfo>() {
                        @Override
                        public void onSubmit(String id, Object callerContext) {
                            Log.e("fresco" + j, "onSubmit");
                        }

                        @Override
                        public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
                            Log.e("fresco" + j, "onFinalImageset");
                            invalidate();
                        }

                        @Override
                        public void onIntermediateImageSet(String id, ImageInfo imageInfo) {
                            Log.e("fresco" + j, "onIntermediateImageSet");
                        }

                        @Override
                        public void onIntermediateImageFailed(String id, Throwable throwable) {
                            Log.e("fresco" + j, "onIntermediateImageFailed");
                        }

                        @Override
                        public void onFailure(String id, Throwable throwable) {
                            Log.e("fresco" + j, "onFailure");
                        }

                        @Override
                        public void onRelease(String id) {
                            Log.e("fresco" + j, "onRelease");
                        }
                    })
                    .build();
            draweeHolder.setController(controller);
            multiDraweeHolder.add(draweeHolder);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.e("fresco", "ondraw");
        for (int i = 0; i < multiDraweeHolder.size(); i++) {
            Drawable drawable = multiDraweeHolder.get(i).getTopLevelDrawable();
            drawable.setBounds(50 * i, 50 * i, 50 * (i + 1), 50 * (i + 1));
            drawable.draw(canvas);
        }
    }

    @Override
    protected boolean verifyDrawable(@NonNull Drawable who) {
        return multiDraweeHolder.verifyDrawable(who);
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        multiDraweeHolder.onDetach();
    }

    @Override
    public void onStartTemporaryDetach() {
        super.onStartTemporaryDetach();
        multiDraweeHolder.onDetach();
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        multiDraweeHolder.onAttach();
    }

    @Override
    public void onFinishTemporaryDetach() {
        super.onFinishTemporaryDetach();
        multiDraweeHolder.onAttach();
    }
}

The logic behind my code is to invalidate the view as soon as the image downloads inonFinalImageSetso it redraws. But the Drawables are not drawing. If then i send the app to the background and open it again so onStart is called again, the Drawables show. Am I missing something here, or is there any example of a custom DraweView that extends View and not ImageView?


Solution

  • You need to set the Drawable.Callback as described here: http://frescolib.org/docs/writing-custom-views.html

    Also, make sure that the callback actually invalidates the correct are. If you invalidate the wrong one, it won't work either.