注: 这里说的图片的平移和缩放不是对ImageView整个view进行的,而是对ImageView里面的图片进行的(view本身没有什么变化),所以Android自带的动画效果不能满足需求。
功能点:
1、一开始可以像centerCrop一样显示图片(觉得scaleType为centerCrop时显示效果比较好,图片会铺满整个View,而且图片本身的分辨率不变)
2、对ImageView里的图片平移或放大
3、将这个平移或放大做成一个动画效果
一、在ScaleType为matrix的情况下实现centerCrop的显示效果
要充分利用Android的源码,看ImageView的源代码就可以简单很多,在configureBounds()方法中:
不过为了之后的平移,要保证图片的宽度比View的宽度大
publicvoidsetImage(Drawabledrawable){
if(null==drawable)return;
intdwidth=drawable.getIntrinsicWidth();
intdheight=drawable.getIntrinsicHeight();
intvwidth=mWidth;
intvheight=mHeight;
floatscale=1.0f;
floatdx=0,dy=0;
if(dwidth*vheight>vwidth*dheight){
scale=(float)vheight/(float)dheight;
dx=(vwidth-dwidth*scale)*0.5f+0.5f;
}else{
scale=(float)vwidth/(float)dwidth;
dy=(vheight-dheight*scale)*0.5f+0.5f;
}
if(dwidth*scale<2*vwidth){
scale=(float)vwidth/(2.0f*dwidth);
dx=-dwidth/2;
dy=(vheight-dheight*scale)*0.5f+0.5f;
}
Matrixmatrix=newMatrix();
matrix.setScale(scale,scale);
matrix.postTranslate(dx,dy);
mImage.setImageMatrix(matrix);
mImage.setImageDrawable(drawable);
}
// vwidth和vheight使用确定的值,因为如果在应用初始化时view.getWidth()可能为0
二、利用Matrix实现平移和放大
平移和放大都是在当前图片的基础上,先用mImage.getImageMatrix()得到当前的matrix,再用Matrix的postTranslate或postScale方法就可以了。
需要注意的是:
如果用Matrix matrix = mImage.getImageMatrix (); //matrix只是得到一个对象的引用
应该用Matrix matrix = new Matrix ( mImage.getImageMatrix () );//这样才是得到一个克隆对象
三、用ValueAnimator实现动画效果
1、平移
dx为负是向左平移,为正是向右平移
因为图片的宽度设置为至少是view的2倍,所以向左和向右平移的最大距离都是vwidth / 2。
privateclassMyTransXAnimatorListenerimplementsAnimatorUpdateListener{
privateMatrixmPrimaryMatrix;
publicMyTransXAnimatorListener(Matrixmatrix){
mPrimaryMatrix=newMatrix(matrix);
}
@Override
publicvoidonAnimationUpdate(ValueAnimatoranimation){
intdx=(Integer)animation.getAnimatedValue();
Matrixmatrix=newMatrix(mPrimaryMatrix);
matrix.postTranslate(dx,0);
mImage.setImageMatrix(matrix);
}
}
publicvoidsetTranslateAnimation(){
ValueAnimatoranimator=ValueAnimator.ofInt(0,-60);
animator.addUpdateListener(newMyTransXAnimatorListener(mImage.getImageMatrix()));
animator.setDuration(1000);
animator.setInterpolator(newDecelerateInterpolator());
animator.setStartDelay(500);
animator.start();
}
2、放大
放大要设置中心点为ImageView的中心
privateclassMyScaleAnimatorListenerimplementsAnimatorUpdateListener{
privateMatrixmPrimaryMatrix;
publicMyScaleAnimatorListener(Matrixmatrix){
mPrimaryMatrix=matrix;
}
@Override
publicvoidonAnimationUpdate(ValueAnimatoranimation){
floatscale=(Float)animation.getAnimatedValue();
Matrixmatrix=newMatrix(mPrimaryMatrix);
matrix.postScale(scale,scale,mWidth/2,mHeight/2);
mImage.setImageMatrix(matrix);
}
}
publicvoidsetScaleAnimation(){
ValueAnimatoranimator=ValueAnimator.ofFloat(1.0f,1.2f);
animator.addUpdateListener(newMyScaleAnimatorListener(mImage.getImageMatrix()));
animator.setDuration(1000);
animator.setInterpolator(newDecelerateInterpolator());
animator.setStartDelay(500);
animator.start();
}