首页 » Android » Android Glide设置默认图片、异常图片为圆形图片

Android Glide设置默认图片、异常图片为圆形图片

原文 http://blog.csdn.net/hexingen/article/details/78143982

2017-09-30 17:20:49阅读(383)

Android Glide4 异步图片框架

简介篇: Glide框架

迁移篇:Glide V4 框架新特性(Migrating from v3 to v4)

基础篇:Android开发中使用Glide V4 中Generated API特性

进级篇:Kotlin编程开发之Glide V4使用OkHttp3作为传输层

前言:

在项目开发中,是需要经常用到圆形图片的,设置默认图片,设置资源图片等等。

若是,异常图片,默认图片都需要美工妹子做成圆形图片,无疑增加了美工妹子的工作量。本着当活雷锋的思想,程序员能搞定的事情,绝不麻烦美工妹子。

要说图片异步加载框架,现今最流行的非Glide莫属,连谷歌I/O App都在使用,可见它的强大之处。

根据源码走向找到,设置默认图片,异常图片的方法。

众所周知,Glide的开启加载是通过调用GlideApp.with().....into()或者preload().

1. 首先,进入RequestBuilder类#into():
  /**
   * Set the target the resource will be loaded into.
   *
   * @param target The target to load the resource into.
   * @return The given target.
   * @see RequestManager#clear(Target)
   */
  public <Y extends Target<TranscodeType>> Y into(@NonNull Y target) {
    Util.assertMainThread();
    Preconditions.checkNotNull(target);
    if (!isModelSet) {
      throw new IllegalArgumentException("You must call #load() before calling #into()");
    }
    Request previous = target.getRequest();
    if (previous != null) {
      requestManager.clear(target);
    }
    requestOptions.lock();
    Request request = buildRequest(target);
    target.setRequest(request);
    requestManager.track(target, request);
    return target;
  }
2. 接下,源码来走向到RequestManager类中track():
  void track(Target<?> target, Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }
3. 在接下来,源码走向到RequestTracker类中runRequest():
  /**
   * Starts tracking the given request.
   */
  public void runRequest(Request request) {
    requests.add(request);
    if (!isPaused) {
      request.begin();
    } else {
      pendingRequests.add(request);
    }
  }
4. 最终走向到SingleRequest类中begin():
@Override
public void begin() {
    stateVerifier.throwIfRecycled();
    startTime = LogTime.getLogTime();
    if (model == null) {
      if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
        width = overrideWidth;
        height = overrideHeight;
      }
      // Only log at more verbose log levels if the user has set a fallback drawable, because
      // fallback Drawables indicate the user expects null models occasionally.
      int logLevel = getFallbackDrawable() == null ? Log.WARN : Log.DEBUG;
      onLoadFailed(new GlideException("Received null model"), logLevel);
      return;
    }
    status = Status.WAITING_FOR_SIZE;
    if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
      onSizeReady(overrideWidth, overrideHeight);
    } else {
      target.getSize(this);
    }
    if ((status == Status.RUNNING || status == Status.WAITING_FOR_SIZE)
        && canNotifyStatusChanged()) {
      target.onLoadStarted(getPlaceholderDrawable());
    }
    if (Log.isLoggable(TAG, Log.VERBOSE)) {
      logV("finished run method in " + LogTime.getElapsedMillis(startTime));
    }
}

可以从源码target.onLoadStarted(getPlaceholderDrawable())发觉,最后是通过Target对象的onLoadStarted()方法来设置默认空白图片的。

SingleRequest类中设置异常图片的源码:

  private void setErrorPlaceholder() {
    if (!canNotifyStatusChanged()) {
      return;
    }
    Drawable error = null;
    if (model == null) {
      error = getFallbackDrawable();
    }
    // Either the model isn't null, or there was no fallback drawable set.
    if (error == null) {
      error = getErrorDrawable();
    }
    // The model isn't null, no fallback drawable was set or no error drawable was set.
    if (error == null) {
      error = getPlaceholderDrawable();
    }
    target.onLoadFailed(error);
  }

可以从源码target.onLoadFailed(error)可知,是通过Target对象的onLoadFailed()方法来设置异常图片的。

长征路已经走完一半,已经找到了最后的源码走向。剩下来,只需要自定义一个Target子类。

Glide中已经存在一个ImageViewTarget类,查看源码如下:
public abstract class ImageViewTarget<Z> extends ViewTarget<ImageView, Z>
    implements Transition.ViewAdapter {
  @Nullable
  private Animatable animatable;
  public ImageViewTarget(ImageView view) {
    super(view);
  }
  /**
   * Returns the current {@link android.graphics.drawable.Drawable} being displayed in the view
   * using {@link android.widget.ImageView#getDrawable()}.
   */
  @Override
  @Nullable
  public Drawable getCurrentDrawable() {
    return view.getDrawable();
  }
  /**
   * Sets the given {@link android.graphics.drawable.Drawable} on the view using {@link
   * android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
   *
   * @param drawable {@inheritDoc}
   */
  @Override
  public void setDrawable(Drawable drawable) {
    view.setImageDrawable(drawable);
  }
  /**
   * Sets the given {@link android.graphics.drawable.Drawable} on the view using {@link
   * android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
   *
   * @param placeholder {@inheritDoc}
   */
  @Override
  public void onLoadStarted(@Nullable Drawable placeholder) {
    super.onLoadStarted(placeholder);
    setResourceInternal(null);
    setDrawable(placeholder);
  }
  /**
   * Sets the given {@link android.graphics.drawable.Drawable} on the view using {@link
   * android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
   *
   * @param errorDrawable {@inheritDoc}
   */
  @Override
  public void onLoadFailed(@Nullable Drawable errorDrawable) {
    super.onLoadFailed(errorDrawable);
    setResourceInternal(null);
    setDrawable(errorDrawable);
  }
  /**
   * Sets the given {@link android.graphics.drawable.Drawable} on the view using {@link
   * android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
   *
   * @param placeholder {@inheritDoc}
   */
  @Override
  public void onLoadCleared(@Nullable Drawable placeholder) {
    super.onLoadCleared(placeholder);
    setResourceInternal(null);
    setDrawable(placeholder);
  }
  @Override
  public void onResourceReady(Z resource, @Nullable Transition<? super Z> transition) {
    if (transition == null || !transition.transition(resource, this)) {
      setResourceInternal(resource);
    } else {
      maybeUpdateAnimatable(resource);
    }
  }
  @Override
  public void onStart() {
    if (animatable != null) {
      animatable.start();
    }
  }
  @Override
  public void onStop() {
    if (animatable != null) {
      animatable.stop();
    }
  }
  private void setResourceInternal(@Nullable Z resource) {
    maybeUpdateAnimatable(resource);
    setResource(resource);
  }
  private void maybeUpdateAnimatable(@Nullable Z resource) {
    if (resource instanceof Animatable) {
      animatable = (Animatable) resource;
      animatable.start();
    } else {
      animatable = null;
    }
  }
  protected abstract void setResource(@Nullable Z resource);
}

从源码可知,无论是空白图片,还是异常图片都是最后走向到setDrawable(Drawable drawable)。

源码寻找之路已经走完,马上就可以实现自己需要的需求,继续撸起。

定义一个默认,异常,资源图片都为圆形的 ImageViewTarget子类。

分析:

定义ImageViewTarget子类: 重写setDrawable(Drawable drawable),异常,默认空白图片设置为圆形。 实现抽象方法setResource( Bitmap resource),正常加载的资源图片设置为圆形

代码编写如下:

/**
 *
 * 设置 默认图片,异常图片,指定路径的图片为圆角图片
 */
public class CircleBitmapTarget extends ImageViewTarget<Bitmap> {
    public CircleBitmapTarget(ImageView view) {
        super(view);
    }
    /**
     *  从指定路径加载的Bitmap
     * @param resource
     */
    @Override
    protected void setResource(@Nullable Bitmap resource) {
         bindCircleBitmapToImageView(resource);
    }
    /**
     *
     * onLoadFailed()和onLoadStarted调用该方法,用于设置默认的图片和异常图片
     * 设置默认图片
     * @param drawable
     */
    @Override
    public void setDrawable(Drawable drawable) {
        if (drawable instanceof BitmapDrawable){
           Bitmap bitmap1= ((BitmapDrawable) drawable).getBitmap();
          bindCircleBitmapToImageView(bitmap1);
        }else{
            view.setImageDrawable(drawable);
        }
    }
    /**
     * 通过RoundedBitmapDrawable绘制圆形Bitmap,且加载ImageView.
     * @param bitmap
     */
    private void bindCircleBitmapToImageView(Bitmap bitmap){
        RoundedBitmapDrawable bitmapDrawable=  RoundedBitmapDrawableFactory.create(view.getContext().getResources(),bitmap);
        bitmapDrawable.setCircular(true);
        view.setImageDrawable(bitmapDrawable);
    }
}

最后使用方式:

  GlideRequest<Bitmap> glideRequest = GlideApp.with(context).asBitmap();
        glideRequest.load(imageUrl).error(errorResourceId)//异常时候显示的图片
                .placeholder(placeResourceId)//加载成功前显示的图片
                .fallback(nullResourceId)//url为空的时候,显示的图片
                .into(new CircleBitmapTarget(imageView));//在RequestBuilder<Bitmap> 中使用自定义的ImageViewTarget

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