android - 在 ScrollView 上启用缩放

标签 android zooming scrollview

我在我的 ScrollView 中放置了某些数据。我想让它放大/缩小。它包含简单的 ImageViewTextView

任何建议都会有所帮助。 谢谢。

这是我的代码:

<ScrollView
    android:id="@+id/viewSoupMenu"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
     android:background="@drawable/soupback" >

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

<LinearLayout
          android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
          android:layout_marginTop="50dp">

    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         android:layout_marginLeft="35dp"
         android:layout_marginTop="30dp"
        android:background="@android:color/transparent"
        android:src="@drawable/flowericon" />

    <ImageButton
        android:id="@+id/btnVegClearSoup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         android:layout_marginLeft="5dp"
         android:layout_marginTop="20dp"
        android:background="@android:color/transparent"
        android:src="@drawable/btnvegsoupclearclickedxml" />

     </LinearLayout>
</ScrollView>

最佳答案

您可以使用下面提到的类在您的 ImageView 中启用捏合缩放,您可以创建此类的重复类,它扩展 TextView 而不是 ImageView 用于启用缩放。

public class PinchZoomImageView extends ImageView implements OnTouchListener{

    public PinchZoomImageView(Context context) {
        super(context);
        _init();
    }

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

    public PinchZoomImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        _init();
    }

    private void _init(){
        //setOnTouchListener(this);

        view = (ImageView) this;
        view.setOnTouchListener(this);

        metric = new DisplayMetrics();
        // Work around a Cupcake bug

        d_dpi=((0.52f/(metric.densityDpi))*240.0f)-0.52f;
        Log.d("ash","dpi= "+d_dpi);
        if(metric.densityDpi==160)
        d_dpi=0.34f;
        matrix.setTranslate(1f, 1f);
        matrix.setScale((0.52f/800.0f)*metric.widthPixels+d_dpi, (0.52f/480.0f)*metric.heightPixels+d_dpi);
        view.setImageMatrix(matrix);
        bMap =  BitmapFactory.decodeResource(getResources(), R.drawable.mfigure);
        btsize = BitmapFactory.decodeResource(getResources(), R.drawable.map);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(hasFocus){
            init();
        }
    }

    private void init() {
        maxZoom = (3.0f/480.0f)*metric.heightPixels+d_dpi;
        minZoom = (0.52f/800.0f)*metric.widthPixels+d_dpi;
        height = view.getDrawable().getIntrinsicHeight();
        width = view.getDrawable().getIntrinsicWidth();
        viewRect = new RectF(0, 0, view.getWidth(), view.getHeight());
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ImageView view = (ImageView) v;

        // Handle touch events here...
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                start.set(event.getX()/metric.widthPixels * 800, event.getY()/metric.heightPixels * 480);
                Log.d(TAG, "mode=DRAG");
                mode = DRAG;
                click = true;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                Log.d(TAG, "oldDist=" + oldDist);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                    Log.d(TAG, "mode=ZOOM");
                }
                click = false;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                Log.d(TAG, "mode=NONE");
                if(click)
                    onClick(event.getX(), event.getY(),true);
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {

                    temp_x = ((start.x) - ((event.getX()/metric.widthPixels)*800));
                    temp_y = ((start.y) - ((event.getY()/metric.heightPixels) * 480));               
                    if(FloatMath.sqrt(temp_x * temp_x + temp_y * temp_y)< 10)
                      break;

                    matrix.set(savedMatrix);

                    // limit pan
                    matrix.getValues(matrixValues);
                    float currentY = matrixValues[Matrix.MTRANS_Y];
                    float currentX = matrixValues[Matrix.MTRANS_X];
                    float currentScale = matrixValues[Matrix.MSCALE_X];
                    float currentHeight = height * currentScale;
                    float currentWidth = width * currentScale;
                    float dx = (event.getX()/metric.widthPixels * 800) - start.x;
                    float dy = (event.getY()/metric.heightPixels * 480) - start.y;
                    float newX = currentX+dx;
                    float newY = currentY+dy;

                    RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
                    float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
                    float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
                    float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
                    float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
                    if(diffUp > 0 ){
                        dy +=diffUp;
                    }
                    if(diffDown < 0){
                        dy +=diffDown;
                    }
                    if( diffLeft> 0){
                        dx += diffLeft;
                    }
                    if(diffRight < 0){
                        dx += diffRight;
                    }
                    matrix.postTranslate(dx, dy);
                    //selection.set(selection.x + dx, selection.y + dy);
                    click = false;
                }
                else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    Log.d(TAG, "newDist=" + newDist);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;

                        matrix.getValues(matrixValues);
                        float currentScale = matrixValues[Matrix.MSCALE_X];

                        // limit zoom
                        if (scale * currentScale > maxZoom) {
                            scale = maxZoom / currentScale;
                        } else if (scale * currentScale < minZoom) {
                            scale = minZoom / currentScale;
                        }
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                }
                break;
        }
        float mv[] = new float[9];
        matrix.getValues(mv);

        Log.d("PV", "Click x " + mv[Matrix.MTRANS_X] + " y " + mv[Matrix.MTRANS_Y] + " cx " + event.getX() + " cy " + event.getY());

        view.setImageMatrix(matrix);
        view.invalidate();
        return true; // indicate event was handled
    }

     public void onClick(float x, float y,boolean state){
        Log.d("TAG","x="+x+" y "+y);
        float mv[] = new float[9];
        matrix.getValues(mv);

        if(btsize != null)
            btsize.recycle();

        btsize = BitmapFactory.decodeResource(getResources(), R.drawable.map);

        if(btSel != null)
            btSel.recycle();

        btSel = BitmapFactory.decodeResource(getResources(), R.drawable.mfigure);

        Canvas canvas;
        try{
            canvas = new Canvas(btsize);
        }
        catch(Exception e){
            btsize = BitmapFactory.decodeResource(getResources(), R.drawable.map).copy(Config.ARGB_8888,true);
            canvas = new Canvas(btsize);
        }

        x -= mv[Matrix.MTRANS_X];
        y -= mv[Matrix.MTRANS_Y];

        float wdt = btsize.getWidth() * mv[Matrix.MSCALE_X];
        float ht = btsize.getHeight() * mv[Matrix.MSCALE_Y];

        float tw = x/wdt;
        float th = y/ht;

        selPoint.set(tw, th);
        if(state)
             canvas.drawBitmap(btSel, (tw * btsize.getWidth()) - (btSel.getWidth()/2), (th * btsize.getHeight()) - (btSel.getHeight()/2), null);
        else
            canvas.drawBitmap(btSel, (x * btsize.getWidth()) - (btSel.getWidth()/2), (y * btsize.getHeight()) - (btSel.getHeight()/2), null);

        setImageBitmap(btsize);

    }

    /** Determine the space between the first two fingers */
    private float spacing(MotionEvent event) {
         float x = ((event.getX(0)/metric.widthPixels)*800) - ((event.getX(1)/metric.widthPixels)*800);
           float y = ((event.getY(0)/metric.heightPixels) * 480) - ((event.getY(1)/metric.heightPixels) * 480);
        return FloatMath.sqrt(x * x + y * y);
    }

    /** Calculate the mid point of the first two fingers */
    private void midPoint(PointF point, MotionEvent event) {
         float x = ((event.getX(0)/metric.widthPixels) * 800) + ((event.getX(1)/metric.widthPixels)*800);
           float y = ((event.getY(0)/metric.heightPixels) * 480) + ((event.getY(1)/metric.heightPixels) * 480);
        point.set(x / 2, y / 2);
    }

    private static final String TAG = "Touch";
    // These matrices will be used to move and zoom image
    Matrix matrix = new Matrix();
    Matrix savedMatrix = new Matrix();

    // We can be in one of these 3 states
    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    int mode = NONE;

    // Remember some things for zooming
    PointF start = new PointF();
    PointF mid = new PointF();
    float oldDist = 1f;

    // Limit zoomable/pannable image
    private ImageView view;
    private float[] matrixValues = new float[9];
    private float maxZoom;
    private float minZoom;
    private float height;
    private float width;
    private RectF viewRect;
    private float temp_x,temp_y;
    private boolean click = false;
    public PointF selPoint = new PointF();
    Bitmap bMap;
    private float d_dpi;
    Paint paint = new Paint();
    Canvas canvas = new Canvas();
    private DisplayMetrics metric; 
    Bitmap bt = null;
    Bitmap btsize = null;
    Bitmap btSel = null;

} 

关于android - 在 ScrollView 上启用缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18572014/

相关文章:

android - Osmdroid 滚动和缩放限制

iphone - 如何使用 Xcode 4.5 将 UIImageView 嵌入到 iOS 中的 UIScrollView

ios - 在 UIViewController 的 subview 上初始化 xib

android - Libgdx:AssetManager 未加载 Assets

wordpress - 将 Woocommerce Zoom 添加到自定义库

iOS - 使用 openGL ES 仅缩放显示的一部分

java - 如何将 ScrollView 添加到抽屉导航

android - 如何用新 View 滑动 ListView 会像android中的删除按钮一样出现?

android - turtle 和 kivy

Android - 如何在通知中显示大文本