I have an activity where a user can choose a photo through an intent. The expected behavior is as follows:
The image is sized to fill the parent width (minus margins).
This sizing should never increase the image, just scale down when needed.
Aspect ratio should ALWAYS be accurate.
Height should be scaled exactly as width is to maintain correct aspect ratio.
In portrait mode the maximum height is however big it can get before scrolling appears (just fill the screen).
This means that the width may not fully stretch to parent width if limited by the height.
In landscape mode the maximum height is irrelevant because scrolling is allowed, width should always be parent width.
Here's the portrait XML layout I am using:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/gray_background"
android:weightSum="1" >
<!-- Other controls here -->
<ImageView android:id="#+id/imgView"
android:layout_gravity="center"
android:layout_margin="5dip"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:contentDescription="#string/ImageToSend"
android:adjustViewBounds="true"
android:layout_weight="1"
android:scaleType="fitCenter" />
<!-- Other controls here -->
</LinearLayout>
Here's the Landscape XML layout I am using:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<!-- Other controls are here -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/gray_background" >
<ImageView android:id="#+id/imgView"
android:layout_gravity="center"
android:layout_margin="5dip"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:contentDescription="#string/ImageToSend"
android:adjustViewBounds="true"
android:layout_weight="1"
android:scaleType="fitCenter" />
<!-- Other controls are here -->
</LinearLayout>
</ScrollView>
This works perfectly fine no matter what view I am in. The problem I am having is that when the user rotates the device, the ImageView no longer has the correct size. If I start by selecting the image in landscape mode, rotations look fine. If I start by selecting an image in portrait mode, then switch to landscape mode, the image now displays as 1px by 1px.
Any ideas anyone?
After a while of failed expiraments, I found that calling setContentView() and redoing the layout fixed the issue. Not sure if this is what I was supposed to do, but it has fixed it.
Related
I have two ImageViews with the same image source inside LinearLayout, but why the second image is smaller than the first?
This is the source code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/background_landscape" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/background_landscape" />
</LinearLayout>
</RelativeLayout>
The error can be reproduced clearly on 800x1280 pixel resolution.
How can make both images have the same size with the second image cropped on the right side of the screen. (NOT SCALED DOWN)
... why the second image is smaller than the first?
Because the first image gets its real width due to wrap_content value of layout_width attribute. And the second image receives the rest width (width of layout minus width of first image) from LinearLayout, which is obviously smaller, than the real width of the image. That's why it gets scaled down.
How can make both images have the same size with the second image
cropped on the right side of the screen. (NOT SCALED DOWN)
You might use ScrollView, which allows children to go out of parent's boundaries.
Update: as mentioned by CommonsWare:
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="false"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/background_landscape" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/background_landscape" />
</LinearLayout>
</HorizontalScrollView>
Like beworker said the first image is getting its width due to the wrap_content and the second image gets the remaining available horizontal space.
Use android:layout_weight="1" in both ImageViews if you want them each to ocuppy half the available screen width
I use match_parent for height,but I don't want to use wrap_content or fill_parent for width. I want to set height as same as width. How can I do that in layout.xml?
Your question largely depends on whether you are in portrait or landscape.
If you are trying to make a layout width to match the height in portrait, then your layout will be going off screen, which does not seem possible in xml. And vice-versa, matching the height to the width in landscape would make the layout go offscreen as well.
If you are trying to make a square layout the same dimension as the smallest dimension of the screen, then a round about way to do that in xml is to make a shape drawable that is square, transparent and larger than your screen size. Then set the drawable to be an imageview inside a relativelayout and set your width and heights to the proper settings (match_parent or wrap_content). Then add views to the relativelayout as needed and reference them to the parent and not the image, making the new views reside "on top" of the imageview.
In portrait, the following relativelayout is square:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/square_draw" />
</RelativeLayout>
</LinearLayout>
In landscape, the following relativelayout is square:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:adjustViewBounds="true"
android:src="#drawable/square_draw" />
</RelativeLayout>
</LinearLayout>
Also, make sure that adjustViewBounds is set to true. For some reason, this solution does not allow the image to grow larger than the screen size and it also uses more resources due to the overdraw.
I've read all there is to read in terms of supporting different screen desnities. And, I have supplied proper variations of the images being display to appropriate folders. However, I am bewildered by something.
The documentation for ImageView says that setting android:layout_width and android:layout_height to "fill_parent"/"match_parent" will result in the image stretching to fill the screen. (This seems necessary since not all screen densities offer the same size/pixel count screens and I don't want those extra few pixels to result in padding on the bottom of the screen)
This seems to work any other time, but is not working for me when the ImageView is placed inside of a Horizontalscrollview and the width of the image is longer than that of the screen.
My code below:
(The activity is set to landscape in my manifest)
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/hscrollview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dp"
android:fadingEdge="none"
android:scrollbars="none"
android:overScrollMode="never" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0dp"
android:fadingEdge="none"
android:scrollbars="none"
android:overScrollMode="never" >
<ImageView
android:id="#+id/MapImageView"
android:src="#drawable/map"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
</RelativeLayout>
</HorizontalScrollView>
Edit: I replaced :src with :background to no effect.
This is the effect I get on devices like tablets. Ideally I want the image to fill the entire screen, like it does, below, on a phone with typical 480x800 resolution or the like.
Try using android:scaleType="fitXY" in your ImageView.
This is working for me:
<ImageView
android:id="#+id/main_imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="42dp"
android:alpha="0.5"
android:src="#drawable/img_alchemy2" />
It is a portrait image that fills the screen in portrait mode, and in landscape it fills it vertically without stretching it horizontally.
I have a LinearLayout (Horizontal) that I am using to display 3 ImageViews. When I first add the ImageViews the last one is shrunk because the images are too big to fit 3 across. Here is what my designer screen looks like:
Notice the third image is shrunk.
To fix this issue I set the following attributes on each ImageView.
width: 0dp
weight: 1
Here is how my images look after setting those attributes:
The problem I am running into is even though the images have been shrunk there is still space at the top and bottom as shown by the blue rectangle in the following image:
My question is, why is this extra padding there and how can I get rid of it?
Thank you
UPDATE - adding my layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:background="#color/app_background_color"
android:contentDescription="#string/game_image_button"
android:gravity="center"
tools:context=".EasyActivity" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/ImageView02"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:contentDescription="#string/game_image_button"
android:src="#drawable/ruler200x200" />
<ImageView
android:id="#+id/ImageView01"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:contentDescription="#string/game_image_button"
android:src="#drawable/ruler200x200" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:contentDescription="#string/game_image_button"
android:src="#drawable/ruler200x200" />
</LinearLayout>
</RelativeLayout>
ImageViews support different ScaleTypes, the default is FIT_CENTER. here are the other options. FIT_CENTER means its going to start out with height and width equal to your image (what your images looked like in the first screen shot before you added weight). What I believe happened is that it then resized the width of the image based on your layout_weight, and maintained the image's aspect ratio by shrinking it to fit the new width. It left the height to be the original height and centered the result.
I think one of the other scale types would do what you want. Maybe CENTER or CENTER_INSIDE
You can use the following code
<Imageview.....
android:adjustViewBounds="true"
..../>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:scaleType="fitXY"
android:adjustViewBounds="true"
android:layout_x="0dip"
android:layout_y="0dip"
android:background="#drawable/mlview1" />
I'm using android emulator 2.2 . My image occupies the screen horizontally but vertically shows a large gap from the Bottom. The image size is 800X600 . should it be re-sized and then used?
Make sure that:
1. Both height and width on both parent and child is fill_parent
2. You are setting the src property and not the background one on the image
Note: You also don't need the layout_x nor layout_y