简体   繁体   English

如何为此代码实现捏合缩放

[英]How to implement pinch to zoom for this code

I am developing a app with some photos.In this app i am trying to implement the pinch to zoom activity.我正在开发一个带有一些照片的应用程序。在这个应用程序中,我正在尝试实现捏合缩放活动。 I don't know how to do.I am searching for more than one week for this examples and there is no any example for implementing pinch to zoom in ViewPager .我不知道该怎么做。我为此示例搜索了一个多星期,但没有任何示例可以实现捏合以放大ViewPager Here is my code.这是我的代码。 please help me to implement this and sorry for my English.请帮助我实现这一点,并为我的英语感到抱歉。 here al1, al2 al3, all are the images in drawable folder.这里al1,al2 al3,都是drawable文件夹中的图片。

@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);
    }}

} }

<android.support.v4.view.ViewPager
    android:id="@+id/viewPageAndroid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/aa"
    />

try this尝试这个

 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();
         // }
     }
 }

and replace this并替换这个

<android.support.v4.view.ViewPager
android:id="@+id/viewPageAndroid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/aa"
/>

to

<com.example.demo.CustomViewPager
android:id="@+id/viewPageAndroid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/aa"
/>

Use this class from HERE After implementing this class use TouchImageView instead of ImageView in your view pager like this:这里使用这个类在实现这个类之后,在你的视图寻呼机中使用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);
    }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM