Android 如何实现此代码的收缩到缩放

Android 如何实现此代码的收缩到缩放,android,android-viewpager,android-imageview,pinchzoom,Android,Android Viewpager,Android Imageview,Pinchzoom,我正在开发一个包含一些照片的应用程序。在这个应用程序中,我正在尝试实现“收缩到缩放”活动。我不知道该怎么做。我正在为这个示例搜索一周多的时间,没有任何示例可以实现收缩以放大ViewPager。这是我的密码。请帮我实现这一点,对不起我的英语。这里的al1、al2、al3都是可绘制文件夹中的图像 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

我正在开发一个包含一些照片的应用程序。在这个应用程序中,我正在尝试实现“收缩到缩放”活动。我不知道该怎么做。我正在为这个示例搜索一周多的时间,没有任何示例可以实现收缩以放大
ViewPager
。这是我的密码。请帮我实现这一点,对不起我的英语。这里的al1、al2、al3都是可绘制文件夹中的图像

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.content_main);

    ViewPager mViewPager = (ViewPager) findViewById(R.id.viewPageAndroid);
    AndroidImageAdapter adapterView = new AndroidImageAdapter(this);
    mViewPager.setAdapter(adapterView);


}




private class AndroidImageAdapter extends PagerAdapter {
    Context mContext;

    AndroidImageAdapter(Context context) {
        this.mContext = context;
    }
    @Override
    public int getCount() {
        return sliderImagesId.length;
    }
    private int[] sliderImagesId = new int[]{
            R.drawable.al1, R.drawable.al2, R.drawable.al3,
            R.drawable.al4, R.drawable.al5, R.drawable.al6,
            R.drawable.al7, R.drawable.al8,
    };

    @Override
    public boolean isViewFromObject(View v, Object obj) {
        return v == ((ImageView) obj);
    } @Override
    public Object instantiateItem(ViewGroup container, int i) {
        ImageView mImageView = new ImageView(mContext);
        mImageView.setScaleType(ImageView.ScaleType.FIT_XY);
        mImageView.setImageResource(sliderImagesId[i]);
        ((ViewPager) container).addView(mImageView, 0);
        return mImageView;
    }

    @Override
    public void destroyItem(ViewGroup container, int i, Object obj) {
        ((ViewPager) container).removeView((ImageView) obj);
    }}
}


从中使用此类 实现该类后,在视图页面中使用
TouchImageView
而不是
ImageView
,如下所示:

   @Override
    public boolean isViewFromObject(View v, Object obj) {
        return v == ((TouchImageView ) obj);
    } @Override
    public Object instantiateItem(ViewGroup container, int i) {
        TouchImageView mImageView = new TouchImageView(mContext);
        mImageView.setScaleType(ImageView.ScaleType.FIT_XY);
        mImageView.setImageResource(sliderImagesId[i]);
        ((ViewPager) container).addView(mImageView, 0);
        return mImageView;
    }

    @Override
    public void destroyItem(ViewGroup container, int i, Object obj) {
        ((ViewPager) container).removeView((TouchImageView) obj);
    }}
