关于新浪微博里面长图加载功能的一点窥探

之前写过一篇文章 关于Andorid加载高清大图,有兴趣的可以去看一下。由于昨天弄了一下反编译其实是想看下google相册里面的一些动画效果的实现,经过本人查阅各种资料的不泄努力,终于还是没有得到什么实质性的努力效果。由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!


先说下结论,如果不感兴趣下面也可以不看:
1. 图片缩放使用的是Matrix,以及Scroller配合一些动画
2. 图片放大之后的滚动条是自己画上去的,不是系统的

如果一下内容造成了侵权行为,请通知我及时删除本文章

想到之前实现过的新浪长图功能,顺手今天看了下官方里面的具体实现。
顺便啰嗦两句,用的反编译工具是dex2jar+apktool,大家可以网上下载即可,自行体会。

好了开始今天的正题。主要类有2个TouchImageViewSplitTouchImageView。我先帖一下TouchImageView的反编译代码:

package com.sina.weibo.view;

import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.ViewParent;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.Scroller;
import com.sina.weibo.utils.bn;
import com.sina.weibo.utils.bz.a;
import com.sina.weibo.utils.s;

public class TouchImageView extends ImageView
  implements GestureDetector.OnDoubleTapListener, GestureDetector.OnGestureListener, ag.a
{
  private static final String c = TouchImageView.class.getSimpleName();
  protected Matrix a = new Matrix();
  protected long b;
  private float d = 1.0F;
  private float e = 4.0F;
  private Matrix f = new Matrix();
  private GestureDetector g;
  private ag h;
  private Bitmap i;
  private boolean j;
  private boolean k;
  private c l;
  private RectF m;
  private a n = new a();

  public TouchImageView(Context paramContext)
  {
    super(paramContext);
    i();
  }

  public TouchImageView(Context paramContext, AttributeSet paramAttributeSet)
  {
    super(paramContext, paramAttributeSet);
    i();
  }

  public TouchImageView(Context paramContext, AttributeSet paramAttributeSet, int paramInt)
  {
    super(paramContext, paramAttributeSet, paramInt);
    i();
  }

  private void a(int paramInt1, int paramInt2)
  {
    this.a.set(this.f);
    this.a.postTranslate(paramInt1, paramInt2);
    a(true, true);
    setImageMatrix(this.a);
    this.f.set(this.a);
  }

  private RectF c()
  {
    Matrix localMatrix = new Matrix();
    localMatrix.set(this.a);
    RectF localRectF = new RectF(0.0F, 0.0F, b(), f());
    localMatrix.mapRect(localRectF);
    return localRectF;
  }

  private boolean d()
  {
    RectF localRectF = c();
    if (this.m == null)
      if (g())
        if (localRectF.top <= (getHeight() - localRectF.height()) / 2.0F);
    do
    {
      do
      {
        while (true)
        {
          return true;
          return false;
          if (localRectF.top < 0.0F)
            return false;
        }
        if (!(g()))
          break label83;
      }
      while (localRectF.top > (getHeight() - localRectF.height()) / 2.0F);
      label83: return false;
    }
    while (localRectF.top >= this.m.top);
    return false;
  }

  private boolean e()
  {
    RectF localRectF = c();
    if (this.m == null)
      if (g())
        if (localRectF.bottom > getHeight() / 2 + localRectF.height() / 2.0F);
    do
    {
      do
      {
        while (true)
        {
          return true;
          return false;
          if (localRectF.bottom > getHeight())
            return false;
        }
        if (!(g()))
          break label91;
      }
      while (localRectF.bottom <= getHeight() / 2 + localRectF.height() / 2.0F);
      label91: return false;
    }
    while (localRectF.bottom <= this.m.bottom);
    return false;
  }

  private boolean g()
  {
    RectF localRectF = c();
    if (this.m == null)
      if (localRectF.height() >= getHeight());
    do
    {
      return true;
      return false;
    }
    while (localRectF.height() < this.m.height());
    return false;
  }

  private void p()
  {
    q();
  }

  private void q()
  {
    float f1;
    if ((!(d())) && (!(e())))
      return;
    Object localObject = c();
    if (this.m == null)
    {
      if (d())
      {
        if (g())
          f1 = ((RectF)localObject).top - ((getHeight() - ((RectF)localObject).height()) / 2.0F);
        while (true)
        {
          do
          {
            label59: localObject = new TranslateAnimation(0.0F, 0.0F, f1, 0.0F);
            ((TranslateAnimation)localObject).setFillAfter(false);
            ((TranslateAnimation)localObject).setDuration(100L);
            f1 -= 0.0F;
          }
          while (f1 == 0.0F);
          this.a.set(this.f);
          this.a.postTranslate(0.0F, f1);
          a(true, true);
          setImageMatrix(this.a);
          this.f.set(this.a);
          startAnimation((Animation)localObject);
          return;
          f1 = ((RectF)localObject).top;
        }
      }
      if (g())
        f1 = ((RectF)localObject).bottom - getBottom() + (getHeight() - ((RectF)localObject).height()) / 2.0F;
      while (true)
      {
        break label59:
        f1 = ((RectF)localObject).bottom - getBottom();
      }
    }
    if (d())
    {
      if (g())
        f1 = ((RectF)localObject).top - this.m.top - ((this.m.height() - ((RectF)localObject).height()) / 2.0F);
      while (true)
      {
        break label59:
        f1 = ((RectF)localObject).top - this.m.top;
      }
    }
    if (g())
      f1 = ((RectF)localObject).bottom - this.m.bottom + (this.m.height() - ((RectF)localObject).height()) / 2.0F;
    while (true)
    {
      break label59:
      f1 = ((RectF)localObject).bottom - this.m.bottom;
    }
  }

  public void a(boolean paramBoolean1, boolean paramBoolean2)
  {
    int i1;
    if (a())
      return;
    RectF localRectF = c();
    float f5 = localRectF.height();
    float f4 = localRectF.width();
    float f3 = 0.0F;
    float f2 = 0.0F;
    float f1 = f2;
    if (paramBoolean2)
    {
      if (this.m != null)
        break label179;
      i1 = getHeight();
      if (f5 >= i1)
        break label129;
      f1 = (i1 - f5) / 2.0F - localRectF.top;
    }
    f2 = f3;
    if (paramBoolean1)
    {
      i1 = getWidth();
      if (f4 >= i1)
        break label279;
      f2 = (i1 - f4) / 2.0F - localRectF.left;
    }
    while (true)
    {
      while (true)
      {
        do
        {
          while (true)
          {
            while (true)
            {
              while (true)
              {
                do
                {
                  while (true)
                  {
                    this.a.postTranslate(f2, f1);
                    return;
                    label129: if (localRectF.top <= 0.0F)
                      break;
                    f1 = -localRectF.top;
                  }
                  f1 = f2;
                }
                while (localRectF.bottom >= i1);
                f1 = getHeight() - localRectF.bottom;
              }
              label179: f1 = this.m.height();
              if (f5 >= f1)
                break;
              f1 = (f1 - f5) / 2.0F - localRectF.top;
            }
            if (localRectF.top <= this.m.top)
              break;
            f1 = this.m.top - localRectF.top;
          }
          f1 = f2;
        }
        while (localRectF.bottom >= this.m.bottom);
        f1 = this.m.bottom - localRectF.bottom;
      }
      if (localRectF.left > 0.0F)
        label279: f2 = -localRectF.left;
      f2 = f3;
      if (localRectF.right >= i1)
        continue;
      f2 = i1 - localRectF.right;
    }
  }

  protected boolean a()
  {
    return (this.i != null);
  }

  public boolean a(MotionEvent paramMotionEvent1, MotionEvent paramMotionEvent2)
  {
    this.j = true;
    this.f.set(this.a);
    return true;
  }

  public boolean a(MotionEvent paramMotionEvent1, MotionEvent paramMotionEvent2, MotionEvent paramMotionEvent3)
  {
    this.f.set(this.a);
    return true;
  }

  public boolean a(MotionEvent paramMotionEvent1, MotionEvent paramMotionEvent2, MotionEvent paramMotionEvent3, PointF paramPointF, float paramFloat)
  {
    if (a())
      return false;
    this.a.set(this.f);
    float f2 = j();
    float f3 = f2 * paramFloat;
    float f1 = paramFloat;
    if (f2 != 0.0F)
    {
      if (f3 >= l())
        break label101;
      f1 = l() / f2;
    }
    while (true)
    {
      this.a.postScale(f1, f1, paramPointF.x, paramPointF.y);
      a(true, true);
      setImageMatrix(this.a);
      return true;
      label101: f1 = paramFloat;
      if (f3 <= m())
        continue;
      f1 = m() / f2;
    }
  }

  protected int b()
  {
    return this.i.getWidth();
  }

  protected int f()
  {
    return this.i.getHeight();
  }

  public boolean h()
  {
    return (a.a(this.n).isFinished());
  }

  protected void i()
  {
    setScaleType(ImageView.ScaleType.MATRIX);
    this.g = new GestureDetector(getContext(), this);
    this.g.setIsLongpressEnabled(false);
    this.h = new ag(getContext(), this);
  }

  public float j()
  {
    float[] arrayOfFloat = new float[9];
    this.a.getValues(arrayOfFloat);
    if (Double.compare(arrayOfFloat[0], 0.0D) != 0)
      return Math.abs(arrayOfFloat[0]);
    if (Double.compare(arrayOfFloat[1], 0.0D) != 0)
      return Math.abs(arrayOfFloat[1]);
    return Math.abs(arrayOfFloat[0]);
  }

  public Matrix k()
  {
    return this.a;
  }

  public float l()
  {
    return this.d;
  }

  public float m()
  {
    if ((!(a())) && (b() > 0) && (f() > 0))
      if (b() <= f())
        break label70;
    label70: for (this.e = Math.max(1.0F, Math.max(getWidth() / b(), getHeight() / f())); ; this.e = Math.max(4.0F, getWidth() / b()))
      return this.e;
  }

  public void n()
  {
    if (this.n == null)
      return;
    this.n.a();
  }

  public Bitmap o()
  {
    return this.i;
  }

  @SuppressLint({"NewApi", "DefaultLocale"})
  public boolean onDoubleTap(MotionEvent paramMotionEvent)
  {
    float f1;
    float f2;
    if ((!(isEnabled())) || (this.k));
    do
      return false;
    while (a());
    if (s.q())
    {
      f2 = Math.max(getWidth() / b(), l());
      f1 = f2;
      if (String.format("%.3f", new Object[] { Float.valueOf(j()) }).equals(String.format("%.3f", new Object[] { Float.valueOf(f2) })))
      {
        f2 = Math.min(getHeight() / f(), m());
        f1 = f2;
        if (!(a()))
        {
          f1 = f2;
          if (b() > 0)
          {
            f1 = f2;
            if (f() > 0)
            {
              if (b() <= f())
                break label237;
              f1 = Math.min(getHeight() / f(), m());
            }
          }
        }
      }
      ValueAnimator localValueAnimator = ValueAnimator.ofFloat(new float[] { j(), f1 });
      localValueAnimator.addUpdateListener(new b(paramMotionEvent.getX(), paramMotionEvent.getY()));
      localValueAnimator.setDuration(200L);
      localValueAnimator.setInterpolator(new DecelerateInterpolator());
      localValueAnimator.start();
    }
    while (true)
    {
      while (true)
      {
        return true;
        label237: f1 = m();
      }
      f1 = 1.0F;
      if (String.format("%.3f", new Object[] { Float.valueOf(j()) }).equals(String.format("%.3f", new Object[] { Float.valueOf(1.0F) })))
        f1 = getWidth() / b();
      f2 = f1;
      if (j() != 0.0F)
        f2 = f1 / j();
      this.a.postScale(f2, f2, paramMotionEvent.getX(), paramMotionEvent.getY());
      a(true, true);
      setImageMatrix(this.a);
    }
  }

  public boolean onDoubleTapEvent(MotionEvent paramMotionEvent)
  {
    return false;
  }

  public boolean onDown(MotionEvent paramMotionEvent)
  {
    return false;
  }

  public boolean onFling(MotionEvent paramMotionEvent1, MotionEvent paramMotionEvent2, float paramFloat1, float paramFloat2)
  {
    int i1;
    if (!(isEnabled()));
    do
      return false;
    while (a());
    if (Math.abs(paramFloat1) > Math.abs(paramFloat2))
      i1 = (int)paramFloat1;
    for (int i2 = 0; ; i2 = (int)paramFloat2)
    {
      this.f.set(this.a);
      this.n.a(i1, i2);
      return true;
      i1 = 0;
    }
  }

  public void onLongPress(MotionEvent paramMotionEvent)
  {
    bn.b("liujin", "onLongPress>>>>>>>>>>>>>>>>>");
    if (this.l == null)
      return;
    this.l.a();
  }

  public boolean onScroll(MotionEvent paramMotionEvent1, MotionEvent paramMotionEvent2, float paramFloat1, float paramFloat2)
  {
    paramMotionEvent1 = c();
    if ((Math.abs(paramFloat1) > Math.abs(paramFloat2)) && ((((paramMotionEvent1.left > -1.0F) && (paramFloat1 < 0.0F)) || ((paramMotionEvent1.right < getWidth() + 1) && (paramFloat1 > 0.0F)))))
      getParent().requestDisallowInterceptTouchEvent(false);
    do
      return false;
    while ((!(isEnabled())) || (a()));
    float f1 = paramFloat2;
    if (e())
    {
      f1 = paramFloat2;
      if (paramFloat2 > 0.0F)
      {
        f1 = paramFloat2;
        if (this.m == null)
          f1 = 0.0F;
      }
    }
    paramFloat2 = f1;
    if (d())
    {
      paramFloat2 = f1;
      if (f1 < 0.0F)
      {
        paramFloat2 = f1;
        if (this.m == null)
          paramFloat2 = 0.0F;
      }
    }
    this.a.postTranslate(-paramFloat1, -paramFloat2);
    a(true, false);
    setImageMatrix(this.a);
    return true;
  }

  public void onShowPress(MotionEvent paramMotionEvent)
  {
  }

  public boolean onSingleTapConfirmed(MotionEvent paramMotionEvent)
  {
    if (!(this.j))
      return performClick();
    return false;
  }

  public boolean onSingleTapUp(MotionEvent paramMotionEvent)
  {
    return false;
  }

  protected void onSizeChanged(int paramInt1, int paramInt2, int paramInt3, int paramInt4)
  {
    super.onSizeChanged(paramInt1, paramInt2, paramInt3, paramInt4);
    if (a())
      return;
    float f1 = getWidth() / b() / j();
    this.a.postScale(f1, f1, 0.0F, 0.0F);
    a(true, true);
    setImageMatrix(this.a);
  }

  public boolean onTouchEvent(MotionEvent paramMotionEvent)
  {
    int i1;
    boolean bool;
    this.b = System.currentTimeMillis();
    if (a())
      bool = false;
    do
    {
      return bool;
      i1 = paramMotionEvent.getAction() & bz.a.c;
      if (i1 == 0)
        this.n.a();
      bool = false;
      if (isEnabled())
        bool = this.h.a(paramMotionEvent);
      this.g.onTouchEvent(paramMotionEvent);
      if (i1 == 0)
        getParent().requestDisallowInterceptTouchEvent(true);
      if ((i1 != 1) || (!(isEnabled())))
        continue;
      p();
    }
    while (i1 != 0);
    this.j = false;
    return true;
  }

  public void setCenterRegion(RectF paramRectF)
  {
    this.m = paramRectF;
  }

  public void setDoubleClickDisable(boolean paramBoolean)
  {
    this.k = paramBoolean;
  }

  public void setImageBitmap(Bitmap paramBitmap)
  {
    super.setImageBitmap(paramBitmap);
    this.i = paramBitmap;
    if (this.i == null)
      return;
    a(true, true);
    setImageMatrix(this.a);
  }

  public void setImageMatrix(Matrix paramMatrix)
  {
    if (this.a != paramMatrix)
      this.a = paramMatrix;
    a(true, false);
    super.setImageMatrix(paramMatrix);
  }

  public void setImageResource(int paramInt)
  {
    Drawable localDrawable = getResources().getDrawable(paramInt);
    float f1 = (getWidth() - localDrawable.getMinimumWidth()) / 2;
    float f2 = (getHeight() - localDrawable.getMinimumHeight()) / 2;
    Matrix localMatrix = new Matrix();
    localMatrix.postTranslate(f1, f2);
    setImageMatrix(localMatrix);
    setImageDrawable(localDrawable);
  }

  public void setLongpressEnabled(boolean paramBoolean)
  {
    if (this.g == null)
      return;
    this.g.setIsLongpressEnabled(paramBoolean);
  }

  public void setMaxScale(float paramFloat)
  {
    this.e = paramFloat;
  }

  public void setMinScale(float paramFloat)
  {
    this.d = paramFloat;
  }

  public void setOnLongPressListener(c paramc)
  {
    this.l = paramc;
  }

  public void setScale(RectF paramRectF1, RectF paramRectF2)
  {
    float f1 = paramRectF2.width() / 2.0F;
    float f2 = paramRectF2.left;
    float f3 = paramRectF1.width() / 2.0F;
    float f4 = paramRectF1.left;
    float f5 = paramRectF2.height() / 2.0F;
    float f6 = paramRectF2.top;
    float f7 = paramRectF1.height() / 2.0F;
    float f8 = paramRectF1.top;
    float f9 = paramRectF2.height() / paramRectF1.height();
    this.a.postTranslate(f1 + f2 - (f3 + f4), f5 + f6 - (f7 + f8));
    this.a.postScale(f9, f9, paramRectF2.width() / 2.0F, paramRectF2.height() / 2.0F + paramRectF2.top);
    setImageMatrix(this.a);
  }

  private class a
    implements Runnable
  {
    private Scroller b = new Scroller(TouchImageView.this.getContext());
    private int c;
    private int d;

    private void b()
    {
      TouchImageView.this.removeCallbacks(this);
    }

    private void c()
    {
      this.b.forceFinished(true);
    }

    public void a()
    {
      TouchImageView.this.removeCallbacks(this);
      c();
    }

    public void a(int paramInt1, int paramInt2)
    {
      int i;
      if ((paramInt1 == 0) && (paramInt2 == 0))
        return;
      b();
      if (paramInt1 < 0)
      {
        i = 2147483647;
        this.c = i;
        if (paramInt2 >= 0)
          break label72;
      }
      label72: for (int j = 2147483647; ; j = 0)
        while (true)
        {
          this.d = j;
          this.b.fling(i, j, paramInt1, paramInt2, 0, 2147483647, 0, 2147483647);
          TouchImageView.this.post(this);
          return;
          i = 0;
        }
    }

    public void run()
    {
      if (TouchImageView.this.a())
      {
        c();
        return;
      }
      Scroller localScroller = this.b;
      boolean bool = localScroller.computeScrollOffset();
      int k = localScroller.getCurrX();
      int l = localScroller.getCurrY();
      int i = k - this.c;
      if (i > 0)
      {
        i = Math.min(TouchImageView.this.getWidth(), i);
        j = l - this.d;
        if (j <= 0)
          break label139;
      }
      label139: for (int j = Math.min(TouchImageView.this.getHeight(), j); ; j = Math.max(-TouchImageView.this.getHeight(), j))
        while (true)
        {
          TouchImageView.a(TouchImageView.this, i, j);
          if (!(bool))
            break label155;
          this.c = k;
          this.d = l;
          TouchImageView.this.post(this);
          return;
          i = Math.max(-TouchImageView.this.getWidth(), i);
        }
      label155: c();
    }
  }

  @SuppressLint({"NewApi"})
  private class b
    implements ValueAnimator.AnimatorUpdateListener
  {
    private float b;
    private float c;

    public b(float paramFloat1, float paramFloat2)
    {
      this.b = paramFloat1;
      this.c = paramFloat2;
    }

    public void onAnimationUpdate(ValueAnimator paramValueAnimator)
    {
      float f = TouchImageView.this.j();
      f = ((Float)paramValueAnimator.getAnimatedValue()).floatValue() / f;
      TouchImageView.this.a.postScale(f, f, this.b, this.c);
      TouchImageView.this.a(true, true);
      TouchImageView.this.setImageMatrix(TouchImageView.this.a);
    }
  }

  public static abstract interface c
  {
    public abstract void a();
  }
}

