Glide源码阅读之模板模式1

定义

菜鸟教程

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

UML图
在这里插入图片描述

大话设计模式

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

UML图
在这里插入图片描述

《Android源码设计模式解析与实践》
在这里插入图片描述

使用场景

  1. 多个子类有公有的方法,并且逻辑基本相同时
  2. 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
  3. 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数约束行为

Glide模板模式应用

LifecycleListener

包路径:com.bumptech.glide.manager.LifecycleListener
一个用于侦听Fragment和Activity生命周期事件的接口。


/**
 * An interface for listener to {@link android.app.Fragment} and {@link android.app.Activity}
 * lifecycle events.
 */
 一个用于侦听FragmentActivity生命周期事件的接口。
public interface LifecycleListener {

  /**
   * Callback for when {@link android.app.Fragment#onStart()}} or {@link
   * android.app.Activity#onStart()} is called.
   */
  void onStart();

  /**
   * Callback for when {@link android.app.Fragment#onStop()}} or {@link
   * android.app.Activity#onStop()}} is called.
   */
  void onStop();

  /**
   * Callback for when {@link android.app.Fragment#onDestroy()}} or {@link
   * android.app.Activity#onDestroy()} is called.
   */
  void onDestroy();
}

Target 接口继承
包路径:com.bumptech.glide.request.target.Target


/**
 * An interface that Glide can load a resource into and notify of relevant lifecycle events during a
 * load.
 *
 * <p>The lifecycle events in this class are as follows:
 *
 * <ul>
 *   <li>onLoadStarted
 *   <li>onResourceReady
 *   <li>onLoadCleared
 *   <li>onLoadFailed
 * </ul>
 *
 * The typical lifecycle is onLoadStarted -> onResourceReady or onLoadFailed -> onLoadCleared.
 * However, there are no guarantees. onLoadStarted may not be called if the resource is in memory or
 * if the load will fail because of a null model object. onLoadCleared similarly may never be called
 * if the target is never cleared. See the docs for the individual methods for details.
 *
 * @param <R> The type of resource the target can display.
 */
 这个接口可以让Glide加载资源,并在加载期间通知相关的生命周期事件。
这个类中的生命周期事件如下:

onLoadStarted
onResourceReady
onLoadCleared
onLoadFailed
典型的生命周期是onLoadStarted -> onResourceReady或onLoadFailed -> onLoadCleared。然而,这并不能保证。如果资源在内存中,或者由于一个空模型对象导致加载失败,onLoadStarted可能不会被调用。同样,如果目标从未被清除,onLoadCleared也可能永远不会被调用。有关详细信息,请参阅文档中的各个方法。
public interface Target<R> extends LifecycleListener {
  /** Indicates that we want the resource in its original unmodified width and/or height. */
  int SIZE_ORIGINAL = Integer.MIN_VALUE;

  /**
   * A lifecycle callback that is called when a load is started.
   *
   * <p>Note - This may not be called for every load, it is possible for example for loads to fail
   * before the load starts (when the model object is null).
   *
   * <p>Note - This method may be called multiple times before any other lifecycle method is called.
   * Loads can be paused and restarted due to lifecycle or connectivity events and each restart may
   * cause a call here.
   *
   * @param placeholder The placeholder drawable to optionally show, or null.
   */
   当加载启动时调用的生命周期回调。
注意:这可能不会在每次加载时都被调用,例如,在加载开始之前(当模型对象为空时),可能会出现加载失败。

注意:在调用任何其他生命周期方法之前,这个方法可能会被多次调用。由于生命周期或连接事件,负载可以暂停或重新启动,每次重新启动都可能导致这里的调用。

参数:
占位符-可选择显示的占位符,或为空。
  void onLoadStarted(@Nullable Drawable placeholder);

