2014-01-06 59 views
18

我想在Imageview上實現Pinch Zoom,在View Pager中類似於Default Android Gallery。我在GitHub上找到了多個源代碼,但縮放和滑動僅適用於第一個圖像。View Pager + ImageView + Pinch Zoom + Rotation

我曾嘗試:

1)TouchImageView

2)PhotoView

3)Android Touch Gallery

上述所有環節工作正常單張圖像顯示。但是,當涉及到圖像查看尋呼機,他們有一些毛刺,只適用於視圖尋呼機中的第一個圖像。當我們滾動到視圖尋呼機中的第4個圖像時,如果圖像被縮放,則拖動功能無法按預期工作。

如果有人知道這樣做有什麼好的圖書館,請爲我提供鏈接。

回答

38

編輯2:示例代碼已被推送到TouchImageView的主分支。這是一個link to the example activity和一個link to the ExtendedViewPager


編輯:添加代碼,調整示例鏈接到TouchImageView。注意:您將需要最新的代碼,該代碼當前位於開發分支中。將來,這將包含在v1.2.0中。如果TouchImageView覆蓋canScrollHorizo​​ntally,你知道你有最新的代碼。

第1步:擴展ViewPager並覆蓋canScroll來調用canScrollHorizo​​ntallyFroyo。

public class ExtendedViewPager extends ViewPager { 

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

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

@Override 
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { 
    if (v instanceof TouchImageView) { 
     return ((TouchImageView) v).canScrollHorizontallyFroyo(-dx); 
    } else { 
     return super.canScroll(v, checkV, dx, x, y); 
    } 
} 

} 

步驟2:修改TouchImageView通過添加canScrollHorizo​​ntallyFroyo:

public boolean canScrollHorizontallyFroyo(int direction) { 
    return canScrollHorizontally(direction); 
} 

步驟3:你的活動

public class TouchImageViewActivity extends Activity { 

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     ExtendedViewPager mViewPager = (ExtendedViewPager) findViewById(R.id.view_pager); 
     setContentView(mViewPager); 
     mViewPager.setAdapter(new TouchImageAdapter()); 
    } 

    static class TouchImageAdapter extends PagerAdapter { 

      private static int[] images = { R.drawable.img1, R.drawable.img2, R.drawable.img3 }; 

      @Override 
      public int getCount() { 
        return images.length; 
      } 

      @Override 
      public View instantiateItem(ViewGroup container, int position) { 
        TouchImageView img = new TouchImageView(container.getContext()); 
        img.setImageResource(images[position]); 
        container.addView(img, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 
        return img; 
      } 

      @Override 
      public void destroyItem(ViewGroup container, int position, Object object) { 
        container.removeView((View) object); 
      } 

      @Override 
      public boolean isViewFromObject(View view, Object object) { 
        return view == object; 
      } 

    } 
} 

步驟4: main.xml中

<com.example.touch.ExtendedViewPager 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/view_pager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

TouchImageView實際上是我的項目。我目前在dev branch中有a fix與ViewPagers集成,將在即將發佈的版本中推送給Master。不幸的是,由於蜂窩和以前不叫canScrollHorizontally,此修補程序僅適用於API 14及更高版本。如果您需要支持較舊的API,則需要在ViewPager中實施解決方法。 Here is an example.

+1

