美文网首页
Glide 是如何获取ImageView的大小的?

Glide 是如何获取ImageView的大小的?

作者: bogerLiu | 来源:发表于2019-03-26 16:16 被阅读0次
    草图镇楼 ff9d5505445322c03e69a5813aba596.jpg
    d73b6e1e4bb97f712c627b00674d858.jpg

    带着问题来看源码, Glide.with().load().into()之前的文章里面有说过with和load方法不涉及图片操作,所以就直接看into方法追踪源码可以看到into方法如下 传入Imageview 然后构建一个ImageviewTarget,
    into(context.buildImageViewTarget(view, transcodeClass))

    继续看into方法

      Request request = buildRequest(target);
        target.setRequest(request);
        requestManager.track(target, request);
    

    是构建了一个request
    继续追踪得到如下方法

      private Request buildRequestRecursive(Target<TranscodeType> target,
          @Nullable ThumbnailRequestCoordinator parentCoordinator,
          TransitionOptions<?, ? super TranscodeType> transitionOptions,
          Priority priority, int overrideWidth, int overrideHeight) {
        if (thumbnailBuilder != null) {
          // Recursive case: contains a potentially recursive thumbnail request builder.
          if (isThumbnailBuilt) {
            throw new IllegalStateException("You cannot use a request as both the main request and a "
                + "thumbnail, consider using clone() on the request(s) passed to thumbnail()");
          }
    
          TransitionOptions<?, ? super TranscodeType> thumbTransitionOptions =
              thumbnailBuilder.transitionOptions;
          if (DEFAULT_ANIMATION_OPTIONS.equals(thumbTransitionOptions)) {
            thumbTransitionOptions = transitionOptions;
          }
    
          Priority thumbPriority = thumbnailBuilder.requestOptions.isPrioritySet()
              ? thumbnailBuilder.requestOptions.getPriority() : getThumbnailPriority(priority);
    
          int thumbOverrideWidth = thumbnailBuilder.requestOptions.getOverrideWidth();
          int thumbOverrideHeight = thumbnailBuilder.requestOptions.getOverrideHeight();
          if (Util.isValidDimensions(overrideWidth, overrideHeight)
              && !thumbnailBuilder.requestOptions.isValidOverride()) {
            thumbOverrideWidth = requestOptions.getOverrideWidth();
            thumbOverrideHeight = requestOptions.getOverrideHeight();
          }
    
          ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
          Request fullRequest = obtainRequest(target, requestOptions, coordinator,
              transitionOptions, priority, overrideWidth, overrideHeight);
          isThumbnailBuilt = true;
          // Recursively generate thumbnail requests.
          Request thumbRequest = thumbnailBuilder.buildRequestRecursive(target, coordinator,
              thumbTransitionOptions, thumbPriority, thumbOverrideWidth, thumbOverrideHeight);
          isThumbnailBuilt = false;
          coordinator.setRequests(fullRequest, thumbRequest);
          return coordinator;
        } else if (thumbSizeMultiplier != null) {
          // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
          ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
          Request fullRequest = obtainRequest(target, requestOptions, coordinator, transitionOptions,
              priority, overrideWidth, overrideHeight);
          RequestOptions thumbnailOptions = requestOptions.clone()
              .sizeMultiplier(thumbSizeMultiplier);
    
          Request thumbnailRequest = obtainRequest(target, thumbnailOptions, coordinator,
              transitionOptions, getThumbnailPriority(priority), overrideWidth, overrideHeight);
    
          coordinator.setRequests(fullRequest, thumbnailRequest);
          return coordinator;
        } else {
          // Base case: no thumbnail.
          return obtainRequest(target, requestOptions, parentCoordinator, transitionOptions, priority,
              overrideWidth, overrideHeight);
        }
      }
    

    这里主要是判断是否设置缩略图,如果没有那么就直接调用最后那句 return obtianRequest(*****);
    为了保持清晰,我们直接可以看这句 然后看下方法

      private Request obtainRequest(Target<TranscodeType> target,
          RequestOptions requestOptions, RequestCoordinator requestCoordinator,
          TransitionOptions<?, ? super TranscodeType> transitionOptions, Priority priority,
          int overrideWidth, int overrideHeight) {
        requestOptions.lock();
    
        return SingleRequest.obtain(
            context,
            model,
            transcodeClass,
            requestOptions,
            overrideWidth,
            overrideHeight,
            priority,
            target,
            requestListener,
            requestCoordinator,
            context.getEngine(),
            transitionOptions.getTransitionFactory());
      }
    

    可以看到构造了一个SingleRequest,这里也就知道了 Request是SingleRequest的实现类
    那么然后就继续看into方法 执行到了
    requestManager.track(target, request);
    内部是调用了

      public void runRequest(Request request) {
        requests.add(request);
        if (!isPaused) {
          request.begin();
        } else {
          pendingRequests.add(request);
        }
      }
    

    直接看begin方法因为我们知道是SingleRequst,所以直接看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));
        }
      }
    

    这里的model通过追踪可以得知,就是load方法传入的数据源对象,所以说就是判断数据源是否有效,所以我们直接往下看,假装他有效(2333),那么就开始了判断size是否可用,一开始没赋值,那么肯定是不可以用的,所以就是调用了target.getSize(this);方法,前面说过这里的target是构造出来的DrawableImageViewTarget然后看下他的getSize方法,发现没有,那么就往父类上找,最后发现是通过SizeDeterminer这个类来获取的,然后可以看到方法getSize,至此通过查看方法知道了Imageview的大小是如何得到了,通过layoutparams,Imageview的size,已经padding来得到的

    总结

    文章格式还需要继续改进,这里只是指引大家如何带着问题来查看源码一个过程,看源码不用太深入,重要是把流程走到位,熟悉流程了然后再来看内部仔细的实现,当然这里再看的时候也看到了很多的设计模式可以学习一下。

    相关文章

      网友评论

          本文标题:Glide 是如何获取ImageView的大小的?

          本文链接:https://www.haomeiwen.com/subject/lntnvqtx.html