也许你会说你贴的是什么狗屎代码,简直日了狗。我可以很负责任地告诉你,我也没把源码编译出来(O(∩_∩)O哈哈哈~)。TouchImageView它里面主要涉及了使用Matrix去缩放图片,Scroller去滚动,使用ValueAnimator改变Matrix,以及配合手势处理类。例如下面这段代码:

 public boolean onTouchEvent(MotionEvent paramMotionEvent)
  {
    int i1;
    boolean bool;
    this.b = System.currentTimeMillis();
    if (a())
      bool = false;
    do
    {
      return bool;
      i1 = paramMotionEvent.getAction() & bz.a.c;
      if (i1 == 0)
        this.n.a();
      bool = false;
      if (isEnabled())
        bool = this.h.a(paramMotionEvent);
      this.g.onTouchEvent(paramMotionEvent);
      if (i1 == 0)
        getParent().requestDisallowInterceptTouchEvent(true);
      if ((i1 != 1) || (!(isEnabled())))
        continue;
      p();
    }
    while (i1 != 0);
    this.j = false;
    return true;
  }

这里注意p(),然后进去看到他调用的是q(),然后呢

private void q()
  {
    float f1;
    if ((!(d())) && (!(e())))
      return;
    Object localObject = c();
    if (this.m == null)
    {
      if (d())
      {
        if (g())
          f1 = ((RectF)localObject).top - ((getHeight() - ((RectF)localObject).height()) / 2.0F);
        while (true)
        {
          do
          {
            label59: localObject = new TranslateAnimation(0.0F, 0.0F, f1, 0.0F);
            ((TranslateAnimation)localObject).setFillAfter(false);
            ((TranslateAnimation)localObject).setDuration(100L);
            f1 -= 0.0F;
          }
          while (f1 == 0.0F);
          this.a.set(this.f);
          this.a.postTranslate(0.0F, f1);
          a(true, true);
          setImageMatrix(this.a);
          this.f.set(this.a);
          startAnimation((Animation)localObject);
          return;
          f1 = ((RectF)localObject).top;
        }
      }
      if (g())
        f1 = ((RectF)localObject).bottom - getBottom() + (getHeight() - ((RectF)localObject).height()) / 2.0F;
      while (true)
      {
        break label59:
        f1 = ((RectF)localObject).bottom - getBottom();
      }
    }
    if (d())
    {
      if (g())
        f1 = ((RectF)localObject).top - this.m.top - ((this.m.height() - ((RectF)localObject).height()) / 2.0F);
      while (true)
      {
        break label59:
        f1 = ((RectF)localObject).top - this.m.top;
      }
    }
    if (g())
      f1 = ((RectF)localObject).bottom - this.m.bottom + (this.m.height() - ((RectF)localObject).height()) / 2.0F;
    while (true)
    {
      break label59:
      f1 = ((RectF)localObject).bottom - this.m.bottom;
    }
  }

