I went through the documentation for the tag android:cropToPadding here, it only says:
If true, the image will be cropped to fit within its padding.
May be a boolean value, such as "true" or "false".
which is quite confusing for me to understand.
I have an ImageView inside my app, (which was developed by someone else):
<ImageView
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_gravity="center"
android:maxWidth="100dp"
android:padding="20dp" />
This ImageView had cropToPadding tag inside it, there were like 20 ImageView on main screen, which all had this tag inside them, and the app was obviously taking time to load as there were more Images, but then removing images was not an option, so I was finding stuff that was useless and trying to optimize the layout when I came across this tag.
Removing this tag did no change to the images that were shown inside the ImageView, but there must be some reason that every image contained this tag. So I started finding what this tag did, and documentation wasn't much clear as to why this tag should be used.
Can someone please explain what this tag does to the Image? I found out not many resources, all that I found was "This crops the Image to padding", what does that mean! I know what padding is, I know what cropping is, but what does "Sets whether this ImageView will crop to padding" mean?
This is a complex question to answer, because we have to drill into some nitty-gritty details of how ImageView actually draws the image to the screen.
The first thing to establish is that there are two rectangles that affect ImageView drawing behavior. The first is the rectangle defined by the ImageView's dimensions ignoring padding. The second is the rectangle defined by the ImageView's dimensions considering padding. (Obviously, if padding is 0, then these will be the same.)
The next thing to establish is that ImageViews all have a scale type that defines how the image is stretched and/or cropped when the image's intrinsic size doesn't match the size of the rectangle that it is being drawn into.
The default scale type is FIT_CENTER, which scales the image down to fit within the view bounds + padding (that is, the image will be drawn inside the rectangle that considers padding). Since the image is being drawn inside the padding rectangle, android:cropToPadding has no effect.
However, other scale types work differently. The scale type CENTER simply positions the image in the middle of the view, but performs no scaling (so the image will be clipped if it is bigger than the view). In this case, android:cropToPadding defines whether the image will be clipped by only the view's bounds or also clipped by the view's padding.
A picture is worth a thousand words:
This picture shows the same 72x72 image inside a 72x72 view with 16dp padding and CENTER scale type. The left ImageView has android:cropToPadding="false" and the right ImageView has android:cropToPadding="true".
Related
I am trying to scale an image inside an ImageView, but I want the image to get cropped if it goes outside the view boundaries. This is what it looks like. The image just gets rendered outside the View boundaries. I have tried all the different forms of android:scaleType and android:adjustViewBounds but none of them work to keep the image inside those boundaries. Basically what I want to have as an end result is an image that can zoom in and zoom out but when you zoom in, the image gets cropped to fit in the space. Maybe this is one of those things that is just not possible?
android:layout_width="wrap_content"
android:layout_height="wrap_content"
means that the view will adjust its size in acordance with the content. If you want the image to crop, specify those, e.g.
android:layout_width="40dp"
android:layout_height="40dp"
scaleX and scaleY is scalling the image. Removing both will solve your problem. Also give it a fixed height and width.
Edit these lines
android:layout_width="50dp"
android:layout_height="50dp"
And remove these lines
android:scaleX="2"
android:scaleY="2"
I have an image like this used as background in a RelativeLayout:
This image is used as background for all the levels of my game. Every level is drawn onto the blue area.
I want to keep fixed the aspect-ratio of the blue area, changing the size of the red edges to avoid to show to the user unused pixels of their screen. The green area must be fixed to 80dp for all phones. Then I must add a View (a GLSurfaceView) in my layout in such a way that it fit perfectly the blue area. Thus all levels of my Android game will be perfectly the same in all Android device.
How can I solve this problem?
The real image that I use is a little more complex. You can look it here:
Real image
I would use a FrameLayout for the middle part of the screen(blue), add an ImageView, containing the BackgroundImage you want to display, and put the GLSurfaceView on top of it.
Since the aspect ratio is always the same, you could set the ImageViews sclaing to fit xy and the image should always look the same.
Lets assume you are using a simple SurfaceView, the xml code id use to put a ImageView begind it would look like this
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
As i dont know how you build your View i cant post the code that does the job, but just add a FrameLayout instead of your GLSurfaceView to your View, with the Same Dimensions, the GLSurfaceView would have.
To that FrameLayout first add the ImageView, then the GLSurfaceView. Both with height and width set to match_parent.
To Figure out the size of your SurfaceView...
Retrieve Display Dimensions
Substract Green Bar Dimensions
Calculate the size of the Blue View, get the Height/Width (whatever is bigger) calculate the missing Dimension
Set the Red Views to Occupie the empty space.
So you would have to do this programmatically :)
Things looked quite simple first but in the end the result is not good.
I have an image which has a width larger than screen's width. So I need to scale it down in my imageview. I looked over the ScaleType options and tried them all but none is ok. First "center" only displays the image centered on the layout, no scaling done. "fitCenter" scales the image to fit in my layout but has a major drawback: the height of the item remains as it would have the large image in it. Take a look at the second screen in the attached image. How can I force the list item, to reduce its height to wrap both the text and the image ?
Use the scaletype which seems best to you ( I guess you like what you see with fitCenter). The additional thing that you must do is
android:adjustViewBounds="true"
in your ImageView.
or you could go with FitXY but sometimes the result is not exactly what you want.
use android:scaleType="fitXY"
Could you use FitXY?
This would work if you knew the size of the area you were putting the image into.
CentreInside may also work, I've used this to scale down images, but I think it depends if you've control of the size of the bounding layout element.
You either need to set android:height = "wrap_content" on your outer container, or set static height of TextBox and give ImageView android:weight = "1" so that the ImageView takes remaining space in container.
I am a puzzled about using src or background for an ImageView.
I know the former means the content of this ImageView and the latter means the background of the ImageView.
But how to decide which one to use? I don't see the difference.
All views can take a background image.
The src to an ImageView has additional features:
different scaling types
adjustViewBounds for setting bounds to match image dimensions
some transformations such as alpha-setting
And more that you may find in the docs.
when you use android:background, image will be set to fit on ImageView area(i.e according to width and height of ImageView). It doesn't matter if the image is smaller or larger than ImageView.
when you use android:src, then image will display in its original size. No
automatic scaling, adjustments will happen.
Note: Using android:src, we can get additional benefit of adjustViewBounds property
If you set an image to be the background of your ImageView, then the image will scale to whatever size the ImageView is. Other than that, src is a foreground image and background is a background image. Pretty much as it implies.
The difference between XML attribute src and background in ImageView:
The background will stretch according to the length given by the ImageView component, and SRC will hold the size of the original image without stretching. SRC is the picture content (foreground), BG is the background, can be used at the same time.
In addition: ScaleType only works on SRC; BG can set transparency, for example, in ImageButton, you can use Android:scaletype to control how the image is scaled, sample code as follows:
<ImageView
android:id="#+id/img"
android:layout_height="60dip"
android:layout_width= "60dip"
android:src="#drawable/logo"
android:scaleType="centerInside"
android:layout_centerVertical= "true"/>
Feel free to ask doubt if you get any.
The property android:layout_gravity="clip_vertical|horizontal" does the following as mentioned in the SDK documentation:
Additional option that can be set to
have the top and/or bottom edges of
the child clipped to its container's
bounds. The clip will be based on the
vertical gravity: a top gravity will
clip the bottom edge, a bottom gravity
will clip the top edge, and neither
will clip both edges.
But I can't see anything of this in my applications,
so what is the purpose of this property exactly ?
thanks
Short version:
clip_horizontal and clip_vertical apply to the measurements of the view itself, before any contents (such as the image in a BitmapDrawable) are rendered.
Long version:
I've run into some similar confusion over clip_horizontal and clip_vertical. (In my case, it was related to android:gravity for a BitmapDrawable, but it's similar enough to be applicable.)
From the documentation I thought that something like android:gravity="top|left|clip_vertical" on a bitmap would cause the image's top left corner to be positioned at the view's top left corner, and that, if the bitmap was taller than the view, it would be "clipped" at the bottom edge of the view. In other words, show only as much of the bitmap that the view is tall enough to reveal; do not stretch the bitmap, but instead only show whatever will fit, letting the rest extend below the bottom edge.
However, the opposite happened: when I set clip_vertical, a large bitmap was squished vertically to fit within the height of the view.
After examining the applyDisplay() method in platform/frameworks/core/java/android/view/Gravity.java, I realized my mistake:
It isn't the bitmap image that was going to be clipped, but the view -- the actual size of the container the image is ultimately rendered into.
Setting clip_vertical in my case didn't mean "clip the image at the bottom edge," it meant "clip the BitmapDrawable's view itself so its height matches the height of its parent container"...which then caused the image to be "squished" as it filled that shorter height.
So, the important thing to remember with android:gravity and android:layout_gravity is that clip_horizontal and clip_vertical apply to the measurements of the view itself, before any contents (such as my BitmapDrawable) are rendered.
Maybe there is no effect because horizontal is not defined in the android:layout_gravity. clip_vertical is just an additional property that is used in addition to a base property.
Flag to clip the edges of the object to its container along the horizontal axis.
check this