  /**
   * A <b>mandatory</b> lifecycle callback that is called when a load fails.
   *
   * <p>Note - This may be called before {@link #onLoadStarted(android.graphics.drawable.Drawable) }
   * if the model object is null.
   *
   * <p>You <b>must</b> ensure that any current Drawable received in {@link #onResourceReady(Object,
   * Transition)} is no longer used before redrawing the container (usually a View) or changing its
   * visibility.
   *
   * @param errorDrawable The error drawable to optionally show, or null.
   */
   强制的生命周期回调,在加载失败时调用。
注意-如果模型对象为空,这可能会在onLoadStarted(android.graphics.drawable.Drawable)之前调用。

你必须确保在重新绘制容器(通常是一个视图)或改变它的可见性之前,在onResourceReady(Object, Transition)中接收到的任何当前的Drawable都不再使用。

参数:
errorDrawable -可选择显示的错误,或为空。
  void onLoadFailed(@Nullable Drawable errorDrawable);

  /**
   * The method that will be called when the resource load has finished.
   *
   * @param resource the loaded resource.
   */
   当资源加载完成时将被调用的方法。
参数:
Resource -加载的资源。
  void onResourceReady(@NonNull R resource, @Nullable Transition<? super R> transition);

  /**
   * A <b>mandatory</b> lifecycle callback that is called when a load is cancelled and its resources
   * are freed.
   *
   * <p>You <b>must</b> ensure that any current Drawable received in {@link #onResourceReady(Object,
   * Transition)} is no longer used before redrawing the container (usually a View) or changing its
   * visibility.
   *
   * @param placeholder The placeholder drawable to optionally show, or null.
   */
   强制的生命周期回调,在取消负载并释放其资源时调用。
你必须确保在重新绘制容器(通常是一个视图)或改变它的可见性之前,在onResourceReady(Object, Transition)中接收到的任何当前的Drawable都不再使用。

参数:
占位符-可选择显示的占位符,或为空。
  void onLoadCleared(@Nullable Drawable placeholder);

  /**
   * A method to retrieve the size of this target.
   *
   * @param cb The callback that must be called when the size of the target has been determined
   */
   检索此目标的大小的方法。
参数:
cb -当目标的大小已经确定时必须调用的回调函数
  void getSize(@NonNull SizeReadyCallback cb);

  /**
   * Removes the given callback from the pending set if it's still retained.
   *
   * @param cb The callback to remove.
   */
   如果给定的回调函数仍然被保留,则从挂起的回调函数集中删除它。
参数:
cb -要删除的回调函数。
  void removeCallback(@NonNull SizeReadyCallback cb);

  /** Sets the current request for this target to retain, should not be called outside of Glide. */
  设置当前请求为此目标保留,不应在Glide外调用。
  void setRequest(@Nullable Request request);

  /** Retrieves the current request for this target, should not be called outside of Glide. */
  为该目标检索当前请求,不应在Glide外部调用。
  @Nullable
  Request getRequest();
}

LifecycleListener已知的实现类列表如下:

  1. AppWidgetTarget
  2. BaseTarget
  3. BitmapImageViewTarget
  4. BitmapThumbnailImageViewTarget
  5. CustomTarget
  6. CustomViewTarget
  7. DrawableImageViewTarget
  8. DrawableThumbnailImageViewTarget
  9. ImageViewTarget
  10. NotificationTarget
  11. PreloadTarget
  12. RequestFutureTarget
  13. RequestManager
  14. SimpleTarget
  15. TargetTracker
  16. ThumbnailImageViewTarget
  17. ViewTarget

CustomTarget

先看看CustomTarget
用于加载视图之外的资源(位图,Drawable等)的基本目标。
如果你要把资源加载到视图中,使用RequestBuilder.into(ImageView), ImageViewTarget的子类,或者CustomViewTarget。使用这个类将资源加载到视图中会阻止Glide正确取消之前的任何加载,这可能会导致视图中出现不正确的图像,特别是在像RecyclerView这样的滚动视图中。

你必须实现target . onloadcleared (Drawable),并确保所有对任何资源的引用都传递到target中。onResourceReady(Object, Transition)在Target.onLoadCleared(Drawable)完成之前被移除。如果不这样做,可能会导致图像损坏,回收位图导致的崩溃,以及其他未定义的行为。让Target.onLoadCleared(Drawable)未实现或为空永远都不安全。即使你没有手动清除这个目标,在fragment和activity的某些生命周期事件之后,Glide也会自动清除。