试试这个

 public class CustomViewPager extends ViewPager {

     public CustomViewPager(Context context) {
         super(context);
     }

     public CustomViewPager(Context context, AttributeSet attrs) {
         super(context, attrs);
     }

     public interface ZoomViewListener {

         void onZoomStarted(float zoom, float zoomx, float zoomy);

         void onZooming(float zoom, float zoomx, float zoomy);

         void onZoomEnded(float zoom, float zoomx, float zoomy);
     }

     // zooming
     float zoom = 1.0f;
     float maxZoom = 2.0f;
     float smoothZoom = 1.0f;
     float zoomX, zoomY;
     float smoothZoomX, smoothZoomY;
     private boolean scrolling; // NOPMD by karooolek on 29.06.11 11:45

     // minimap variables
     private boolean showMinimap = false;
     private int miniMapColor = Color.BLACK;
     private int miniMapHeight = -1;
     private String miniMapCaption;
     private float miniMapCaptionSize = 10.0f;
     private int miniMapCaptionColor = Color.WHITE;

     // touching variables
     private long lastTapTime;
     private float touchStartX, touchStartY;
     private float touchLastX, touchLastY;
     private float startd;
     private boolean pinching;
     private float lastd;
     private float lastdx1, lastdy1;
     private float lastdx2, lastdy2;

     // drawing
     private final Matrix m = new Matrix();
     private final Paint p = new Paint();

     // listener
     ZoomViewListener listener;

     private Bitmap ch;

     public float getZoom() {
         return zoom;
     }

     public float getMaxZoom() {
         return maxZoom;
     }

     public void setMaxZoom(final float maxZoom) {
         if (maxZoom < 1.0f) {
             return;
         }

         this.maxZoom = maxZoom;
     }

     public void setMiniMapEnabled(final boolean showMiniMap) {
         this.showMinimap = showMiniMap;
     }

     public boolean isMiniMapEnabled() {
         return showMinimap;
     }

     public void setMiniMapHeight(final int miniMapHeight) {
         if (miniMapHeight < 0) {
             return;
         }
         this.miniMapHeight = miniMapHeight;
     }

     public int getMiniMapHeight() {
         return miniMapHeight;
     }

     public void setMiniMapColor(final int color) {
         miniMapColor = color;
     }

     public int getMiniMapColor() {
         return miniMapColor;
     }

     public String getMiniMapCaption() {
         return miniMapCaption;
     }

     public void setMiniMapCaption(final String miniMapCaption) {
         this.miniMapCaption = miniMapCaption;
     }

     public float getMiniMapCaptionSize() {
         return miniMapCaptionSize;
     }

     public void setMiniMapCaptionSize(final float size) {
         miniMapCaptionSize = size;
     }

     public int getMiniMapCaptionColor() {
         return miniMapCaptionColor;
     }

     public void setMiniMapCaptionColor(final int color) {
         miniMapCaptionColor = color;
     }

     public void zoomTo(final float zoom, final float x, final float y) {
         this.zoom = Math.min(zoom, maxZoom);
         zoomX = x;
         zoomY = y;
         smoothZoomTo(this.zoom, x, y);
     }

     public void smoothZoomTo(final float zoom, final float x, final float y) {
         smoothZoom = clamp(1.0f, zoom, maxZoom);
         smoothZoomX = x;
         smoothZoomY = y;
         if (listener != null) {
             listener.onZoomStarted(smoothZoom, x, y);
         }
     }

     public ZoomViewListener getListener() {
         return listener;
     }

     public void setListner(final ZoomViewListener listener) {
         this.listener = listener;
     }

     public float getZoomFocusX() {
         return zoomX * zoom;
     }

     public float getZoomFocusY() {
         return zoomY * zoom;
     }

     @Override
     public boolean dispatchTouchEvent(final MotionEvent ev) {
         // single touch
         if (ev.getPointerCount() == 1) {
             processSingleTouchEvent(ev);
         }

         // // double touch
         if (ev.getPointerCount() == 2) {
             processDoubleTouchEvent(ev);
         }

         // redraw
         getRootView().invalidate();
         invalidate();

         return true;
     }

     private void processSingleTouchEvent(final MotionEvent ev) {

         final float x = ev.getX();
         final float y = ev.getY();

         final float w = miniMapHeight * (float) getWidth() / getHeight();
         final float h = miniMapHeight;
         final boolean touchingMiniMap = x >= 10.0f && x <= 10.0f + w && y >= 10.0f && y <= 10.0f + h;

         if (showMinimap && smoothZoom > 1.0f && touchingMiniMap) {
             processSingleTouchOnMinimap(ev);
         } else {
             processSingleTouchOutsideMinimap(ev);
         }
     }

     private void processSingleTouchOnMinimap(final MotionEvent ev) {
         final float x = ev.getX();
         final float y = ev.getY();

         final float w = miniMapHeight * (float) getWidth() / getHeight();
         final float h = miniMapHeight;
         final float zx = (x - 10.0f) / w * getWidth();
         final float zy = (y - 10.0f) / h * getHeight();
         smoothZoomTo(smoothZoom, zx, zy);
     }

     private void processSingleTouchOutsideMinimap(final MotionEvent ev) {
         final float x = ev.getX();
         final float y = ev.getY();
         float lx = x - touchStartX;
         float ly = y - touchStartY;
         final float l = (float) Math.hypot(lx, ly);
         float dx = x - touchLastX;
         float dy = y - touchLastY;
         touchLastX = x;
         touchLastY = y;

         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 touchStartX = x;
                 touchStartY = y;
                 touchLastX = x;
                 touchLastY = y;
                 dx = 0;
                 dy = 0;
                 lx = 0;
                 ly = 0;
                 scrolling = false;
                 break;

             case MotionEvent.ACTION_MOVE:
                 if (scrolling || (smoothZoom > 1.0f && l > 30.0f)) {
                     if (!scrolling) {
                         scrolling = true;
                         ev.setAction(MotionEvent.ACTION_CANCEL);
                         super.dispatchTouchEvent(ev);
                     }
                     smoothZoomX -= dx / zoom;
                     smoothZoomY -= dy / zoom;
                     return;
                 }
                 break;

             case MotionEvent.ACTION_OUTSIDE:
             case MotionEvent.ACTION_UP:

                 // tap
                 if (l < 30.0f) {
                     // check double tap
                     if (System.currentTimeMillis() - lastTapTime < 500) {
                         if (smoothZoom == 1.0f) {
                             smoothZoomTo(maxZoom, x, y);
                         } else {
                             smoothZoomTo(1.0f, getWidth() / 2.0f, getHeight() / 2.0f);
                         }
                         lastTapTime = 0;
                         ev.setAction(MotionEvent.ACTION_CANCEL);
                         super.dispatchTouchEvent(ev);
                         return;
                     }

                     lastTapTime = System.currentTimeMillis();

                     performClick();
                 }
                 break;

             default:
                 break;
         }

         ev.setLocation(zoomX + (x - 0.5f * getWidth()) / zoom, zoomY + (y - 0.5f * getHeight()) / zoom);

         ev.getX();
         ev.getY();

         super.dispatchTouchEvent(ev);
     }

     private void processDoubleTouchEvent(final MotionEvent ev) {
         final float x1 = ev.getX(0);
         final float dx1 = x1 - lastdx1;
         lastdx1 = x1;
         final float y1 = ev.getY(0);
         final float dy1 = y1 - lastdy1;
         lastdy1 = y1;
         final float x2 = ev.getX(1);
         final float dx2 = x2 - lastdx2;
         lastdx2 = x2;
         final float y2 = ev.getY(1);
         final float dy2 = y2 - lastdy2;
         lastdy2 = y2;

         // pointers distance
         final float d = (float) Math.hypot(x2 - x1, y2 - y1);
         final float dd = d - lastd;
         lastd = d;
         final float ld = Math.abs(d - startd);

         Math.atan2(y2 - y1, x2 - x1);
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 startd = d;
                 pinching = false;
                 break;

             case MotionEvent.ACTION_MOVE:
                 if (pinching || ld > 30.0f) {
                     pinching = true;
                     final float dxk = 0.5f * (dx1 + dx2);
                     final float dyk = 0.5f * (dy1 + dy2);
                     smoothZoomTo(Math.max(1.0f, zoom * d / (d - dd)), zoomX - dxk / zoom, zoomY - dyk / zoom);
                 }

                 break;

             case MotionEvent.ACTION_UP:
             default:
                 pinching = false;
                 break;
         }

         ev.setAction(MotionEvent.ACTION_CANCEL);
         super.dispatchTouchEvent(ev);
     }

     private float clamp(final float min, final float value, final float max) {
         return Math.max(min, Math.min(value, max));
     }

     private float lerp(final float a, final float b, final float k) {
         return a + (b - a) * k;
     }

     private float bias(final float a, final float b, final float k) {
         return Math.abs(b - a) >= k ? a + k * Math.signum(b - a) : b;
     }

     @Override
     protected void dispatchDraw(final Canvas canvas) {
         // do zoom
         zoom = lerp(bias(zoom, smoothZoom, 0.05f), smoothZoom, 0.2f);
         smoothZoomX = clamp(0.5f * getWidth() / smoothZoom, smoothZoomX, getWidth() - 0.5f * getWidth() / smoothZoom);
         smoothZoomY = clamp(0.5f * getHeight() / smoothZoom, smoothZoomY, getHeight() - 0.5f * getHeight() / smoothZoom);

         zoomX = lerp(bias(zoomX, smoothZoomX, 0.1f), smoothZoomX, 0.35f);
         zoomY = lerp(bias(zoomY, smoothZoomY, 0.1f), smoothZoomY, 0.35f);
         if (zoom != smoothZoom && listener != null) {
             listener.onZooming(zoom, zoomX, zoomY);
         }

         final boolean animating = Math.abs(zoom - smoothZoom) > 0.0000001f
                 || Math.abs(zoomX - smoothZoomX) > 0.0000001f || Math.abs(zoomY - smoothZoomY) > 0.0000001f;

         // nothing to draw
         if (getChildCount() == 0) {
             return;
         }

         // prepare matrix
         m.setTranslate(0.5f * getWidth(), 0.5f * getHeight());
         m.preScale(zoom, zoom);
         m.preTranslate(-clamp(0.5f * getWidth() / zoom, zoomX, getWidth() - 0.5f * getWidth() / zoom),
                 -clamp(0.5f * getHeight() / zoom, zoomY, getHeight() - 0.5f * getHeight() / zoom));

         // get view
         final View v = getChildAt(0);
         m.preTranslate(v.getLeft(), v.getTop());

         // get drawing cache if available
         if (animating && ch == null && isAnimationCacheEnabled()) {
             v.setDrawingCacheEnabled(true);
             ch = v.getDrawingCache();
         }

         // draw using cache while animating
         if (animating && isAnimationCacheEnabled() && ch != null) {
             p.setColor(0xffffffff);
             canvas.drawBitmap(ch, m, p);
         } else { // zoomed or cache unavailable
             ch = null;
             canvas.save();
             canvas.concat(m);
             v.draw(canvas);
             canvas.restore();
         }

         // draw minimap
         if (showMinimap) {
             if (miniMapHeight < 0) {
                 miniMapHeight = getHeight() / 4;
             }

             canvas.translate(10.0f, 10.0f);

             p.setColor(0x80000000 | 0x00ffffff & miniMapColor);
             final float w = miniMapHeight * (float) getWidth() / getHeight();
             final float h = miniMapHeight;
             canvas.drawRect(0.0f, 0.0f, w, h, p);

             if (miniMapCaption != null && miniMapCaption.length() > 0) {
                 p.setTextSize(miniMapCaptionSize);
                 p.setColor(miniMapCaptionColor);
                 p.setAntiAlias(true);
                 canvas.drawText(miniMapCaption, 10.0f, 10.0f + miniMapCaptionSize, p);
                 p.setAntiAlias(false);
             }

             p.setColor(0x80000000 | 0x00ffffff & miniMapColor);
             final float dx = w * zoomX / getWidth();
             final float dy = h * zoomY / getHeight();
             canvas.drawRect(dx - 0.5f * w / zoom, dy - 0.5f * h / zoom, dx + 0.5f * w / zoom, dy + 0.5f * h / zoom, p);

             canvas.translate(-10.0f, -10.0f);
         }

         // redraw
         // if (animating) {
         getRootView().invalidate();
         invalidate();
         // }
     }
 }
