Here is a simple layout:
If you do android:scaleType="FIT_END"
, without the FrameLayout
, does that put the Subway image near the "Subway" text? I wonder, because you have android:layout_alignParentLeft="true"
in there. I'm thinking that the ImageView
's original size before the scaling is what is throwing off the layout without a FrameLayout
.
It probably doesn't matter too much, but it does take some processing to scale and resize the image for what you want it to do. If it is viable for what you want to do, I'd simply resize the image myself instead of relying on XML. If I wanted to cater to multiple sizes, I would have a couple of different layouts made. This of course may be overkill for your purpose, I do not know.
Extra space came in first image because u set match parent in image container layout. but second u used wrap content in FrameLayout which is image container.
my suggession to do these thing Create linear layout insider relative layout and apply layout_weight propert so ratio will be same in both view.
try to replace android:scaleType="fitStart"
with this android:scaleType="fitXY"
Edit
in your image view you should set the width of imagView to wrap-content
this will take the size of image. If you hard-code the imageView's
width (as you have done it by giving the width to 40dp) then this will not look so good in other android mobile devices.
Still if you want to do so then Try to load image of lesser in resolution. if this image is 200X100
in resolution, then try to load the image of 100X50
in your ImageView
This applies to almost all the view but answer is written considering specifically ImageView
Guideline to set Height and Width
Choose one of this three options only.
WRAP_CONTENT
" FILL_PARENT
" FIXED SIZE
"
Width=WRAP_CONTENT and Height=FILL_PARENT
Guideline to set SCALETYPE for ImageView
What does ScaleType do?
It scale the image you set to the ImageView, It doesn't scale ImageView so when you set it to fitStart it will scale your image and show on the right but your imageView will remain same in terms of height and width as what you have specified.
As if you are using WRAP_CONTENT
for height and width you don't need to specify ScaleType cause your ImageView is automatically going to be as big as your image.
As if you are using FILL_PARENT
for height and width you will have option to show the image in Center,Start,End or in Full view.. so based on that you can choose your ScaleType.
As if you are using FIXED_SIZE
fpr height and width you should opt for scaletype=FITXY
.
Guideline to set Image into ImageView
As if you are setting image statically in XML then you have one image on your hand so you can create image of the size you wish as per your layout design and just move on with WRAP_CONTENT.
As if you are setting image at runtime after downloading it from somewhere, that time download the image and create bitmap of the size you prefer and then set it to ImageView
Specific to your case
You can see that your image is quite stretched and the text is not readable that's because you have downloaded and set image as it is but in smaller height and width.. rather you should have done like,
Set ImageView height and width to WRAP_CONTENT
in XML file
<ImageView
android:id="@+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true" />
Download image in your required size say 50X100, for example see this code
class LoadPics extends AsyncTask<Void, Bitmap, Bitmap> {
String urlStr;
ImageView iv;
int width, height;
public LoadPics(ImageView iv, String url, int width, int height) {
this.iv = iv;
this.urlStr = url;
this.width = width;
this.height = height;
}
@Override
protected Bitmap doInBackground(Void... params) {
try {
InputStream in = null;
try {
URL url = new URL(urlStr);
URLConnection urlConn = url.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) urlConn;
httpConn.connect();
in = httpConn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
int scale = 2;
if (o.outHeight > width || o.outWidth > height) {
scale = 2 ^ (int) Math.ceil(Math.log(width
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5));
}
if (scale <= 1 && o.outHeight > 150) {
scale = 5;
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap b1 = BitmapFactory.decodeStream(in, null, o2);
b1 = Bitmap.createScaledBitmap(b1, width, height, true);
loader.addToCache(urlStr, b1);
publishProgress(b1);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Bitmap... values) {
super.onProgressUpdate(values);
iv.setImageBitmap(values[0]);
}
}
And call this method with your arguments,
new LoadPics(ivUser,imgURL,100,50).execute();
The height of an image I will set by setImageBitmap() is more that 40dp. Using this layout I have an extra space between ImageView and TextView, where did it come from?
Since the android:layout_height="40dp"
with a android:scaleType="fitStart"
, the image is getting scaled down (and to the left/start) to fit the height, so this "extra space" is actually the original width of the image, since your android:layout_width="wrap_content"
. I recreated your layout with my own image that is larger than 40dp
. When you select the ImageView
, you can see that its bounds stretch to the image's original width.
To further prove this, if I set android:scaleType="center"
, no fit is applied and you can see the ImageView
's original width.
Can you guys explain why shall I put ImageView into FrameLayout to have things as intended?
It appears that since your FrameLayout
uses android:layout_width="wrap_content"
, it gets the correct scaled down width from your ImageView
after it gets scaled due to android:adjustViewBounds="true"
. It is strange that the ImageView
itself uses android:layout_width="wrap_content"
, but shows the original image's width, and not the scaled width. My hunch is that the height and width of ImageView
s get set before the scaling is applied, so the ImageView
gets the original image's width, but the parent FrameLayout
gets the scaled width of it's ImageView
child after the scaling is applied. This may not be true, but it appears that way to me.
However, you can solve the unscaled width issue (without using a FrameLayout
) by using android:maxHeight="40dp"
on the ImageView
. You can then set android:layout_height="wrap_content"
so your images can be smaller than 40dp
if the image is smaller.
<ImageView
android:id="@+id/companyIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:adjustViewBounds="true"
android:maxHeight="40dp"
android:scaleType="fitStart" />
try to set the scale type to center_inside.