web-dev-qa-db-fra.com

Voir téléavertisseur + ImageView + Zoom pincé + Rotation

Je veux implémenter Pinch Zoom sur Imageview, avec dans View Pager similaire à Default Android Gallery. J'ai trouvé plusieurs sources sur GitHub, mais le zoom et le glissement ne fonctionnent que pour la première image uniquement.

Ce que j'ai essayé:

1.) TouchImageView

2.) PhotoView

3.) Galerie tactile Android

Tous les liens ci-dessus fonctionnent bien pour une vue d'image unique. Mais en ce qui concerne le pager Images dans View, ils ont quelques problèmes et ne fonctionnent correctement que pour la première image du View Pager. Lorsque nous faisons défiler jusqu'à la 3ème 4ème image dans le téléavertisseur, la fonctionnalité de glisser ne fonctionne pas comme prévu si l'image est agrandie.

S'il vous plaît, si quelqu'un connaît une bonne bibliothèque pour ce faire, alors fournissez-moi le lien pour eux.

19
Avtar Guleria

EDIT 2: un exemple de code a été transmis à la branche principale de TouchImageView. Voici un lien vers l'exemple d'activité et un lien vers ExtendedViewPager .


EDIT: ajout de code adaptant l'exemple de lien à TouchImageView. Remarque: vous aurez besoin du dernier code, qui se trouve actuellement dans la branche dev. À l'avenir, cela sera inclus dans la version 1.2.0. Vous savez que vous disposez du dernier code si TouchImageView remplace canScrollHorizontally.

Étape 1 : étendez ViewPager et remplacez canScroll pour appeler canScrollHorizontallyFroyo.

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

}

Étape 2: Modifiez TouchImageView en ajoutant canScrollHorizontallyFroyo:

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

Étape 3: Votre activité

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

    }
}

Étape 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 est en fait mon projet. J'ai actuellement n correctif dans la branche de développement pour l'intégration avec ViewPagers, qui sera poussé à maîtriser dans une prochaine version. Malheureusement, ce correctif n'est applicable que pour l'API 14 et les versions ultérieures, car honeycomb et les versions antérieures n'appellent pas canScrollHorizontally. Si vous devez prendre en charge des API plus anciennes, vous devrez implémenter une solution de contournement dans votre ViewPager. Voici un exemple.

40
Mike Ortiz

J'ai trouvé une jolie solution avec la bibliothèque ImageViewZoom . Afin de faire défiler l'image zoomée dans ViewPager, j'ai créé son propre 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);
        }
    }
}

Voir plus https://Gist.github.com/atermenji/3781644

4
Mansurov Ruslan

Après plusieurs heures de test des solutions ci-dessus, j'ai enfin trouvé la bibliothèque géniale Subsampling Scale Image View , qui fonctionne même avec ViewPager standard de Android Support Package.

3
lobzik

Ma solution utilisant Bibliothèque ImageViewZoom est basée sur ce ViewPager personnalisé:

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

J'ai corrigé la solution précédente. Vous pouvez faire défiler la page, lorsque ImageViewTouch est en mode zoom.

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