Home » Android » Android ImageView sized by weight not centering in parent LinearLayout

Android ImageView sized by weight not centering in parent LinearLayout

Posted by: admin June 16, 2020 Leave a comment

Questions:

I realize this is probably a trivial layout question, but I can’t seem to get it working the way I want without layering in what I feel is too many container layouts. What I am trying to do is setup an ImageView such that the following conditions are satisfied:

  1. The width of the ImageView is some given percentage of the width of its parent (the screen width for now).
  2. The ImageView is centered horizontally within the screen.

I have created a test case using an XML layout, but in practice I will be creating these layouts and views programmatically; I don’t think this matters for the purposes of figuring out the correct layout though.

I am somewhat familiar with weights in Android layouts and how they are typically used to layout multiple views with relative weighting factors. In order to satisfy condition 1, I create a container LinearLayout (horizontal orientation), set its weightSum = 1, then embed my ImageView with a weight of whatever percentage I want, say 0.5. This works!

Next, I would like the ImageView to end up being centered in the screen horizontally. So I set the gravity to “center”/”centerHorizontal”. This is where I am stuck, because no matter what gravity/layout_gravity settings I choose it seems to always align to the left side.

Layout file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFF">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0">
        <ImageView
            android:src="@drawable/earth"
            android:adjustViewBounds="true"
            android:layout_width="0"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:layout_gravity="center_horizontal"
            android:id="@+id/imageView1" />
    </LinearLayout>
</LinearLayout>

Result:

Resulting image aligned to the left

What I really want to achieve is something like this:

Desired result

But in order to achieve that, I had to insert two dummy LinearLayouts with weights 0.25 on either side of my ImageView like so:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFF">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="0"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"/>
        <ImageView
            android:src="@drawable/earth"
            android:adjustViewBounds="true"
            android:layout_width="0"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:layout_gravity="center_horizontal"
            android:id="@+id/imageView1" />
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="0"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"/>
    </LinearLayout>
</LinearLayout>

This is an ugly and awkward layout in my opinion, not only because I am now having to use 3 additional LinearLayouts aside from my top-level LinearLayout just to size and position my view, but also because I want to do all of the layout programmatically and dynamically. I might decide to right or left align my views at runtime, or change their scaling factor relative to the screen width, which in this solution requires potentially adding/removing dummy layout views and setting all the weights appropriately.

I am hoping that someone better at layouts than I will have a better solution! Ideally something where I can just set the “gravity” (although I haven’t been able to get that to work), or some alternative way to set the width without needing the horizontal LinearLayout container and weights, since without that container I can center horizontally in my top-level vertical LinearLayout.

Thanks!

EDIT: I just realized that in my second layout attempt using dummy padding LinearLayouts that I can do away with the second padding LinearLayout (set to weight of 0.25) and just use one dummy padding LinearLayout before my ImageView, since they are relative to a predetermined weightSum in the parent. E.g.:

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="0"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"/>
        <ImageView
            android:src="@drawable/earth"
            android:adjustViewBounds="true"
            android:layout_width="0"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:layout_gravity="center_horizontal"
            android:id="@+id/imageView1" />
    </LinearLayout>

Still not the ideal solution I was hoping for.

How to&Answers:

you can just add android:gravity="center" to your linear layout (not in the imageView)

I hope it helps.

Answer:

The gravity of the ImageView does not center because the parent LinearLayout is horizontal.

You want to set gravity of the parent LinearLayout, that one will center horizontally inside its parent (the vertical LinearLayout).