/* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ package com.facebook.drawee.view; import java.util.ArrayList; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.view.MotionEvent; import android.view.View; import com.facebook.common.internal.Lists; import com.facebook.common.internal.Preconditions; import com.facebook.common.internal.VisibleForTesting; import com.facebook.drawee.interfaces.DraweeHierarchy; /** * Contains multiple Drawee holders. * * <p>Intended for use in custom views that are showing more than one hierarchy. * * Users of this class must< call {@link Drawable#setBounds} on the top-level drawable * of each DraweeHierarchy in this holder. Otherwise the drawables will not be drawn. * <p>The containing view must also call {@link #onDetach()} from its * {@link View#onStartTemporaryDetach()} and {@link View#onDetachedFromWindow()} methods. It must * call {@link #onAttach} from its {@link View#onFinishTemporaryDetach()} and * {@link View#onAttachedToWindow()} methods. */ public class MultiDraweeHolder<DH extends DraweeHierarchy> { @VisibleForTesting boolean mIsAttached = false; @VisibleForTesting ArrayList<DraweeHolder<DH>> mHolders = Lists.newArrayList(); /** * Gets the controller ready to display the images. * * <p>The containing view must call this method from both {@link View#onFinishTemporaryDetach()} * and {@link View#onAttachedToWindow()}. */ public void onAttach() { if (mIsAttached) { return; } mIsAttached = true; for (int i = 0; i < mHolders.size(); ++i) { mHolders.get(i).onAttach(); } } /** * Releases resources used to display the image. * * <p>The containing view must call this method from both {@link View#onStartTemporaryDetach()} * and {@link View#onDetachedFromWindow()}. */ public void onDetach() { if (!mIsAttached) { return; } mIsAttached = false; for (int i = 0; i < mHolders.size(); ++i) { mHolders.get(i).onDetach(); } } public boolean onTouchEvent(MotionEvent event) { for (int i = 0; i < mHolders.size(); ++i) { if (mHolders.get(i).onTouchEvent(event)) { return true; } } return false; } public void clear() { if (mIsAttached) { for (int i = 0; i < mHolders.size(); ++i) { mHolders.get(i).onDetach(); } } mHolders.clear(); } public void add(DraweeHolder<DH> holder) { add(mHolders.size(), holder); } public void add(int index, DraweeHolder<DH> holder) { Preconditions.checkNotNull(holder); Preconditions.checkElementIndex(index, mHolders.size() + 1); mHolders.add(index, holder); if (mIsAttached) { holder.onAttach(); } } public void remove(int index) { DraweeHolder<DH> holder = mHolders.get(index); if (mIsAttached) { holder.onDetach(); } mHolders.remove(index); } public DraweeHolder<DH> get(int index) { return mHolders.get(index); } public int size() { return mHolders.size(); } /** Convenience method to draw all the top-level drawables in this holder. */ public void draw(Canvas canvas) { for (int i = 0; i < mHolders.size(); ++i) { Drawable drawable = get(i).getTopLevelDrawable(); if (drawable != null) { drawable.draw(canvas); } } } /** Returns true if the argument is a top-level Drawable in this holder. */ public boolean verifyDrawable(Drawable who) { for (int i = 0; i < mHolders.size(); ++i) { if (who == get(i).getTopLevelDrawable()) { return true; } } return false; } }