1.效果
maimai.gif2.根据效果分析
这里脉脉APP上的图片效果有
1.双击放大
2.单手指滑动图片
3.图片惯性滑动
4.双指滑动放大缩小
3.代码实现
1.添加图片,将图片正常显示
image.png public class CMMaiMaiImageView extends View {
private static final float IMAGE_WIDTH = DpToPxUtil.dp2px(100);
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Bitmap mBitmap;
private float originOffsetX;
private float originOffsetY;
private float smallScalab;
private float bigScalab;
public CMMaiMaiImageView(Context context) {
this(context,null);
}
public CMMaiMaiImageView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public CMMaiMaiImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//添加绘制图片
mBitmap = CMBitMapUtils.getAvatarWithImage(getResources(),(int) IMAGE_WIDTH, R.drawable.kenan);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
originOffsetX = ((float)(getWidth() - mBitmap.getWidth())) / 2f;
originOffsetY = ((float)(getHeight() - mBitmap.getHeight())) / 2f;
if( ((float)mBitmap.getWidth()/mBitmap.getHeight()) > ((float) mBitmap.getHeight()/mBitmap.getWidth())){
//图片宽度比高度大,横向图片
smallScalab = (float) getWidth()/mBitmap.getWidth();
bigScalab = (float) getHeight()/mBitmap.getHeight();
}else{
//图片宽度比高度小,纵向图片
smallScalab = (float) getHeight()/mBitmap.getHeight();
bigScalab = (float) getWidth()/mBitmap.getWidth();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.scale(smallScalab,smallScalab,getWidth()/2f,getHeight()/2f);
canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
}
2.添加图片双击放大缩小效果
//判断当前图片展示的是大图还是小图
private boolean isBig;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float scale = isBig ? bigScalab : smallScalab;
canvas.scale(scale,scale,getWidth()/2f,getHeight()/2f);
canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
}
class CMGestureDetectorListener extends GestureDetector.SimpleOnGestureListener{
@Override
public boolean onDown(MotionEvent e) {
Log.e("====","onDow=");
return true;
}
@Override
public void onShowPress(MotionEvent e) {
Log.e("====","onShowPress=");
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.e("====","onSingleTapUp=");
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.e("====","onScroll=");
return false;
}
@Override
public void onLongPress(MotionEvent e) {
Log.e("====","onLongPress=");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
Log.e("====","onFling=");
return false;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.e("====","onSingleTapConfirmed=");
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.e("====","onDoubleTap=");
isBig = !isBig;
invalidate();
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
Log.e("====","onDoubleTapEvent=" + isBig);
return false;
}
}
3.添加图片放大缩小的动画
//图片放大缩小的动画
private float scaleFraction;
//图片放大缩小的动画
private ObjectAnimator mObjectAnimator;
public ObjectAnimator getObjectAnimator() {
if(mObjectAnimator == null){
mObjectAnimator = ObjectAnimator.ofFloat(this,"scaleFraction",0,1);
}
return mObjectAnimator;
}
public float getScaleFraction() {
return scaleFraction;
}
public void setScaleFraction(float scaleFraction) {
this.scaleFraction = scaleFraction;
invalidate();
}
双击手势中的处理
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.e("====","onDoubleTap=");
isBig = !isBig;
if(isBig){
getObjectAnimator().start();
}else{
getObjectAnimator().reverse();
}
return false;
}
绘制中的处理
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float scale = smallScalab + (bigScalab - smallScalab)*scaleFraction;
canvas.scale(scale,scale,getWidth()/2f,getHeight()/2f);
canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
}
4.图片放大后的滑动处理以及边界修正
这里图片放大后,需要实现可以将图片平移
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(offsetX,offsetY);
float scale = smallScalab + (bigScalab - smallScalab)*scaleFraction;
canvas.scale(scale,scale,getWidth()/2f,getHeight()/2f);
canvas.drawBitmap(mBitmap,originOffsetX,originOffsetY,mPaint);
}
图片放大后位置修正
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Log.e("====","onScroll=");
if(isBig){
offsetX -= distanceX;
offsetY -= distanceY;
offsetX = Math.min(offsetX,(mBitmap.getWidth()*bigScalab - getWidth())/2);
offsetX = Math.max(offsetX,-(mBitmap.getWidth()*bigScalab - getWidth())/2);
offsetY = Math.min(offsetY,(mBitmap.getHeight()*bigScalab - getHeight())/2);
offsetY = Math.max(offsetY,-(mBitmap.getHeight()*bigScalab - getHeight())/2);
invalidate();
}
return false;
}
5.惯性滑动 OverScroller
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if(isBig){
offsetX -= distanceX;
offsetY -= distanceY;
fixOffset();
invalidate();
}
return false;
}
private void fixOffset() {
offsetX = Math.min(offsetX,(mBitmap.getWidth()*bigScalab - getWidth())/2);
offsetX = Math.max(offsetX,-(mBitmap.getWidth()*bigScalab - getWidth())/2);
offsetY = Math.min(offsetY,(mBitmap.getHeight()*bigScalab - getHeight())/2);
offsetY = Math.max(offsetY,-(mBitmap.getHeight()*bigScalab - getHeight())/2);
}
6.双指放大缩小
class CMOnScaleListener implements ScaleGestureDetector.OnScaleGestureListener{
float initiaScale;
@Override
public boolean onScale(ScaleGestureDetector detector) {
currentFraction = initiaScale * detector.getScaleFactor() < smallScalab ? smallScalab:initiaScale * detector.getScaleFactor();
currentFraction = currentFraction > bigScalab ? bigScalab : currentFraction;
invalidate();
return false;
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
initiaScale = currentFraction;
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
}
}
7 完工效果
kenan.gif
网友评论