该类只能与Target一起使用。SIZE_ORIGINAL,或者在创建目标时知道所需的资源维度。如果你想运行一些异步进程,并充分利用getSize(SizeReadyCallback)和SizeReadyCallback,直接扩展Target而不是使用这个类。


/**
 * A base {@link Target} for loading resources ({@link android.graphics.Bitmap}, {@link Drawable}
 * etc) that are used outside of {@link android.view.View}s.
 *
 * <p>If you're loading a resource into a {@link View}, use {@link
 * com.bumptech.glide.RequestBuilder#into(ImageView)}, a subclass of {@link ImageViewTarget}, or
 * {@link CustomViewTarget}. Using this class to load resources into {@link View}s can prevent Glide
 * from correctly cancelling any previous loads, which may result in incorrect images appearing in
 * the view, especially in scrolling views like {@link androidx.recyclerview.widget.RecyclerView}.
 *
 * <p>You <em>MUST</em> implement {@link #onLoadCleared(Drawable)} and ensure that all references to
 * any resource passed into the target in {@link #onResourceReady(Object, Transition)} are removed
 * before {@link #onLoadCleared(Drawable)} completes. Failing to do so can result in graphical
 * corruption, crashes caused by recycled {@link Bitmap}s, and other undefined behavior. It is never
 * safe to leave {@link #onLoadCleared(Drawable)} unimplemented or empty. Even if you do not
 * manually clear this {@link Target}, Glide may do so automatically after certain lifecycle events
 * in {@link androidx.fragment.app.Fragment}s and {@link android.app.Activity}s.
 *
 * <p>This class can only be used with {@link Target#SIZE_ORIGINAL} or when the desired resource
 * dimensions are known when the {@link Target} is created. If you'd like to run some asynchronous
 * process and make full use of {@link #getSize(SizeReadyCallback)} and {@link SizeReadyCallback},
 * extend {@link Target} directly instead of using this class.
 *
 * @param <T> The type of resource that will be loaded (e.g. {@link Bitmap}).
 */
 用于加载视图之外的资源(位图,Drawable)的基本目标。
如果你要把资源加载到视图中,使用RequestBuilder.into(ImageView)ImageViewTarget的子类,或者CustomViewTarget。使用这个类将资源加载到视图中会阻止Glide正确取消之前的任何加载,这可能会导致视图中出现不正确的图像,特别是在像RecyclerView这样的滚动视图中。

你必须实现target . onloadcleared (Drawable),并确保所有对任何资源的引用都传递到target中。onResourceReady(Object, Transition)Target.onLoadCleared(Drawable)完成之前被移除。如果不这样做,可能会导致图像损坏,回收位图导致的崩溃,以及其他未定义的行为。让Target.onLoadCleared(Drawable)未实现或为空永远都不安全。即使你没有手动清除这个目标,在fragment和activity的某些生命周期事件之后,Glide也会自动清除。

