0

我编写了一个可以拖动图像的 android 应用程序。默认模式下图像的顶部和左侧是 0, 0。我的问题是如何在拖动后获得可见图像的顶部和左侧。

触摸类:

public class Touch implements OnTouchListener {

    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;

    private static final float MIN_ZOOM = 1f;
    private static final float MAX_ZOOM = 5f;

    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();

    private PointF start = new PointF();
    private PointF mid = new PointF();

    private float[] values = new float[9];

    private int mode = NONE;
    private float dx;
    private float dy;
    private float matrixX = 0;
    private float matrixY = 0;
    private float width = 0;
    private float height = 0;
    private float oldDistance = 1f;

    public boolean onTouch(View view, MotionEvent event) {
         ImageView imageView = (ImageView)view;

         switch(event.getAction() & MotionEvent.ACTION_MASK) {

             case MotionEvent.ACTION_DOWN:
                 savedMatrix.set(matrix);
                 start.set(event.getX(), event.getY());
                 mode = DRAG;
                 break;

             case MotionEvent.ACTION_POINTER_DOWN:
                 oldDistance = spacing(event);
                 if(oldDistance > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                 }
                 break;

             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_POINTER_UP:
                 mode = NONE;
                 break;

             case MotionEvent.ACTION_MOVE:
                if(mode == DRAG) {
                    matrix.set(savedMatrix);
                    matrix.getValues(values);
                    matrixX = values[Matrix.MTRANS_X];
                    matrixY = values[Matrix.MTRANS_Y];
                    width = values[Matrix.MSCALE_X] * imageView.getDrawable().getIntrinsicWidth();
                    height = values[Matrix.MSCALE_Y] * imageView.getDrawable().getIntrinsicHeight();
                    dx = event.getX() - start.x;
                    dy = event.getY() - start.y;
                    if(matrixY + dy > 0)
                        while(matrixY + dy > 0)
                            dy--;
                    if(matrixX + dx + width < imageView.getWidth())
                        while(matrixX + dx + width < imageView.getWidth())
                            dx++;
                    if(matrixY + dy + height < imageView.getHeight())
                         while(matrixY + dy + height < imageView.getHeight())
                             dy++;
                    if(matrixX + dx > 0)
                         while(matrixX + dx > 0)
                             dx--;
                    matrix.postTranslate(dx, dy);
                 }
                 else if(mode == ZOOM) {
                    float newDistance = spacing(event);
                    if(newDistance > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDistance / oldDistance;
                        matrix.getValues(values);
                        float currentScale = values[Matrix.MSCALE_X];
                        if(scale * currentScale > MAX_ZOOM) 
                            scale = MAX_ZOOM / currentScale;
                        else if (scale * currentScale < MIN_ZOOM)
                            scale = MIN_ZOOM / currentScale;
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                 }
                 break;
        }
        imageView.setImageMatrix(matrix);
        return true;
    }

    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    private void midPoint(PointF point, MotionEvent event) {
        point.set((event.getX(0) + event.getX(1)) / 2, (event.getY(0) + event.getY(1)) / 2);
    }

}

活动类:

public class RepositionTestActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.reposition_test_layout);
        imageView = (ImageView)findViewById(R.id.android_image);
        imageView.setOnTouchListener(new Touch());
    }

}

布局xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/reposition_test_layout"
    android:paddingLeft="20dp"
    android:paddingTop="20dp"
    android:paddingRight="20dp"
    android:paddingBottom="20dp"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <ImageView
         android:id="@+id/android_image"
         android:src="@drawable/android"
         android:layout_width="300dp"
         android:layout_height="300dp"
         android:scaleType="matrix"
         android:contentDescription="@string/android_image_description" >
    </ImageView>

</LinearLayout>

谢谢你的帮助。

4

1 回答 1

0

我终于解决了这个问题。当用户重新定位图像时,我们可以将矩阵信息保存在文件或数据库中。

活动类:

public class RepositionTestActivity extends Activity {

    private ImageView imageView;
    private Button button;
    private SQLiteDatabase db;
    private Cursor cursor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.reposition_test_layout);
        imageView = (ImageView)findViewById(R.id.android_image);
        button = (Button)findViewById(R.id.reposition_button);
        ViewTreeObserver viewTreeObserver = imageView.getViewTreeObserver();
        if(viewTreeObserver.isAlive()) {
            viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    db = openOrCreateDatabase("DB_DATING", MODE_PRIVATE, null);
                    db.execSQL("" +
                        "CREATE TABLE IF NOT EXISTS tbl_images (" +
                        "   id INTEGER PRIMARY KEY AUTOINCREMENT," +
                        "   name VARCHAR(50) UNIQUE NOT NULL," +
                        "   scale_x FLOAT NOT NULL," +
                        "   scale_y FLOAT NOT NULL," +
                        "   trans_x FLOAT NOT NULL," +
                        "   trans_y FLOAT NOT NULL" +
                        ");");
                    cursor = db.query("tbl_images", new String[] {"name", "scale_x", "scale_y", "trans_x", "trans_y"}, "name = \"android\"", null, null, null, null);
                    imageView.setScaleType(ScaleType.MATRIX);
                    cursor.moveToNext();
                    if(cursor.getCount() > 0) {
                        Matrix matrix = new Matrix();
                        matrix.postScale(cursor.getFloat(1), cursor.getFloat(2));
                        matrix.postTranslate(cursor.getFloat(3), cursor.getFloat(4));
                        imageView.setImageMatrix(matrix);
                    }
                    imageView.setOnTouchListener(new Touch(imageView.getImageMatrix()));
                    button.setOnClickListener(new OnClickListener() {
                        public void onClick(View view) {
                            float[] values = new float[9];
                            imageView.getImageMatrix().getValues(values);
                            ContentValues contentValues = new ContentValues();
                            contentValues.put("scale_x", values[Matrix.MSCALE_X]);
                            contentValues.put("scale_y", values[Matrix.MSCALE_Y]);
                            contentValues.put("trans_x", values[Matrix.MTRANS_X]);
                            contentValues.put("trans_y", values[Matrix.MTRANS_Y]);
                            if(cursor.getCount() > 0) {
                                long count = db.update("tbl_images", contentValues, "name = \"android\"", null);
                                Log.d("Update Count", "===========> " + count);
                            }
                            else {
                                contentValues.put("name", "android");
                                long count = db.insert("tbl_images", null, contentValues);
                                Log.d("Insert Count", "===========> " + count);
                            }
                        }
                    });
                }
            });
        }
    }

}
于 2012-08-24T15:04:48.673 回答