這個解決方法對我來說不起作用。:(如果我用更高的速度滾動,它會將我移動到下一張幻燈片。 –

+0

@AvtarGuleria我的編輯幫助中包含了另一個解決方法嗎?我知道我已經成功地僱用了它在過去 –

+1

沒有第二個解決方法也沒有爲我工作每當我水平滾動,它只是將我移動到第二張幻燈片但如果我滾動垂直或以其他角度水平以外的其他角度..so,再次水平它不工作... –

4

我發現漂亮的解決方案與ImageViewZoom庫。 爲了在ViewPager滾動縮放圖像,我創建自己的ViewPager:

public class ExtendedViewPager extends ViewPager { 

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

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

    @Override 
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { 
     if (v instanceof ImageViewTouch) { 
      return ((ImageViewTouch) v).canScroll(dx); 
     } else { 
      return super.canScroll(v, checkV, dx, x, y); 
     } 
    } 
} 

查看更多https://gist.github.com/atermenji/3781644

+0

將視圖尋呼機縮放並滑動到下一圖像後,如果我滑回到上一圖像,該圖像不會出現在原始位置 – Shadow

+0

ViewPager不會從存儲器中銷燬先前的圖像,因此當您移動返回ViewPager只顯示保存狀態的對象。爲了重置縮放,您可以使用ImageViewTouch的方法resetDisplay或任何其他適合您的方法。 –

+0

是的,我用@Master但沒有工作。 http://stackoverflow.com/questions/25760505/how-to-reset-imageview-to-original-position-in-view-pager – Shadow

2

使用ImageViewZoom Library我的解決方案是基於這一習俗ViewPager:

public class ImageViewTouchViewPager extends ViewPager { 

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

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

    @Override 
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { 
     if (v instanceof ImageViewTouch) { 
      ImageViewTouch imageViewTouch = (ImageViewTouch)v; 
      if (imageViewTouch.getScale() == imageViewTouch.getMinScale()) { 
       return super.canScroll(v, checkV, dx, x, y); 
      } 
      return imageViewTouchCanScroll(imageViewTouch, dx); 
     } else { 
      return super.canScroll(v, checkV, dx, x, y); 
     } 
    } 


    /** 
    * Determines whether the ImageViewTouch can be scrolled. 
    * 
    * @param direction - positive direction value means scroll from right to left, 
    *     negative value means scroll from left to right 
    * @return true if there is some more place to scroll, false - otherwise. 
    */ 
    private boolean imageViewTouchCanScroll(ImageViewTouch v, int direction){ 
     RectF bitmapRect = v.getBitmapRect(); 
     Rect imageViewRect = new Rect(); 
     getGlobalVisibleRect(imageViewRect); 

     if (null == bitmapRect) { 
      return false; 
     } 

     if (direction < 0) { 
      return Math.abs(bitmapRect.right - imageViewRect.right) > 1.0f; 
     }else { 
      return Math.abs(bitmapRect.left - imageViewRect.left) > 1.0f; 
     } 

    } 
} 
0

我糾正了以前的方案。當ImageViewTouch進行模式縮放時,您可以滾動頁面。

public class ImageViewTouchViewPager extends ViewPager { 

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

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

@Override 
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { 
    if (v instanceof ImageViewTouch) { 
     ImageViewTouch imageViewTouch = (ImageViewTouch)v; 
     return imageViewTouchCanScroll(imageViewTouch, dx); 
    } else { 
     return super.canScroll(v, checkV, dx, x, y); 
    } 
} 


/** 
* Determines whether the ImageViewTouch can be scrolled. 
* 
* @param direction - positive direction value means scroll from right to left, 
*     negative value means scroll from left to right 
* @return true if there is some more place to scroll, false - otherwise. 
*/ 
private boolean imageViewTouchCanScroll(ImageViewTouch imageViewTouch, int direction){ 
    int widthScreen = getWidthScreen(); 

    RectF bitmapRect = imageViewTouch.getBitmapRect(); 
    Rect imageViewRect = new Rect(); 
    getGlobalVisibleRect(imageViewRect); 

    int widthBitmapViewTouch = (int)bitmapRect.width(); 

    if (null == bitmapRect) { 
     return false; 
    } 

    if(widthBitmapViewTouch < widthScreen){ 
     return false; 
    } 

    if (direction < 0) { 
     return Math.abs(bitmapRect.right - imageViewRect.right) > 1.0f; 
    }else { 
     return Math.abs(bitmapRect.left - imageViewRect.left) > 1.0f; 
    } 

} 

private int getWidthScreen(){ 
    WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 
    Display display = wm.getDefaultDisplay(); 

    Point size = new Point(); 
    display.getSize(size); 
    return size.x; 
} 

}