web-dev-qa-db-ja.com

ポケットベルの表示+ ImageView +ピンチズーム+回転

デフォルトのAndroid Galleryに似たView Pagerで、Imageviewにピンチズームを実装したい。GitHubで複数のソースを見つけたが、ズームとスライドは最初の画像に対してのみ機能する。

私が試したもの:

1.) TouchImageView

2.) PhotoView

3.) Android Touch Gallery

上記のリンクはすべて、単一の画像ビューで正常に機能します。しかし、View pagerの画像に関しては、いくつかの不具合があり、View Pagerの最初の画像でのみ正常に機能します。ビューページャーで3番目から4番目の画像にスクロールすると、画像がズームされている場合、ドラッグ機能が期待どおりに機能しません。

誰かがこれを行うための良いライブラリを知っているなら、それらへのリンクを私に提供してください。

19
Avtar Guleria

編集2:サンプルコードはTouchImageViewのマスターブランチにプッシュされています。 例のアクティビティへのリンク および ExtendedViewPagerへのリンク です。


編集:TouchImageViewへのサンプルリンクを適応させるコードを追加しました。注:現在devブランチにある最新のコードが必要になります。将来、これは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:canScrollHorizo​​ntallyFroyoを追加してTouchImageViewを変更します。

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ブランチ にあり、今後のリリースでマスターにプッシュされるViewPagersと統合します。残念ながら、ハニカムおよびそれ以前ではcanScrollHorizontallyを呼び出さないため、この修正はAPI 14以降にのみ適用されます。古いAPIをサポートする必要がある場合は、ViewPagerに回避策を実装する必要があります。 ここに例があります。

40
Mike Ortiz

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

4
Mansurov Ruslan

上記のソリューションを数時間テストした後、ようやく素晴らしい Subsampling Scale Image View ライブラリが見つかりました。これはAndroid Support Package。

3
lobzik

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

    }
}
2
moondroid

以前のソリューションを修正しました。 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;
}

}

0
Krystian