里面最终也是改变了Matrix。由于本人能力有限,暂且对这个类讲解这么多,如果出现错误请多多指正。

再来看下SplitTouchImageView:

package com.sina.weibo.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import com.sina.weibo.R.g;
import com.sina.weibo.R.h;

public class SplitTouchImageView extends TouchImageView
{
  private boolean c;
  private Bitmap[] d;
  private Paint e;

  public SplitTouchImageView(Context paramContext)
  {
    super(paramContext);
  }

  public SplitTouchImageView(Context paramContext, AttributeSet paramAttributeSet)
  {
    super(paramContext, paramAttributeSet);
  }

  public SplitTouchImageView(Context paramContext, AttributeSet paramAttributeSet, int paramInt)
  {
    super(paramContext, paramAttributeSet, paramInt);
  }

  protected void a(Canvas paramCanvas)
  {
    label40: int i;
    long l1;
    if (h())
    {
      this.b = System.currentTimeMillis();
      l1 = 0L;
      if (l1 <= 600L)
        break label40;
    }
    do
    {
      int i2;
      int i3;
      Drawable localDrawable;
      do
      {
        do
        {
          while (true)
          {
            return;
            l1 = System.currentTimeMillis() - this.b;
          }
          i = 0;
          k = 0;
          j = 0;
          int i1 = 0;
          i3 = getHeight();
          i2 = getWidth();
          if (this.c)
          {
            if (this.d == null)
              continue;
            localObject = this.d;
            int i4 = localObject.length;
            l = 0;
            j = i1;
            while (true)
            {
              i = k;
              if (l >= i4)
                break label158;
              localDrawable = localObject[l];
              k += localDrawable.getHeight();
              j = localDrawable.getWidth();
              l += 1;
            }
          }
          if (o() == null)
            continue;
          i = o().getHeight();
          label158: j = o().getWidth();
        }
        while ((i == 0) || (j == 0));
        l = (int)(i * j());
        j = (int)(j * j());
      }
      while ((l <= i3) && (j <= i2));
      int k = getResources().getDimensionPixelSize(R.g.scrollbarSize);
      i = 0;
      Object localObject = new float[9];
      this.a.getValues(localObject);
      if (l > i3)
      {
        i = i3 * i3 / l;
        l = (int)(-localObject[5] * i3 / l);
        localDrawable = getResources().getDrawable(R.h.scrollbar_handle_vertical);
        localDrawable.setBounds(getWidth() - k, l, getWidth(), l + i);
        localDrawable.draw(paramCanvas);
        i = 1;
      }
      if (j <= i2)
        continue;
      i = i2 * i2 / j;
      int l = (int)(-localObject[2] * i2 / j);
      localObject = getResources().getDrawable(R.h.scrollbar_handle_horizontal);
      int j = l + i;
      i = j;
      if (j >= getRight())
        i = j - (k + 1);
      ((Drawable)localObject).setBounds(l, getHeight() - k, i, getHeight());
      ((Drawable)localObject).draw(paramCanvas);
      i = 1;
    }
    while ((i == 0) || (l1 >= 600L));
    invalidate();
  }

