Advertisement
Guest User

Enlargable ImageView implementation

a guest
Jun 6th, 2011
620
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.69 KB | None | 0 0
  1. /*
  2.  * $URL: $
  3.  * $Revision: $
  4.  * $Date: $
  5.  * $Author: tprochazka $
  6.  *
  7.  * Author:  Tomáš Procházka <tomas.prochazka@atomsoft.cz>
  8.  * Licence: Commercial
  9.  */
  10.  
  11. package cz.atomsoft.android.test;
  12.  
  13. import android.content.Context;
  14. import android.util.AttributeSet;
  15.  
  16. /**
  17.  * Special version of ImageView which allow enlarge width of image if android:adjustViewBounds is true.
  18.  *
  19.  * <p>This simulate HTML behaviour &lt;img src="" widh="100" /&gt;</p>
  20.  * <p><a href="http://stackoverflow.com/questions/6202000/imageview-one-dimension-to-fit-free-space-and-second-evaluate-to-keep-aspect-rati">Stackoverflow question link</p>
  21.  *
  22.  * @author Tomáš Procházka &lt;<a href="mailto:tomas.prochazka@atomsoft.cz">tomas.prochazka@atomsoft.cz</a>&gt;
  23.  * @version $Revision: 0$ ($Date: 6.6.2011 18:16:52$)
  24.  */
  25. public class ImageView extends android.widget.ImageView {
  26.  
  27.     private int mDrawableWidth;
  28.     private int mDrawableHeight;
  29.     private boolean mAdjustViewBounds;
  30.     private int mMaxWidth;
  31.     private int mMaxHeight;
  32.  
  33.     public ImageView(Context context, AttributeSet attrs, int defStyle) {
  34.         super(context, attrs, defStyle);
  35.     }
  36.  
  37.     public ImageView(Context context, AttributeSet attrs) {
  38.         super(context, attrs);
  39.     }
  40.  
  41.     public ImageView(Context context) {
  42.         super(context);
  43.     }
  44.  
  45.     public void setAdjustViewBounds(boolean adjustViewBounds) {
  46.         super.setAdjustViewBounds(adjustViewBounds);
  47.         mAdjustViewBounds = adjustViewBounds;
  48.     }
  49.  
  50.     public void setMaxWidth(int maxWidth) {
  51.         super.setMaxWidth(maxWidth);
  52.         mMaxWidth = maxWidth;
  53.     }
  54.  
  55.     public void setMaxHeight(int maxHeight) {
  56.         super.setMaxHeight(maxHeight);
  57.         mMaxHeight = maxHeight;
  58.     }
  59.  
  60.     @Override
  61.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  62.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  63.  
  64.         mDrawableWidth = getDrawable().getIntrinsicWidth();
  65.         mDrawableHeight = getDrawable().getIntrinsicHeight();
  66.  
  67.         int w = 0;
  68.         int h = 0;
  69.  
  70.         // Desired aspect ratio of the view's contents (not including padding)
  71.         float desiredAspect = 0.0f;
  72.  
  73.         // We are allowed to change the view's width
  74.         boolean resizeWidth = false;
  75.  
  76.         // We are allowed to change the view's height
  77.         boolean resizeHeight = false;
  78.  
  79.         if (mDrawableWidth > 0) {
  80.             w = mDrawableWidth;
  81.             h = mDrawableHeight;
  82.             if (w <= 0) w = 1;
  83.             if (h <= 0) h = 1;
  84.  
  85.             // We are supposed to adjust view bounds to match the aspect
  86.             // ratio of our drawable. See if that is possible.
  87.             if (mAdjustViewBounds) {
  88.  
  89.                 int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
  90.                 int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
  91.  
  92.                 resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
  93.                 resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
  94.  
  95.                 desiredAspect = (float) w / (float) h;
  96.             }
  97.         }
  98.  
  99.         int pleft = getPaddingLeft();
  100.         int pright = getPaddingRight();
  101.         int ptop = getPaddingTop();
  102.         int pbottom = getPaddingBottom();
  103.  
  104.         int widthSize;
  105.         int heightSize;
  106.  
  107.         if (resizeWidth || resizeHeight) {
  108.             /* If we get here, it means we want to resize to match the
  109.                 drawables aspect ratio, and we have the freedom to change at
  110.                 least one dimension.
  111.             */
  112.  
  113.             // Get the max possible width given our constraints
  114.             widthSize = resolveAdjustedSize(w + pleft + pright,
  115.                                                                                                 mMaxWidth, widthMeasureSpec);
  116.  
  117.             // Get the max possible height given our constraints
  118.             heightSize = resolveAdjustedSize(h + ptop + pbottom,
  119.                                                                                             mMaxHeight, heightMeasureSpec);
  120.  
  121.             if (desiredAspect != 0.0f) {
  122.                 // See what our actual aspect ratio is
  123.                 float actualAspect = (float) (widthSize - pleft - pright) /
  124.                                                                             (heightSize - ptop - pbottom);
  125.  
  126.                 if (Math.abs(actualAspect - desiredAspect) > 0.0000001) {
  127.  
  128.                     boolean done = false;
  129.  
  130.                     // Try adjusting width to be proportional to height
  131.                     if (resizeWidth) {
  132.                         int newWidth = (int) (desiredAspect *
  133.                                                                                     (heightSize - ptop - pbottom))
  134.                                                                                     + pleft + pright;
  135.                         if (newWidth <= widthSize) {
  136.                             widthSize = newWidth;
  137.                             done = true;
  138.                         }
  139.                     }
  140.  
  141.                     // Try adjusting height to be proportional to width
  142.                     if (!done && resizeHeight) {
  143.                         int newHeight = (int) ((widthSize - pleft - pright)
  144.                                                                                     / desiredAspect) + ptop + pbottom;
  145.                         //if (newHeight <= heightSize) {
  146.                         heightSize = newHeight;
  147.                         //}
  148.                     }
  149.                 }
  150.             }
  151.         } else {
  152.             /* We are either don't want to preserve the drawables aspect ratio,
  153.                or we are not allowed to change view dimensions. Just measure in
  154.                the normal way.
  155.             */
  156.             w += pleft + pright;
  157.             h += ptop + pbottom;
  158.  
  159.             w = Math.max(w, getSuggestedMinimumWidth());
  160.             h = Math.max(h, getSuggestedMinimumHeight());
  161.  
  162.             widthSize = resolveSize(w, widthMeasureSpec);
  163.             heightSize = resolveSize(h, heightMeasureSpec);
  164.         }
  165.  
  166.         setMeasuredDimension(widthSize, heightSize);
  167.     }
  168.  
  169.     private int resolveAdjustedSize(int desiredSize, int maxSize,   int measureSpec) {
  170.         int result = desiredSize;
  171.         int specMode = MeasureSpec.getMode(measureSpec);
  172.         int specSize = MeasureSpec.getSize(measureSpec);
  173.         switch (specMode) {
  174.         case MeasureSpec.UNSPECIFIED:
  175.             /* Parent says we can be as big as we want. Just don't be larger
  176.             than max size imposed on ourselves.
  177.             */
  178.             result = Math.min(desiredSize, maxSize);
  179.             break;
  180.         case MeasureSpec.AT_MOST:
  181.             // Parent says we can be as big as we want, up to specSize.
  182.             // Don't be larger than specSize, and don't be larger than
  183.             // the max size imposed on ourselves.
  184.             result = Math.min(Math.min(desiredSize, specSize), maxSize);
  185.             break;
  186.         case MeasureSpec.EXACTLY:
  187.             // No choice. Do what we are told.
  188.             result = specSize;
  189.             break;
  190.         }
  191.         return result;
  192.     }
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement