0

I have a layout in an android app that is misbehaving. Right now, it looks like this:

enter image description here

The idea is to have 3 images with their reflections as separate images lined up below them. If I just have the images (only the first nested LinearLayout, shown below) then the images show up just fine, in their native resolution and evenly spaced apart. But with the second linearlayout added in (the reflections), the images are shown much smaller than they should be.

Those reflection images in the pic are showing up the right size, and the images should be just as wide as the reflections, natively. If they were showing up properly, then the top of the images to the bottom of the reflections should fill the height of the screen. But they're not. I've tried lots of combinations of layout_width and layout_height on the imageviews and the linearlayouts (also different scaleTypes), but nothing is preventing the images from shrinking for some reason. Can anyone suggest why?

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- IMAGES -->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="3">

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <!-- IMAGE REFLECTIONS -->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="3">

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

</LinearLayout>

Also, I'm not dead set on using LinearLayouts, so alternatives ideas are welcome.

UPDATE:
This is how it looks with a background color added to each ImageView:

enter image description here

...and this is how it should actually look. This is accomplished by setting the layout_width and layout_height of each poster ImageView to 333px and 500px, respectively. But I don't want to do this. It causes horizontal alignment problems between the posters and reflections when there's less than 3 images to show on the screen:

enter image description here

RTF
  • 6,214
  • 12
  • 64
  • 132

6 Answers6

1

If your ImageView displays a placeholder image (such as in an android:src property) before the movie poster images load, a possible reason for the shrinkage is that your placeholder image does not have the same aspect ratio as your movie poster images.

There seems to be a bug in ImageView where sometimes images are resized to the same aspect ratio as the placeholder image.

Try resizing your placeholder image to the same aspect ratio as your movie poster images.

Zhiyong
  • 391
  • 1
  • 3
  • 19
0

Try doing this, I just added weight to the parent linearlayouts also...

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <!-- IMAGES -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

    <!-- IMAGE REFLECTIONS -->

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="3" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />
    </LinearLayout>

</LinearLayout>
Hardik4560
  • 3,202
  • 1
  • 20
  • 31
  • No luck unfortunately. It just pushes the reflections further apart from the images, but leaves the images the same size and in the same position. Also, I get the "nested weights are bad for performance" warning. – RTF Jan 10 '14 at 04:35
  • How are creating your reflection ? Try setting hardcode images in xml and check if that work. If yes I doubt about the creation of reflection code. – Hardik4560 Jan 10 '14 at 04:47
  • The poster images are stored in internal memory. The reflections are generated dynamically in code by doing a transformation on the poster images. The source for each poster imageview is set using setImageDrawable() and the source for each reflection imageview is set using setImageBitmap(). I can actually get it to look the way I want if I set the width and height of the poster images to hardcoded pixel values (333 x 500), which is their native resolution, but it causes another problem. If I only have 1 or 2 images to show, the reflections don't line up horizontally with the posters. – RTF Jan 10 '14 at 04:58
0
  • change the layout_width of all ImageViews to 0px, such that:

    reason is, android won't be looking into layout_weight if layout_width is something other than 0 (This depends on the android version)

  • Besides that, make sure your images are big enough (pixel wise), if you can't guarantee that, you might have to extend ImageView according to your needs:

    1. You have a fixed aspect ratio (easiest to write)

      @Override
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(
                  (int) (MeasureSpec.getSize(widthMeasureSpec) * ASPECT_RATIO),
                  MeasureSpec.EXACTLY));
      }
      
    2. You want the image to adjust it's height accoring to your source-image's aspectratio (start looking here)

  • set a scaleType according to your decision above (link)

Community
  • 1
  • 1
Suau
  • 4,628
  • 22
  • 28
  • No luck. I tried setting all images (posters and reflections) to 0px width, as well as just the posters and just the reflections, but none of those changes changed anything. – RTF Jan 10 '14 at 04:52
  • check my updated answer, you probably should choose centerCrop or fitXY as your scaletype – Suau Jan 10 '14 at 05:02
  • I've already tried every different type of scaleType on the ImageViews. None of them worked. The images themselves are big enough. The posters images are actually the same width as the reflection images. If you were to scale the poster out to be that width, keeping the aspect ratio intact, that's the size that the poster images *should* be – RTF Jan 10 '14 at 05:06
  • set a red background color on each of the normal images and a blue background color on each reflection images. And add the new screenshot – Suau Jan 10 '14 at 06:10
  • The BG colors cover exactly what you would expect them to. Both colors cover the entire width of the screen and the height of the images, respectively. The area below the reflection images has no color. I'm updating the post. – RTF Jan 10 '14 at 13:48
0

Try this just set the width of your ImageView to 0dp this will work. and also go through this link LinearLayout to build a row of elements. its very useful for further use.

<!-- IMAGES -->
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:weightSum="3">

    <ImageView 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <ImageView 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"" />

    <ImageView 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

<!-- IMAGE REFLECTIONS -->
<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:weightSum="3">

    <ImageView 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <ImageView 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"" />

    <ImageView 
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

  • Setting the widths to 0dp didn't work. I also tried playing with baselineAligned on the root LinearLayout and the nested LinearLayouts, with and without 0dp on the ImageViews. No dice. – RTF Jan 10 '14 at 05:16
  • Rewmove `android:weightSum="3"` attribute from your layout –  Jan 10 '14 at 05:19
  • Removing just the weightSums on the LinearLayouts has no effect, presumably because the layout_weights on each individual imageview are still active and doing the exact same thing. Removing the layout_weights too does what you would expect it too. Everything is the same except that the imageviews in the linearlayouts are no longer equally spaced apart, they're bunched up together. – RTF Jan 10 '14 at 05:26
  • `weightSum` Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children. So in your case The behavior in your example would be identical with `weightSum` omitted. [documentation](http://developer.android.com/reference/android/widget/LinearLayout.html#attr_android:weightSum) –  Jan 10 '14 at 05:31
0

I post this as a second answer, because i assume the error on a different part: Your screen height might not be high enough accommodate the normal images + reflections, therefore the first row is squashed and images scaled down to match the aspect ratio. Try to wrap it in a ScrollView, this should fix the issue, but might not be the result you want. Here is the code:

Note that i changed the layout_height of your wrapping LinearLayout to wrap_content

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

    <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        <!-- IMAGES -->
        <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:weightSum="3">

            <ImageView
                    android:layout_width="0px"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>

            <ImageView
                    android:layout_width="0px"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>

            <ImageView
                    android:layout_width="0px"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>

        </LinearLayout>

        <!-- IMAGE REFLECTIONS -->
        <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:weightSum="3">

            <ImageView
                    android:layout_width="0px"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>

            <ImageView
                    android:layout_width="0px"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>

            <ImageView
                    android:layout_width="0px"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"/>

        </LinearLayout>

    </LinearLayout>
</ScrollView>
Suau
  • 4,628
  • 22
  • 28
0

I couldn't find a way to make this work, so I ended up just explicitly setting the width and height of the posters to their pixel values. I actually also ended up going with a different, simpler layout entirely, one with a RelativeLayout as the root containing the six ImageViews (3 posters and their reflections). The poster shrinking effect still occurred though.

If anyone knows how to get around this problem, please let me know.

RTF
  • 6,214
  • 12
  • 64
  • 132