  protected boolean a()
  {
    if (this.c)
      return ((this.d != null) && (this.d.length != 0));
    return super.a();
  }

  protected int b()
  {
    if (this.c)
    {
      if (a())
        return 0;
      return this.d[0].getWidth();
    }
    return super.b();
  }

  protected int f()
  {
    int j = 0;
    if (this.c)
    {
      int k;
      if (a())
      {
        k = 0;
        return k;
      }
      int i = 0;
      Bitmap[] arrayOfBitmap = this.d;
      int l = arrayOfBitmap.length;
      while (true)
      {
        do
          k = i;
        while (j >= l);
        i += arrayOfBitmap[j].getHeight();
        j += 1;
      }
    }
    return super.f();
  }

  public Bitmap[] g()
  {
    return this.d;
  }

  protected void onDraw(Canvas paramCanvas)
  {
    if (this.e == null)
      this.e = new Paint(6);
    if (this.c)
    {
      int j = 0;
      if (this.d == null)
        break label120;
      Bitmap[] arrayOfBitmap = this.d;
      int k = arrayOfBitmap.length;
      int i = 0;
      while (true)
      {
        if (i >= k)
          break label120;
        Bitmap localBitmap = arrayOfBitmap[i];
        Matrix localMatrix = new Matrix(this.a);
        localMatrix.postTranslate(0.0F, j * j());
        paramCanvas.drawBitmap(localBitmap, localMatrix, this.e);
        j += localBitmap.getHeight();
        i += 1;
      }
    }
    super.onDraw(paramCanvas);
    label120: a(paramCanvas);
  }

