-1

I have a LinearLayout in my layout that has three ImageViews inside it. They have their layout_weight set to 1 so they should all take equal space. In XML it says this

<LinearLayout
    android:id="@+id/buttonContainer"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/option1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_weight="1"
        android:scaleType="fitCenter"
        android:src="@drawable/m571" />

    <ImageView
        android:id="@+id/option2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_weight="1"
        android:scaleType="fitCenter"
        android:src="@drawable/m562" />

    <ImageView
        android:id="@+id/option3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_weight="1"
        android:scaleType="fitCenter"
        android:src="@drawable/m531" />
</LinearLayout>

I programmatically change the images every 15 seconds. The program loads around 300 entries from SQLite database on the start. It stores the entries in an ArrayList and shuffles it. Then, every 15 seconds the program takes the first entry in the ArrayList and removes it so it can't be used twice. It uses the object from the ArrayList to change the images.

Here is the code.

// Get the first sign in the list and remove it
RoadSign sign = signs.get(0);
signs.remove(0);

// Get the possible options
List<String> options = Arrays.asList(sign.getOptions().split(","));
// Shuffle the list
Collections.shuffle(options, new Random(System.nanoTime()));

// Create a new ArrayList with two wrong choices and the correct one
ArrayList<String> choices = new ArrayList<String>();
choices.add(options.get(0));
choices.add(options.get(1));
choices.add(sign.getNumber());

// Shuffle the list
Collections.shuffle(choices, new Random(System.nanoTime()));

// Get image resources
int option1Image = getResources().getIdentifier("mypackage:drawable/m" + choices.get(0), null, null);
int option2Image = getResources().getIdentifier("mypackage:drawable/m" + choices.get(1), null, null);
int option3Image = getResources().getIdentifier("mypackage:drawable/m" + choices.get(2), null, null);

// Show the next images
option1.setImageResource(option1Image);
option2.setImageResource(option2Image);
option3.setImageResource(option3Image);

// Change the sign in 15 seconds
handler.postDelayed(runnable, 15000);

The problem is that the images aren't shown correctly every time. The images aren't the same in size but they should still take the same width in the layout. In some cases the images are fine and each of them take 33 % in width.

Here is a picture of the correct placement

enter image description here

Sometimes though this happens.

enter image description here

In some cases only two images are shown. Sometimes all the three are shown but there is one really small, one medium sized and one huge one.

What do I need to do to get the images show correctly?

MikkoP
  • 4,864
  • 16
  • 58
  • 106
  • weight problem you are using 2 wrap_content declaration + 1 weight, one should be 0, check : http://stackoverflow.com/questions/3995825/what-does-androidlayout-weight-mean – LonWolf Jan 06 '14 at 13:15

6 Answers6

3

For weight to work, the affected dimension (width, in this case) must be 0dp.
So, change this:

android:layout_width="wrap_content"

to this:

android:layout_width="0dp"

in your imageView definitions (all the three of them)

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • 1
    Worth mentioning why: LinearLayout distributes the amount of available free space between its children depending on their weight - since you're allowing the ImageViews to be as big as their content (wrap_content), there isn't any free space to allocate. If you set their width to 0, the remaining entire width will be split equally (since they all have the same weight of 1). – FunkTheMonk Jan 06 '14 at 13:24
  • +1 for the detailed explanation ;) – Phantômaxx Jan 06 '14 at 13:26
  • Thanks for answering. I still get the same effect: sometimes one of the images is very tiny and sometimes only two are shown. My layout looks like this now. http://pastebin.com/M66knfF3 – MikkoP Jan 06 '14 at 13:40
  • 1
    Works perfectly... great answer – DragonFire Dec 19 '19 at 08:49
  • @DragonFire Glad that you found it useful! – Phantômaxx Dec 19 '19 at 09:19
1

in the parent layout add android:weightsum="3"

and in imagview add android:layoutwidth="0dp"

Prameshwar
  • 32
  • 6
1

make the image view attribute

android:layout_weight="0.33"

and for complete linear layout

android:layout_weight="1"

This should solve your problem

Balu
  • 1,069
  • 2
  • 10
  • 24
1

When you are using weight

If it is used by vertical layout then its height must be 0dp.

If it is used by horizontal layout then its width must be 0dp.

So finally it means when you are using weight then its affected dimensions will be 0dp depends on layout orientation.

Piyush
  • 18,895
  • 5
  • 32
  • 63
0

Thanks for the rest for answering. It was true I needed to set layout_width to 0dp, but I also had to set the parent layout width to fill_parent. Now it is showing all the ImageViews every time.

MikkoP
  • 4,864
  • 16
  • 58
  • 106
0

To create a linear layout in which each child uses the same amount of space on the screen, set the android:layout_height of each view to "0dp" (for a vertical layout) or the android:layout_width of each view to "0dp" (for a horizontal layout). Then set the android:layout_weight of each view to "1". Refer : http://developer.android.com/guide/topics/ui/layout/linear.html

dreamdeveloper
  • 1,266
  • 1
  • 15
  • 20