How can I get zoom functionality for images?

后端 未结 13 1420
粉色の甜心
粉色の甜心 2020-11-22 02:13

Is there a common way to show a big image and enable the user to zoom in and out and pan the image?

Until now I found two ways:

  1. overwriting ImageView,
13条回答
  •  南旧
    南旧 (楼主)
    2020-11-22 02:46

    In Response to Janusz original question, there are several ways to achieve this all of which vary in their difficulty level and have been stated below. Using a web view is good, but it is very limited in terms of look and feel and controllability. If you are drawing a bitmap from a canvas, the most versatile solutions that have been proposed seems to be MikeOrtiz's, Robert Foss's and/or what Jacob Nordfalk suggested. There is a great example for incorporating the android-multitouch-controller by PaulBourke, and is great for having the multi-touch support and alltypes of custom views.

    Personally, if you are simply drawing a canvas to a bitmap and then displaying it inside and ImageView and want to be able to zoom into and move around using multi touch, I find MikeOrtiz's solution as the easiest. However, for my purposes the code from the Git that he has provided seems to only work when his TouchImageView custom ImageView class is the only child or provide the layout params as:

    android:layout_height="match_parent"
    android:layout_height="match_parent"
    

    Unfortunately due to my layout design, I needed "wrap_content" for "layout_height". When I changed it to this the image was cropped at the bottom and I couldn't scroll or zoom to the cropped region. So I took a look at the Source for ImageView just to see how Android implemented "onMeasure" and changed MikeOrtiz's to suit.

       @Override
    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
      //**** ADDED THIS ********/////
          int  w = (int) bmWidth;
          int  h = (int) bmHeight;
         width = resolveSize(w, widthMeasureSpec);  
         height = resolveSize(h, heightMeasureSpec);
      //**** END ********///   
    
       // width = MeasureSpec.getSize(widthMeasureSpec);   // REMOVED
       // height = MeasureSpec.getSize(heightMeasureSpec); // REMOVED
    
        //Fit to screen.
        float scale;
        float scaleX =  (float)width / (float)bmWidth;
        float scaleY = (float)height / (float)bmHeight;
    
        scale = Math.min(scaleX, scaleY);
        matrix.setScale(scale, scale);
        setImageMatrix(matrix);
        saveScale = 1f;
    
        // Center the image
        redundantYSpace = (float)height - (scale * (float)bmHeight) ;
        redundantXSpace = (float)width - (scale * (float)bmWidth);
        redundantYSpace /= (float)2;
        redundantXSpace /= (float)2;
    
        matrix.postTranslate(redundantXSpace, redundantYSpace);
    
        origWidth = width - 2 * redundantXSpace;
        origHeight = height - 2 * redundantYSpace;
       // origHeight = bmHeight;
        right = width * saveScale - width - (2 * redundantXSpace * saveScale);
        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
    
        setImageMatrix(matrix);
    }
    

    Here resolveSize(int,int) is a "Utility to reconcile a desired size with constraints imposed by a MeasureSpec, where :

    Parameters:

     - size How big the view wants to be
     - MeasureSpec Constraints imposed by the parent
    

    Returns:

     - The size this view should be."
    

    So essentially providing a behaviour a little more similar to the original ImageView class when the image is loaded. Some more changes could be made to support a greater variety of screens which modify the aspect ratio. But for now I Hope this helps. Thanks to MikeOrtiz for his original code, great work.

提交回复
热议问题