之前写过一篇文章 关于Andorid加载高清大图,有兴趣的可以去看一下。由于昨天弄了一下反编译其实是想看下google相册里面的一些动画效果的实现,经过本人查阅各种资料的不泄努力,终于还是没有得到什么实质性的努力效果。由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!
先说下结论,如果不感兴趣下面也可以不看:
1. 图片缩放使用的是Matrix
,以及Scroller
配合一些动画
2. 图片放大之后的滚动条是自己画上去的,不是系统的
如果一下内容造成了侵权行为,请通知我及时删除本文章
想到之前实现过的新浪长图功能,顺手今天看了下官方里面的具体实现。
顺便啰嗦两句,用的反编译工具是dex2jar+apktool,大家可以网上下载即可,自行体会。
好了开始今天的正题。主要类有2个TouchImageView
和SplitTouchImageView
。我先帖一下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遍:
由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!
由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!
由于本人能力有限,不足之处请大婶们多多包含,如果大家有更好的见解和说明,欢迎大家补充!!!