androidxmlandroid-layoutandroid-linearlayoutandroid-layout-weight

How to fix layout_weight in Linear layout?


In my xml file I set each small circle (ImageView) to be the size of 25% of the screen with a Linear View and layout_weights.

Here is a screen shot from my phone
(how it is supposed to look)
On my tablet it does not change the size
to be 25% of the screen (this is how it looks)
How it must look How it looks on tablet

My code consists of three LinearLayout's each containing ImageView's with weights of 0.25 out of 1.

Here is the code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    xmlns:ads="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/imageView12"
        android:src="@drawable/circle_big"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <LinearLayout
        android:id="@+id/wrapper"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.03125" />
        
        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.09375" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.09375" />
        
        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.03125" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/wrapper"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:rotation = "120">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.03125" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.4375" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.03125" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/wrapper"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:weightSum="1.0"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:rotation = "60">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.03125" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.4375" />

        <ImageView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="0.25"
            android:id="@+id/imageView12"
            android:src="@drawable/circle_white"
            android:onClick="changeToScreenSelectLayout"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.03125"/>
    </LinearLayout>
</RelativeLayout>

Solution

  • You cannot use a png file as your circle_white. You could technically make this work if you choose the correct android:scaleType, but it would result in horribly aliased renderings.

    I would first delete your existing pngs (From each resource bucket) since they cannot be used for this. Then make a new file in drawable named "circle_white.xml". Put this in it, this will draw a circle with no intrinsic size. I.E. it will just fill whatever you render it with.

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="oval">
        <solid
            android:color="#fff"/>
    </shape>
    

    And then change from using ImageView's with a src of circle_white to a HeightMatchesWidthView with the background set to this new @drawable/circle_white. You would need to ensure the Views height matches the width which I did in a view extension below. To use this just make a new class somewhere and paste this in. In xml reference it by instead of having ImageView do com.whatever.HeightMatchesWidthView where the com.whatever is whatever package you put this in.

    public class HeightMatchesWidthView extends View {
        public HeightMatchesWidthView(final Context context) {
            super(context);
        }
    
        public HeightMatchesWidthView(final Context context, final AttributeSet attrs) {
            super(context, attrs);
        }
    
        public HeightMatchesWidthView(final Context context, final AttributeSet attrs, final int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
            int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
            setMeasuredDimension(width, width);
        }
    
        @Override
        protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
            super.onSizeChanged(w, w, oldw, oldh);
        }
    }
    

    Instead of the HeightMatchesWidthView you could also use a PercentRelativeLayout instead and use that to force them to be square, and the correct size without having to extend View to add support for forcing square.