该类只能与Target一起使用。SIZE_ORIGINAL,或者在创建目标时知道所需的资源维度。如果你想运行一些异步进程,并充分利用getSize(SizeReadyCallback)SizeReadyCallback,直接扩展Target而不是使用这个类。
类型参数:
将被加载的资源类型(例如位图)public abstract class CustomTarget<T> implements Target<T> {

  private final int width;
  private final int height;

  @Nullable private Request request;

  /**
   * Creates a new {@link CustomTarget} that will attempt to load the resource in its original size.
   *
   * <p>This constructor can cause very memory inefficient loads if the resource is large and can
   * cause OOMs. It's provided as a convenience for when you'd like to specify dimensions with
   * {@link com.bumptech.glide.request.RequestOptions#override(int)}. In all other cases, prefer
   * {@link #CustomTarget(int, int)}.
   */
   创建一个新的CustomTarget,它将尝试以原始大小加载资源。
如果资源很大,这个构造函数可能会导致非常低效的内存负载,并可能导致OOMs。当你想要使用BaseRequestOptions.override(int)指定尺寸时,可以方便地使用它。在所有其他情况下,最好使用CustomTarget(int, int)public CustomTarget() {
    this(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
  }

  /**
   * Creates a new {@code CustomTarget} that will return the given {@code width} and {@code height}
   * as the requested size (unless overridden by {@link
   * com.bumptech.glide.request.RequestOptions#override(int)} in the request).
   *
   * @param width The requested width (> 0, or == Target.SIZE_ORIGINAL).
   * @param height The requested height (> 0, or == Target.SIZE_ORIGINAL).
   * @throws IllegalArgumentException if width/height doesn't meet (> 0, or == Target.SIZE_ORIGINAL)
   */
   创建一个新的CustomTarget,它将返回给定的宽度和高度作为请求的大小(除非在请求中被BaseRequestOptions.override(int)覆盖)。
参数:
width -请求的宽度(> 0,或== Target.SIZE_ORIGINAL)。
height -请求的高度(> 0,或== Target.SIZE_ORIGINAL)。
抛出:
java.lang.IllegalArgumentException -如果宽度/高度不满足(> 0,或== Target.SIZE_ORIGINAL)
  public CustomTarget(int width, int height) {
    if (!Util.isValidDimensions(width, height)) {
      throw new IllegalArgumentException(
          "Width and height must both be > 0 or Target#SIZE_ORIGINAL, but given"
              + " width: "
              + width
              + " and height: "
              + height);
    }

    this.width = width;
    this.height = height;
  }

  @Override
  public void onStart() {
    // Intentionally empty, this can be optionally implemented by subclasses.
  }

  @Override
  public void onStop() {
    // Intentionally empty, this can be optionally implemented by subclasses.
  }

  @Override
  public void onDestroy() {
    // Intentionally empty, this can be optionally implemented by subclasses.
  }

  @Override
  public void onLoadStarted(@Nullable Drawable placeholder) {
    // Intentionally empty, this can be optionally implemented by subclasses.
  }

  @Override
  public void onLoadFailed(@Nullable Drawable errorDrawable) {
    // Intentionally empty, this can be optionally implemented by subclasses.
  }

  @Override
  public final void getSize(@NonNull SizeReadyCallback cb) {
    cb.onSizeReady(width, height);
  }

  @Override
  public final void removeCallback(@NonNull SizeReadyCallback cb) {
    // Do nothing, this class does not retain SizeReadyCallbacks.
  }

  @Override
  public final void setRequest(@Nullable Request request) {
    this.request = request;
  }

  @Nullable
  @Override
  public final Request getRequest() {
    return request;
  }
}

AppWidgetTarget

包路径:com.bumptech.glide.request.target.AppWidgetTarget

/**
 * This class is used in order to display downloaded Bitmap inside an ImageView of an AppWidget
 * through RemoteViews.
 *
 * <p>Note - For cancellation to work correctly, you must pass in the same instance of this class
 * for every subsequent load.
 */
// Public API.
@SuppressWarnings("WeakerAccess")
public class AppWidgetTarget extends CustomTarget<Bitmap> {

接着看AppWidgetTarget后续

。。。。
/** Updates the AppWidget after the ImageView has loaded the Bitmap. */ImageView加载位图后更新AppWidgetprivate void update() {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.context);
    if (this.componentName != null) {
      appWidgetManager.updateAppWidget(this.componentName, this.remoteViews);
    } else {
      appWidgetManager.updateAppWidget(this.widgetIds, this.remoteViews);
    }
  }
  @Override
  public void onResourceReady(
      @NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
    setBitmap(resource);
  }

  @Override
  public void onLoadCleared(@Nullable Drawable placeholder) {
    setBitmap(null);
  }

  private void setBitmap(@Nullable Bitmap bitmap) {
    this.remoteViews.setImageViewBitmap(viewId, bitmap);
    update();
  }
  。。。。

BaseTarget

@Deprecated 弃用了

一个用于加载资源的基本目标,它为大多数方法提供基本的或空的实现。
为了提高效率,当您使用RequestManager.clear(target)完成使用或显示加载到其中的资源时,清除这个目标。

为了将资源加载到视图中,ViewTarget或ImageViewTarget是最好的。


/**
 * A base {@link Target} for loading {@link com.bumptech.glide.load.engine.Resource}s that provides
 * basic or empty implementations for most methods.
 *
 * <p>For maximum efficiency, clear this target when you have finished using or displaying the
 * {@link com.bumptech.glide.load.engine.Resource} loaded into it using {@link
 * com.bumptech.glide.RequestManager#clear(Target)}.
 *
 * <p>For loading {@link com.bumptech.glide.load.engine.Resource}s into {@link android.view.View}s,
 * {@link com.bumptech.glide.request.target.ViewTarget} or {@link
 * com.bumptech.glide.request.target.ImageViewTarget} are preferable.
 *
 * @param <Z> The type of resource that will be received by this target.
 * @deprecated Use {@link CustomViewTarget} if loading the content into a view, the download API if
 *     in the background
 *     (http://bumptech.github.io/glide/doc/getting-started.html#background-threads), or a a fully
 *     implemented {@link Target} for any specialized use-cases. Using BaseView is unsafe if the
 *     user does not implement {@link #onLoadCleared}, resulting in recycled bitmaps being
 *     referenced from the UI and hard to root-cause crashes.
 */
@Deprecated
public abstract class BaseTarget<Z> implements Target<Z> {

ViewTarget

用于将位图加载到视图中的基本目标,它为大多数方法提供了默认实现,并可以使用ViewTreeObserver.OnDrawListener来确定视图的大小。
为了检测ListView或任何重用视图的ViewGroup中的视图重用,这个类使用View. settag (Object)方法来存储一些元数据,以便在视图被重用时,任何以前的加载或以前加载的资源都可以被取消或重用。

任何对View的View. settag (Object)}的调用都会导致过多的分配和/或illegalargumentexception。如果你必须在视图上调用view . settag (Object),使用setTagId(int)为Glide指定一个自定义标签。

子类必须在onLoadCleared(Drawable)中调用super


/**
 * A base {@link Target} for loading {@link android.graphics.Bitmap}s into {@link View}s that
 * provides default implementations for most most methods and can determine the size of views using
 * a {@link android.view.ViewTreeObserver.OnDrawListener}.
 *
 * <p>To detect {@link View} reuse in {@link android.widget.ListView} or any {@link
 * android.view.ViewGroup} that reuses views, this class uses the {@link View#setTag(Object)} method
 * to store some metadata so that if a view is reused, any previous loads or resources from previous
 * loads can be cancelled or reused.
 *
 * <p>Any calls to {@link View#setTag(Object)}} on a View given to this class will result in
 * excessive allocations and and/or {@link IllegalArgumentException}s. If you must call {@link
 * View#setTag(Object)} on a view, use {@link #setTagId(int)} to specify a custom tag for Glide to
 * use.
 *
 * <p>Subclasses must call super in {@link #onLoadCleared(Drawable)}
 *
 * @param <T> The specific subclass of view wrapped by this target.
 * @param <Z> The resource type this target will receive.
 * @deprecated Use {@link CustomViewTarget}. Using this class is unsafe without implementing {@link
 *     #onLoadCleared} and results in recycled bitmaps being referenced from the UI and hard to
 *     root-cause crashes.
 */
 用于将位图加载到视图中的基本目标,它为大多数方法提供了默认实现,并可以使用ViewTreeObserver.OnDrawListener来确定视图的大小。
为了检测ListView或任何重用视图的ViewGroup中的视图重用,这个类使用View. settag (Object)方法来存储一些元数据,以便在视图被重用时,任何以前的加载或以前加载的资源都可以被取消或重用。

任何对ViewView. settag (Object)}的调用都会导致过多的分配和/或illegalargumentexception。如果你必须在视图上调用view . settag (Object),使用setTagId(int)Glide指定一个自定义标签。

