ImageViewは、matrixによるジェスチャーズーム、拡大、縮小、移動を実現します。

20812 ワード

転載元:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/1023/1579.html
テスト有効
ImageViewのジェスチャーのスケーリングについては、多くの方法がありますが、ほとんどのオープンソースのカスタムスケーリングは、Odraw関数を修正して実現されます。しかし、ImageView自体にはscaleType属性があり、android:scaleType=「matrix」を設定することで、少ないコードでズーム機能が可能です。スケーリングの利点は,実現が簡単であると同時に,オンドラー関数を繰り返し呼び出していないため,スケーリング中にフリッカが発生しないということである。
package xxx
 import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView;
public class ImageTouchView extends ImageView {

    private PointF startPoint = new PointF();
    private Matrix matrix = new Matrix();
    private Matrix currentMaritx = new Matrix();

    private int mode = 0;//        private static final int DRAG = 1;//    private static final int ZOOM = 2;//    private float startDis = 0;
    private PointF midPoint;//      /**  *         * @param context  */  public ImageTouchView(Context context){
        super(context);
    }
    /**  *           XML         * @param context  * @param paramAttributeSet  */  public ImageTouchView(Context context,AttributeSet paramAttributeSet){
        super(context,paramAttributeSet);
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mode = DRAG;
                currentMaritx.set(this.getImageMatrix());//  ImageView         startPoint.set(event.getX(),event.getY());//     break;
            case MotionEvent.ACTION_MOVE://       if (mode == DRAG) {//        float dx = event.getX() - startPoint.x;//x       float dy = event.getY() - startPoint.y;
                    matrix.set(currentMaritx);//             matrix.postTranslate(dx, dy);

                } else if(mode == ZOOM){//        float endDis = distance(event);//      if(endDis > 10f){
                        float scale = endDis / startDis;//      //Log.v("scale=", String.valueOf(scale));  matrix.set(currentMaritx);
                        matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                    }


                }
                break;

            case MotionEvent.ACTION_UP:
                mode = 0;
                break;
            //       ,       (  )  case MotionEvent.ACTION_POINTER_UP:
                mode = 0;
                break;
            //         (  ),            case MotionEvent.ACTION_POINTER_DOWN:
                mode = ZOOM;
                startDis = distance(event);

                if(startDis > 10f){//           midPoint = mid(event);
                    currentMaritx.set(this.getImageMatrix());//           }

                break;
        }
        this.setImageMatrix(matrix);
        return true;
    }

    /**  *          * @param event  * @return  */  private static float distance(MotionEvent event){
        //        float dx = event.getX(1) - event.getX(0);
        float dy = event.getY(1) - event.getY(0);
        return FloatMath.sqrt(dx*dx + dy*dy);
    }
    /**  *               * @param event  * @return  */  private static PointF mid(MotionEvent event){
        float midx = event.getX(1) + event.getX(0);
        float midy = event.getY(1) - event.getY(0);

        return new PointF(midx/2, midy/2);
    }
}
このようにxmlにはカスタムImageViewが使われています。
1
2
3
4
5
6<com.jcodecraeer.stargallerry.ImageTouchView    android:id="@+id/image"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:scaleType="matrix"    />ここに細かいところがあります。android:layout_widthとandroid:layout_heightここは全部「matchuplarent」です。もし私達がwrap_に変えたら。contentの場合、画像は小さな区間でしか拡大できないことが分かります。match_parentは画面全体を自由に拡大できます。
でもtch_parentは意外な問題を引き起こしました。
イメージビューの幅と高さを親コントロール全体に充填するように設定し、その後scaleTypeをMatrixに設定すると、画像は中央に表示されていません。全体の画像は上になりました。ここでは原因はまだ分かりませんが、ネット上で解決方法を見つけました。

まずImageViewのScaleType=「CENTER」を設定します。  コントロールにドラッグ&縮小を追加する前に、ScaleTypeを「Matric」に設定します。  (imageView OnTouch Listenerを設定する前に属性を変更すればいいです。)

このうち、「ImageView設定OnTouch Listener前に属性を変更する」という例は、caseMotionEvent.ACTION_に置き換えられます。MOVE://移動イベントからプロパティの変更が始まります。コードの中でScaleTypeを変更するには、このようにすべきです。
this.set ScaleType(ImageView.ScaleType.MATRIX)
ScaleTypeと言えば、ImageView.ScaleTypeの値の意味と違いを見ます。CENTER/センター 画像の元のサイズの中央に表示されています。画像の長さ/幅がビューの長さ/幅を超えると、画像の中央部分を切り取ってCENTER_を表示します。CROP/センターCrop 画像をスケールで拡大したサイゼルの中央に表示すると、画像長(幅)がViewの長さ(幅)以上のCENTER(u)に等しくなります。INSIDE/センターインサイド 画像の内容を完全に中央に表示し、比率によって縮小または元のsizeによって、画像の長さ/幅がViewの長さ/幅FIT_よりも小さくなります。センター 画像をスケールで拡大/縮小して、居中にFIT_を表示します。END/fitEnd  画像をスケールで拡大/縮小してビューの幅に表示します。START/fit Start 画像をスケールで拡大/縮小してビューの幅に表示します。XY/fitXY 画像を比例しないで拡大/縮小してViewの大きさまでMATRIX/matrixを表示してマトリックスで描きます。