Android ImageView strecthes background - android

TL;DR: It looks fine when setting a drawable to ImageView (see attachment - top). Replacing it with a Bitmap (setImageBitmap) and setting again to the original (setImageBitmap(null) & setBackgroundResource(R...)) leads to the drawable being stretched (see atachment - bottom).
The ImageView element has a resource image when starting the app and it looks fine and not stretched. If the user puts his sign by using another activity, the ImageView is used to show a small thumbnail of his sign and the ImageView gets overwritten by using setImageBitmap().
The issue occurs, when user saves the draft and all fields get emptied. Emptying includes setImageBitmap(null)
and setBackGroundResource(R.drawable.ACTUAL_IMAGE_OF_IMG_VIEW).
After resetting the ImageView (deleting Bitmap and setting actual background), the Background-Image gets stretched (see attached picture):
Changing the orientation of the device (landscape and portrait) the image is normal again.
Also there are grid lines on the background of the image, which absolutely doesn't stem from the ressource image.
Would love to hear the way You would solve this.
Edit - Code:
// Inserting Bitmap
private void insertSignature(){
ivSign.setImageBitmap(signature);
}
// setting signature -> null and adding icon again as background
private void ResetInputFields(){
ivSign.setImageBitmap(null);
ivSign.setBackgroundResource(R.drawable.sign_pen);
// TRIED ALREADY:
// ivSign.setBackground(getResources().getDrawable(R.drawable.sign_pen));
}

add to your imageView's XML code
android:scaleType="fitCenter"
or
android:scaleType="centerInside"
and it will keep its original ratio

Related

ImageView android:cropToPadding, what it actually does?

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".

ImageView showing grey square instead of image

I've tried several different ways but the imageview still show only a gray square. I'm testing on API 17.
Below are the options I've tried unsuccessfully:
Configured the ImageView in XML to:
fixed width and height; width and height to wrap_content; width to match_parent and height to wrap_content
android: scaleType to "fitXY" and "centerCrop"
android: adjustViewBounds to true | false;
Image loading methods tried:
binding.captcha.setImageBitmap (BitmapFactory.decodeFile (imgFile2.getAbsolutePath ()));
Also tried this answer https://stackoverflow.com/a/35830800/1764042
Tried Glide:
Glide.with(this)
.load (Uri.fromFile (imgFile2))
.skipMemoryCache (true)
.diskCacheStrategy (DiskCacheStrategy.NONE)
.override (150, 150)
.centerCrop ()
.into (binding.captcha);
The option below is the only that displays the image (in background), however I would like to know what could be happening to prevent me from displaying the image using default methods ...
Drawable drawableImage = new BitmapDrawable(BitmapFactory.decodeFile(imgFile2.getAbsolutePath()));
binding.captcha.setBackgroundDrawable(drawableImage);
Notes:
imgFile2 is not empty, it is loaded from SD Card.
imgFile2 is showing if I use it as background so the problem is not with the file.
The problem is not simply solved with a lib, I'm already trying Glide... But if you Know what I need to do to make it work with glide...
The imageView is inside a fragment, if it matters.
Current xml:
<ImageView
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:id="#+id/captcha"/>
For those who are still facing this issue, for me this is caused because of android:tint property of ImageView to which I was setting image into using Glide.
I was displaying a dummy placeholder image with android:tint as a shade of grey while the actual image loads from url. And that tint was causing the problem.
So try removing the android:tint property alltogether or set the tint to null programmatically after loading the image using imageView.setImageTintList(null)
Hope it helps

Change imageview backgrounds on drop

I have created a drag and drop application that allows the user to drag 4 images from the top and put them in order at the bottom. I have 4 image views on top and 4 imageviews on the bottom. Bringing them down works perfectly, however when I attempt to move them side to side I run into problems.
I have 2 temporary imageviews where I set them equal to a imageview. If i move an image from image view 6 to image view 5, it is supposed to swap the images, but it just changes image view 6 to what image view 5 was and image view 5 stays the same.
Here is the code snippet to where I am attempting to change the images
droppedSwap is equal to the image the user chose to move
dropTargetSwap is equal to where the user wants the image to go
if (dropTargetSwap.equals(ivHero5) && droppedSwap.equals(ivHero6))
{
//set temp imageview that is equal to ivHero5
ImageView tempDropTarget = ivHero5;
//set temp imageview that is equal to ivHero6
ImageView tempDropped = ivHero6;
//supposed to set ivHero6 to ivHero5 image
droppedSwap.setBackground(tempDropTarget.getBackground());// working
//supposed to set ivHero5 to ivHero6 image
dropTargetSwap.setBackground(tempDropped.getBackground());// not working
}
You're problem is that by doing:
ImageView tempDropTarget = ivHero5;
ImageView tempDropped = ivHero6;
You're not actually creating temporary copies but rather references to the original objects, so when you do droppedSwap.setBackground() you're actually setting the ivHero6 background and when you do tempDropped.getBackground() you're getting the ivHero6 background that was changed earlier.
You should create a copy of the backgrounds, which are drawables using:
Drawable copy1 = ivHero5.getBackground().getConstantState().newDrawable();
Drawable copy2 = ivHero6.getBackground().getConstantState().newDrawable();

How to change image size when pressing

I'm currently developing an android app and I would like to achieve an effect to which I haven't found an answer to, even after some searching.
The effect I would like to obtain is over an image. Usually when you press an image, you apply some sort of tint over the image in order to show some feedback, but I would like to go a little bit further, I wouldn't like to apply a tint but a sort os scale over the image.
E.g. I have the following image, Normal Image, and if I press the image (and while I keep it pressed), I would like the image to shrink a bit, like this Pressed Image
N.B.- The black part would not be part of the image, but part of the background. The image would only be the blue square.
Thank you for any help! :)
P.S.- I couldn't post the images here because I don't have enough reputation.
You need to set the onTouchListener of your ImageView that displays the image, so that it replaces the displayed image. This is the listener that runs when you press or unpress the view (in this case the image).
Sample Code:
ImageView iv = (ImageView)findViewById(R.id.my_image_view);
iv.setOnTouchListener(new ImageView.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent e) {
if (e.getAction()==MotionEvent.ACTION_DOWN)
// Write code here that sets the imageview to display the pressed image
else if (e.getAction()==MotionEvent.ACTION_UP)
// Write code here that sets the imageview to display the unpressed image
}
});
Reference to onTouchListener: http://developer.android.com/reference/android/view/View.OnTouchListener.html
Reference to ImageView (for replacing the displayed image):
http://developer.android.com/reference/android/widget/ImageView.html

Moving views inside a layout/view in Android

I have more than one question, but I'll start with the more important and problematic one:
I have a FrameLayout with a ImageView inside it. I need to get the size of the "usable area" of the screen my activity is ocupping, so I set the onSizeChanged on my View (I extended the ImageView class). Everything worked fine here. Now I have a 1000x1000 image that I want to show on the screen, but without scaling. I want it to be clipped, really. If I set the ImageView dimensions using viewObject.setLayoutParams(new Gallery.LayoutParams(1000, 1000)); I get the image being showed correctly, but then the onSizeChanged event returns me always the "1000 x 1000" custom size rather than the real screen size value.
Any ideas of how can I show an image with its real size (no scale!) and still get the view to report the screen available space? I can change the layout as needed as well, of course.
. Amplexos.
Are you asking to get the dimensions of the ImageView? If so then you can get that using getLocalVisibleRect. Here's roughly how it's done:
ImageView yourImageView;
public void onCreate(...){
setContentView(...)
yourImageView = (ImageView) findViewById(...);
(...)
}
getImageViewSize(){
Rect imageViewSize = new Rect();
yourImageView.getLocalVisibleRect(imageViewSize);
// imageViewSize now has all the values you need
Log.d("Your log tag", "ImageView width = " + (imageViewSize.right -
imageViewSize.left));
}
There is however a catch. You have to make sure that you don't try to get the size of the view until after view is finished being laid out on the screen. In other words, if you try to get its size in onCreate, its size will be 0. You have to get it afterwards, for example at the same time as you resize your image, assuming that's done with a button. (If you're using a SurfaceHolder you can also call it during the surfaceCreated callback, but I doubt you're using one of those...)

Categories

Resources