  public void setImageBitmap(Bitmap paramBitmap)
  {
    this.c = false;
    super.setImageBitmap(paramBitmap);
  }

  public void setSplitedBitmaps(Bitmap[] paramArrayOfBitmap)
  {
    this.c = true;
    this.d = paramArrayOfBitmap;
    a(true, true);
    invalidate();
  }
}

相比TouchImageView而言,SplitTouchImageView的代码就很少了。通过对比可以看到对于是指滑动处理以及图片缩放的处理都放到了TouchImageView里面;其实对于SplitTouchImageView我也不算是看懂了。。。
说下自己的见解:
1. android 要加载高清图片,官方建议用的是BitmapRegionDecoder去分块加载。然后我看到了SplitTouchImageView里面也使用了private Bitmap[] d;感觉它可能也是把长图分成了Bitmap[],这个纯属是我自己YY的,毕竟没有任何证据。
2. 注意到长图放大的时候,在手机的右边和下面会出现有2个滚动条,起先我认为是系统自己生成的;但是当我下面这个:

protected void a(Canvas paramCanvas)
  {
    label40: int i;
    long l1;
    if (h())
    {
      this.b = System.currentTimeMillis();
      l1 = 0L;
      if (l1 <= 600L)
        break label40;
    }
    do
    {
      int i2;
      int i3;
      Drawable localDrawable;
      do
      {
        do
        {
          while (true)
          {
            return;
            l1 = System.currentTimeMillis() - this.b;
          }
          i = 0;
          k = 0;
          j = 0;
          int i1 = 0;
          i3 = getHeight();
          i2 = getWidth();
          if (this.c)
          {
            if (this.d == null)
              continue;
            localObject = this.d;
            int i4 = localObject.length;
            l = 0;
            j = i1;
            while (true)
            {
              i = k;
              if (l >= i4)
                break label158;
              localDrawable = localObject[l];
              k += localDrawable.getHeight();
              j = localDrawable.getWidth();
              l += 1;
            }
          }
          if (o() == null)
            continue;
          i = o().getHeight();
          label158: j = o().getWidth();
        }
        while ((i == 0) || (j == 0));
        l = (int)(i * j());
        j = (int)(j * j());
      }
      while ((l <= i3) && (j <= i2));
      int k = getResources().getDimensionPixelSize(R.g.scrollbarSize);
      i = 0;
      Object localObject = new float[9];
      this.a.getValues(localObject);
      if (l > i3)
      {
        i = i3 * i3 / l;
        l = (int)(-localObject[5] * i3 / l);
        localDrawable = getResources().getDrawable(R.h.scrollbar_handle_vertical);
        localDrawable.setBounds(getWidth() - k, l, getWidth(), l + i);
        localDrawable.draw(paramCanvas);
        i = 1;
      }
      if (j <= i2)
        continue;
      i = i2 * i2 / j;
      int l = (int)(-localObject[2] * i2 / j);
      localObject = getResources().getDrawable(R.h.scrollbar_handle_horizontal);
      int j = l + i;
      i = j;
      if (j >= getRight())
        i = j - (k + 1);
      ((Drawable)localObject).setBounds(l, getHeight() - k, i, getHeight());
      ((Drawable)localObject).draw(paramCanvas);
      i = 1;
    }
    while ((i == 0) || (l1 >= 600L));
    invalidate();
  }

才知道原来他的左右的滚动条也是自己进过计算画上去的,果然还是想要什么就自己去画吧(这里用drawable.draw 去画出来)。

重要的事情说3遍:
由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!
由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!
由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值