子类必须在onLoadCleared(Drawable)中调用super
@Deprecated
public abstract class ViewTarget<T extends View, Z> extends BaseTarget<Z> {

ImageViewTarget

在ImageViews中显示资源的基本目标。


/**
 * A base {@link com.bumptech.glide.request.target.Target} for displaying resources in {@link
 * android.widget.ImageView}s.
 *
 * @param <Z> The type of resource that this target will display in the wrapped {@link
 *     android.widget.ImageView}.
 */ImageViews中显示资源的基本目标。
// Public API.
@SuppressWarnings("WeakerAccess")
public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
    implements Transition.ViewAdapter {

BitmapImageViewTarget

包路径:com.bumptech.glide.request.target.BitmapImageViewTarget
一个可以在ImageView中显示位图的目标。


/**
 * A {@link com.bumptech.glide.request.target.Target} that can display an {@link
 * android.graphics.Bitmap} in an {@link android.widget.ImageView}.
 */
 一个可以在ImageView中显示位图的目标。
public class BitmapImageViewTarget extends ImageViewTarget<Bitmap> {
  // Public API.
  @SuppressWarnings("WeakerAccess")
  public BitmapImageViewTarget(ImageView view) {
    super(view);
  }

  /** @deprecated Use {@link #waitForLayout()} instead. */
  // Public API.
  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public BitmapImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  /**
   * Sets the {@link android.graphics.Bitmap} on the view using {@link
   * android.widget.ImageView#setImageBitmap(android.graphics.Bitmap)}.
   *
   * @param resource The bitmap to display.
   */
   使用ImageView.setImageBitmap(android.graphics.Bitmap)设置视图的位图。
规定:
在类ImageViewTarget<android.graphics.Bitmap>
参数:
resource -要显示的位图。
  @Override
  protected void setResource(Bitmap resource) {
    view.setImageBitmap(resource);
  }
}

ThumbnailImageViewTarget


/**
 * Avoids extra calls to {@link android.view.View#requestLayout} when loading more than once image
 * into an {@link android.widget.ImageView} with fixed dimensions.
 *
 * <p>Typically it makes sense to use this class when loading multiple images with the {@link
 * com.bumptech.glide.RequestBuilder#thumbnail(com.bumptech.glide.RequestBuilder)} API into views in
 * a scrolling list like ListView, GridView, or RecyclerView.
 *
 * <p>{@link FixedSizeDrawable} may cause skewing or other undesirable behavior depending on your
 * images, views, and scaling. If this occurs, consider {@link DrawableImageViewTarget} or {@link
 * BitmapImageViewTarget} as alternatives.
 *
 * @param <T> The type of resource that will be displayed in the ImageView.
 */
 当加载多个固定尺寸的图像到ImageView时,避免额外调用View.requestLayout()。
通常,当使用RequestBuilder.thumbnail(com. bump技术。glide.requestbuilder) API加载多个图像到滚动列表的视图(ListView, GridView,或RecyclerView)时,使用这个类是有意义的。

fixedsizerawable可能会导致倾斜或其他不良行为,这取决于你的图像、视图和缩放。如果出现这种情况,可以考虑DrawableImageViewTargetBitmapImageViewTarget作为替代。
类型参数:ImageView中显示的资源类型。
// Public API.
@SuppressWarnings("WeakerAccess")
public abstract class ThumbnailImageViewTarget<T> extends ImageViewTarget<T> {

BitmapThumbnailImageViewTarget

包路径:com.bumptech.glide.request.target.BitmapThumbnailImageViewTarget


/**
 * Efficiently displays multiple Bitmaps loaded serially into a single {@link android.view.View}.
 */
 地显示多个位图,串行加载到一个单一的视图。
// Public API.
@SuppressWarnings("unused")
public class BitmapThumbnailImageViewTarget extends ThumbnailImageViewTarget<Bitmap> {
  public BitmapThumbnailImageViewTarget(ImageView view) {
    super(view);
  }

  /** @deprecated Use {@link #waitForLayout()} instead. */
  @SuppressWarnings("deprecation")
  @Deprecated
  public BitmapThumbnailImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  @Override
  protected Drawable getDrawable(Bitmap resource) {
    return new BitmapDrawable(view.getResources(), resource);
  }
}

CustomViewTarget

一个用于加载资源(Bitmap, Drawable等)到视图的基本目标,它为大多数方法提供了默认实现,并可以使用ViewTreeObserver.OnDrawListener来确定视图的大小。


/**
 * A base {@link Target} for loading resources ({@link android.graphics.Bitmap}, {@link Drawable}
 * etc) into {@link View}s that provides default implementations for most methods and can determine
 * the size of views using a {@link android.view.ViewTreeObserver.OnDrawListener}.
 *
 * @param <T> The specific subclass of view wrapped by this target (e.g. {@link
 *     android.widget.ImageView})
 * @param <Z> The resource type this target will receive (e.g. {@link android.graphics.Bitmap}).
 */
一个用于加载资源(Bitmap, Drawable)到视图的基本目标,它为大多数方法提供了默认实现,并可以使用ViewTreeObserver.OnDrawListener来确定视图的大小。
 类型参数:
T -被这个目标包装的视图的特定子类(例如ImageView)
Z -此目标将接收的资源类型(例如位图)public abstract class CustomViewTarget<T extends View, Z> implements Target<Z> {
  private static final String TAG = "CustomViewTarget";
  @IdRes private static final int VIEW_TAG_ID = R.id.glide_custom_view_target_tag;

  private final SizeDeterminer sizeDeterminer;

  protected final T view;
  @Nullable private OnAttachStateChangeListener attachStateListener;
  private boolean isClearedByUs;
  private boolean isAttachStateListenerAdded;
  。。。


  /**
   * A required callback invoked when the resource is no longer valid and must be freed.
   *
   * <p>You must ensure that any current Drawable received in {@link #onResourceReady(Object,
   * Transition)} is no longer used before redrawing the container (usually a View) or changing its
   * visibility. <b>Not doing so will result in crashes in your app.</b>
   *
   * @param placeholder The placeholder drawable to optionally show, or null.
   */
  protected abstract void onResourceCleared(@Nullable Drawable placeholder);

  /**
   * An optional callback invoked when a resource load is started.
   *
   * @see Target#onLoadStarted(Drawable)
   * @param placeholder The placeholder drawable to optionally show, or null.
   */
  protected void onResourceLoading(@Nullable Drawable placeholder) {
    // Default empty.
  }

  @Override
  public void onStart() {
    // Default empty.
  }

  @Override
  public void onStop() {
    // Default empty.
  }

  @Override
  public void onDestroy() {
    // Default empty.
  }
。。。

DrawableImageViewTarget

com.bumptech.glide.request.target.DrawableImageViewTarget


/** A target for display {@link Drawable} objects in {@link ImageView}s. */
public class DrawableImageViewTarget extends ImageViewTarget<Drawable> {

  public DrawableImageViewTarget(ImageView view) {
    super(view);
  }

  /** @deprecated Use {@link #waitForLayout()} instead. */
  // Public API.
  @SuppressWarnings({"unused", "deprecation"})
  @Deprecated
  public DrawableImageViewTarget(ImageView view, boolean waitForLayout) {
    super(view, waitForLayout);
  }

  @Override
  protected void setResource(@Nullable Drawable resource) {
    view.setImageDrawable(resource);
  }
}

自研产品推荐

历时一年半多开发终于smartApi-v1.0.0版本在2023-09-15晚十点正式上线
smartApi是一款对标国外的postman的api调试开发工具,由于开发人力就作者一个所以人力有限,因此v1.0.0版本功能进行精简,大功能项有:

  • api参数填写
  • api请求响应数据展示
  • PDF形式的分享文档
  • Mock本地化解决方案
  • api列表数据本地化处理
  • 再加上UI方面的打磨

为了更好服务大家把之前的公众号和软件激活结合,如有疑问请大家反馈到公众号即可,下个版本30%以上的更新会来自公众号的反馈。
嗯!先解释不上服务端原因,API调试工具的绝大多数时候就是一个数据模型、数据处理、数据模型理解共识的问题解决工具,所以作者结合自己十多年开发使用的一些痛点来打造的,再加上服务端开发一般是面向企业的,作者目前没有精力和时间去打造企业服务。再加上没有资金投入所以服务端开发会滞后,至于什么时候会进行开发,这个要看募资情况和用户反馈综合考虑。虽然目前国内有些比较知名的api工具了,但作者使用后还是觉得和实际使用场景不符。如果有相关吐槽也可以在作者的公众号里反馈蛤!
下面是一段smartApi使用介绍:
在这里插入图片描述

下载地址:

https://pan.baidu.com/s/1iultkXqeLNG4_eNiefKTjQ?pwd=cnbl

posted @ 2022-01-29 10:12  lichong951  阅读(25)  评论(0编辑  收藏  举报  来源