公共类CustomViewPager扩展了ViewPager{
公共CustomViewPager(上下文){
超级(上下文);
}
公共CustomViewPager(上下文、属性集属性){
超级(上下文,attrs);
}
公共接口ZoomViewListener{
void onZoomStarted(浮动缩放、浮动缩放、浮动缩放);
无效缩放(浮动缩放、浮动缩放、浮动缩放);
void onzoommended(浮动缩放、浮动缩放、浮动缩放);
}
//缩放
浮动缩放=1.0f;
float maxZoom=2.0f;
浮动平滑缩放=1.0f;
浮动zoomX,缩放;
浮动smoothZoomX、smoothZoomY;
私有布尔滚动;//NOPMD由karooolek于29.06.11 11:45
//小地图变量
私有布尔showMinimap=false;
private int miniMapColor=Color.BLACK;
私有整数最小值=-1;
私有字符串最小化;
私有浮动最小apcaptionSize=10.0f;
private int minimappationcolor=Color.WHITE;
//接触变量
私人长时间;
私人浮动touchStartX,touchStartY;
私人浮动touchLastX,touchLastY;
私人浮动标准;
私有布尔pinching;
私人浮动lastd;
私人浮动lastdx1,lastdy1;
私人浮动lastdx2,lastdy2;
//绘图
私有最终矩阵m=新矩阵();
专用最终油漆p=新油漆();
//听众
ZoomViewListener侦听器;
私家车;
公共浮点getZoom(){
返回缩放;
}
公共浮点getMaxZoom(){
返回最大缩放;
}
公共void setMaxZoom(最终浮点maxZoom){
如果(最大缩放<1.0f){
返回;
}
this.maxZoom=maxZoom;
}
公共void setMiniMapEnabled(最终布尔值showMiniMap){
this.showMinimap=showMinimap;
}
公共布尔值isMiniMapEnabled(){
返回小地图;
}
公共无效设置最小值(最终整数最小值){
如果(最小重量<0){
返回;
}
this.minimaphere=最小重量;
}
public int getminimaphight(){
返回微量计;
}
公共无效设置最小颜色(最终内部颜色){
最小颜色=颜色;
}
public int getminimacpolor(){
返回最小颜色;
}
公共字符串getMiniMapCaption(){
返回最小值;
}
public void setminimacaption(最终字符串minimacaption){
this.minimappation=minimappation;
}
公共浮点getMiniMapCaptionSize(){
返回最小apcaptionsize;
}
公共void setMiniMapCaptionSize(最终浮点大小){
miniMapCaptionSize=大小;
}
public int getminimappationcolor(){
返回最小颜色;
}
公共无效设置MinimapCaptionColor(最终内部颜色){
最小颜色=颜色;
}
公共空心缩放(最终浮动缩放、最终浮动x、最终浮动y){
this.zoom=Math.min(zoom,maxZoom);
zoomX=x;
zoomY=y;
smoothZoomTo(this.zoom,x,y);
}
公共空心smoothZoomTo(最终浮点缩放、最终浮点x、最终浮点y){
平滑缩放=钳制(1.0f,缩放,最大缩放);
smoothZoomX=x;
smoothZoomY=y;
if(侦听器!=null){
onZoomStarted(平滑缩放,x,y);
}
}
公共ZoomViewListener getListener(){
返回侦听器;
}
public void setListner(最终ZoomViewListener侦听器){
this.listener=listener;
}
公共浮点getZoomFocusX(){
返回zoomX*zoom;
}
公共浮点getZoomFocusY(){
返回zoomY*zoom;
}
@凌驾
公共布尔dispatchTouchEvent(最终运动事件ev){
//单触式
if(ev.getPointerCount()==1){
processSingleTouchEvent(ev);
}
////双重接触
if(ev.getPointerCount()==2){
processDoubleTouchEvent(ev);
}
//重画
getRootView().invalidate();
使无效();
返回true;
}
私有void processSingleTouchEvent(最终MotionEvent ev){
最终浮点数x=ev.getX();
最终浮动y=ev.getY();
最终浮动w=最小重量*(浮动)getWidth()/getHeight();
最终浮球h=最小浮球;
最终布尔值touchingMiniMap=x>=10.0f&&x=10.0f&&y 1.0f&&touchingMiniMap){
processSingleTouchOnMinimap(ev);
}否则{
处理单点接触外血脂(ev);
}
}
私有void processSingleTouchOnMinimap(最终运动事件ev){
最终浮点数x=ev.getX();
最终浮动y=ev.getY();
最终浮动w=最小重量*(浮动)getWidth()/getHeight();
最终浮球h=最小浮球;
最终浮点数zx=(x-10.0f)/w*getWidth();
最终浮点数zy=(y-10.0f)/h*getHeight();
smoothZoomTo(smoothZoom、zx、zy);
}
私有void进程SingleTouchOutSemidInMap(最终运动事件ev){
最终浮点数x=ev.getX();
最终浮动y=ev.getY();
float lx=x-touchStartX;
float ly=y-触摸屏;
最终浮点数
 public class CustomViewPager extends ViewPager {

     public CustomViewPager(Context context) {
         super(context);
     }

     public CustomViewPager(Context context, AttributeSet attrs) {
         super(context, attrs);
     }

     public interface ZoomViewListener {

         void onZoomStarted(float zoom, float zoomx, float zoomy);

         void onZooming(float zoom, float zoomx, float zoomy);

         void onZoomEnded(float zoom, float zoomx, float zoomy);
     }

     // zooming
     float zoom = 1.0f;
     float maxZoom = 2.0f;
     float smoothZoom = 1.0f;
     float zoomX, zoomY;
     float smoothZoomX, smoothZoomY;
     private boolean scrolling; // NOPMD by karooolek on 29.06.11 11:45

     // minimap variables
     private boolean showMinimap = false;
     private int miniMapColor = Color.BLACK;
     private int miniMapHeight = -1;
     private String miniMapCaption;
     private float miniMapCaptionSize = 10.0f;
     private int miniMapCaptionColor = Color.WHITE;

     // touching variables
     private long lastTapTime;
     private float touchStartX, touchStartY;
     private float touchLastX, touchLastY;
     private float startd;
     private boolean pinching;
     private float lastd;
     private float lastdx1, lastdy1;
     private float lastdx2, lastdy2;

     // drawing
     private final Matrix m = new Matrix();
     private final Paint p = new Paint();

     // listener
     ZoomViewListener listener;

     private Bitmap ch;

     public float getZoom() {
         return zoom;
     }

     public float getMaxZoom() {
         return maxZoom;
     }

     public void setMaxZoom(final float maxZoom) {
         if (maxZoom < 1.0f) {
             return;
         }

         this.maxZoom = maxZoom;
     }

     public void setMiniMapEnabled(final boolean showMiniMap) {
         this.showMinimap = showMiniMap;
     }

     public boolean isMiniMapEnabled() {
         return showMinimap;
     }

     public void setMiniMapHeight(final int miniMapHeight) {
         if (miniMapHeight < 0) {
             return;
         }
         this.miniMapHeight = miniMapHeight;
     }

     public int getMiniMapHeight() {
         return miniMapHeight;
     }

     public void setMiniMapColor(final int color) {
         miniMapColor = color;
     }

     public int getMiniMapColor() {
         return miniMapColor;
     }

     public String getMiniMapCaption() {
         return miniMapCaption;
     }

     public void setMiniMapCaption(final String miniMapCaption) {
         this.miniMapCaption = miniMapCaption;
     }

     public float getMiniMapCaptionSize() {
         return miniMapCaptionSize;
     }

     public void setMiniMapCaptionSize(final float size) {
         miniMapCaptionSize = size;
     }

     public int getMiniMapCaptionColor() {
         return miniMapCaptionColor;
     }

     public void setMiniMapCaptionColor(final int color) {
         miniMapCaptionColor = color;
     }

     public void zoomTo(final float zoom, final float x, final float y) {
         this.zoom = Math.min(zoom, maxZoom);
         zoomX = x;
         zoomY = y;
         smoothZoomTo(this.zoom, x, y);
     }

     public void smoothZoomTo(final float zoom, final float x, final float y) {
         smoothZoom = clamp(1.0f, zoom, maxZoom);
         smoothZoomX = x;
         smoothZoomY = y;
         if (listener != null) {
             listener.onZoomStarted(smoothZoom, x, y);
         }
     }

     public ZoomViewListener getListener() {
         return listener;
     }

     public void setListner(final ZoomViewListener listener) {
         this.listener = listener;
     }

     public float getZoomFocusX() {
         return zoomX * zoom;
     }

     public float getZoomFocusY() {
         return zoomY * zoom;
     }

     @Override
     public boolean dispatchTouchEvent(final MotionEvent ev) {
         // single touch
         if (ev.getPointerCount() == 1) {
             processSingleTouchEvent(ev);
         }

         // // double touch
         if (ev.getPointerCount() == 2) {
             processDoubleTouchEvent(ev);
         }

         // redraw
         getRootView().invalidate();
         invalidate();

         return true;
     }

     private void processSingleTouchEvent(final MotionEvent ev) {

         final float x = ev.getX();
         final float y = ev.getY();

         final float w = miniMapHeight * (float) getWidth() / getHeight();
         final float h = miniMapHeight;
         final boolean touchingMiniMap = x >= 10.0f && x <= 10.0f + w && y >= 10.0f && y <= 10.0f + h;

         if (showMinimap && smoothZoom > 1.0f && touchingMiniMap) {
             processSingleTouchOnMinimap(ev);
         } else {
             processSingleTouchOutsideMinimap(ev);
         }
     }

     private void processSingleTouchOnMinimap(final MotionEvent ev) {
         final float x = ev.getX();
         final float y = ev.getY();

         final float w = miniMapHeight * (float) getWidth() / getHeight();
         final float h = miniMapHeight;
         final float zx = (x - 10.0f) / w * getWidth();
         final float zy = (y - 10.0f) / h * getHeight();
         smoothZoomTo(smoothZoom, zx, zy);
     }

     private void processSingleTouchOutsideMinimap(final MotionEvent ev) {
         final float x = ev.getX();
         final float y = ev.getY();
         float lx = x - touchStartX;
         float ly = y - touchStartY;
         final float l = (float) Math.hypot(lx, ly);
         float dx = x - touchLastX;
         float dy = y - touchLastY;
         touchLastX = x;
         touchLastY = y;

         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 touchStartX = x;
                 touchStartY = y;
                 touchLastX = x;
                 touchLastY = y;
                 dx = 0;
                 dy = 0;
                 lx = 0;
                 ly = 0;
                 scrolling = false;
                 break;

             case MotionEvent.ACTION_MOVE:
                 if (scrolling || (smoothZoom > 1.0f && l > 30.0f)) {
                     if (!scrolling) {
                         scrolling = true;
                         ev.setAction(MotionEvent.ACTION_CANCEL);
                         super.dispatchTouchEvent(ev);
                     }
                     smoothZoomX -= dx / zoom;
                     smoothZoomY -= dy / zoom;
                     return;
                 }
                 break;

             case MotionEvent.ACTION_OUTSIDE:
             case MotionEvent.ACTION_UP:

                 // tap
                 if (l < 30.0f) {
                     // check double tap
                     if (System.currentTimeMillis() - lastTapTime < 500) {
                         if (smoothZoom == 1.0f) {
                             smoothZoomTo(maxZoom, x, y);
                         } else {
                             smoothZoomTo(1.0f, getWidth() / 2.0f, getHeight() / 2.0f);
                         }
                         lastTapTime = 0;
                         ev.setAction(MotionEvent.ACTION_CANCEL);
                         super.dispatchTouchEvent(ev);
                         return;
                     }

                     lastTapTime = System.currentTimeMillis();

                     performClick();
                 }
                 break;

             default:
                 break;
         }

         ev.setLocation(zoomX + (x - 0.5f * getWidth()) / zoom, zoomY + (y - 0.5f * getHeight()) / zoom);

         ev.getX();
         ev.getY();

         super.dispatchTouchEvent(ev);
     }

     private void processDoubleTouchEvent(final MotionEvent ev) {
         final float x1 = ev.getX(0);
         final float dx1 = x1 - lastdx1;
         lastdx1 = x1;
         final float y1 = ev.getY(0);
         final float dy1 = y1 - lastdy1;
         lastdy1 = y1;
         final float x2 = ev.getX(1);
         final float dx2 = x2 - lastdx2;
         lastdx2 = x2;
         final float y2 = ev.getY(1);
         final float dy2 = y2 - lastdy2;
         lastdy2 = y2;

         // pointers distance
         final float d = (float) Math.hypot(x2 - x1, y2 - y1);
         final float dd = d - lastd;
         lastd = d;
         final float ld = Math.abs(d - startd);

         Math.atan2(y2 - y1, x2 - x1);
         switch (ev.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 startd = d;
                 pinching = false;
                 break;

             case MotionEvent.ACTION_MOVE:
                 if (pinching || ld > 30.0f) {
                     pinching = true;
                     final float dxk = 0.5f * (dx1 + dx2);
                     final float dyk = 0.5f * (dy1 + dy2);
                     smoothZoomTo(Math.max(1.0f, zoom * d / (d - dd)), zoomX - dxk / zoom, zoomY - dyk / zoom);
                 }

                 break;

             case MotionEvent.ACTION_UP:
             default:
                 pinching = false;
                 break;
         }

         ev.setAction(MotionEvent.ACTION_CANCEL);
         super.dispatchTouchEvent(ev);
     }

     private float clamp(final float min, final float value, final float max) {
         return Math.max(min, Math.min(value, max));
     }

     private float lerp(final float a, final float b, final float k) {
         return a + (b - a) * k;
     }

     private float bias(final float a, final float b, final float k) {
         return Math.abs(b - a) >= k ? a + k * Math.signum(b - a) : b;
     }

     @Override
     protected void dispatchDraw(final Canvas canvas) {
         // do zoom
         zoom = lerp(bias(zoom, smoothZoom, 0.05f), smoothZoom, 0.2f);
         smoothZoomX = clamp(0.5f * getWidth() / smoothZoom, smoothZoomX, getWidth() - 0.5f * getWidth() / smoothZoom);
         smoothZoomY = clamp(0.5f * getHeight() / smoothZoom, smoothZoomY, getHeight() - 0.5f * getHeight() / smoothZoom);

         zoomX = lerp(bias(zoomX, smoothZoomX, 0.1f), smoothZoomX, 0.35f);
         zoomY = lerp(bias(zoomY, smoothZoomY, 0.1f), smoothZoomY, 0.35f);
         if (zoom != smoothZoom && listener != null) {
             listener.onZooming(zoom, zoomX, zoomY);
         }

         final boolean animating = Math.abs(zoom - smoothZoom) > 0.0000001f
                 || Math.abs(zoomX - smoothZoomX) > 0.0000001f || Math.abs(zoomY - smoothZoomY) > 0.0000001f;

         // nothing to draw
         if (getChildCount() == 0) {
             return;
         }

         // prepare matrix
         m.setTranslate(0.5f * getWidth(), 0.5f * getHeight());
         m.preScale(zoom, zoom);
         m.preTranslate(-clamp(0.5f * getWidth() / zoom, zoomX, getWidth() - 0.5f * getWidth() / zoom),
                 -clamp(0.5f * getHeight() / zoom, zoomY, getHeight() - 0.5f * getHeight() / zoom));

         // get view
         final View v = getChildAt(0);
         m.preTranslate(v.getLeft(), v.getTop());

         // get drawing cache if available
         if (animating && ch == null && isAnimationCacheEnabled()) {
             v.setDrawingCacheEnabled(true);
             ch = v.getDrawingCache();
         }

         // draw using cache while animating
         if (animating && isAnimationCacheEnabled() && ch != null) {
             p.setColor(0xffffffff);
             canvas.drawBitmap(ch, m, p);
         } else { // zoomed or cache unavailable
             ch = null;
             canvas.save();
             canvas.concat(m);
             v.draw(canvas);
             canvas.restore();
         }

         // draw minimap
         if (showMinimap) {
             if (miniMapHeight < 0) {
                 miniMapHeight = getHeight() / 4;
             }

             canvas.translate(10.0f, 10.0f);

             p.setColor(0x80000000 | 0x00ffffff & miniMapColor);
             final float w = miniMapHeight * (float) getWidth() / getHeight();
             final float h = miniMapHeight;
             canvas.drawRect(0.0f, 0.0f, w, h, p);

             if (miniMapCaption != null && miniMapCaption.length() > 0) {
                 p.setTextSize(miniMapCaptionSize);
                 p.setColor(miniMapCaptionColor);
                 p.setAntiAlias(true);
                 canvas.drawText(miniMapCaption, 10.0f, 10.0f + miniMapCaptionSize, p);
                 p.setAntiAlias(false);
             }

             p.setColor(0x80000000 | 0x00ffffff & miniMapColor);
             final float dx = w * zoomX / getWidth();
             final float dy = h * zoomY / getHeight();
             canvas.drawRect(dx - 0.5f * w / zoom, dy - 0.5f * h / zoom, dx + 0.5f * w / zoom, dy + 0.5f * h / zoom, p);

             canvas.translate(-10.0f, -10.0f);
         }

         // redraw
         // if (animating) {
         getRootView().invalidate();
         invalidate();
         // }
     }
 }
<android.support.v4.view.ViewPager
android:id="@+id/viewPageAndroid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/aa"
/>
<com.example.demo.CustomViewPager
android:id="@+id/viewPageAndroid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/aa"
/>