Search code examples
androidxmlandroid-layoutandroid-relativelayoutandroid-percent-library

Switch element not centre aligning horizontally within allocated space


After creating a PercentRelativeLayout, I noticed that the SwitchCompat control does not align to the center horizontally despite settings properties. What can be done in order to resolve this issue? I tried using android:layout_centerHorizontal="true", but this doesn't seem to work.

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="10"
    android:layout_marginTop="10dp"
    android:layout_marginBottom="10dp">
    <ImageView
        android:id="@+id/imageView1"
        app:layout_widthPercent="40%"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_image1" />

    <android.support.v7.widget.SwitchCompat
        android:id="@+id/switch_map_emiratesairline_emiratesgreenwichpeninsula"
        app:layout_widthPercent="20%"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:theme="@style/Theme.AppCompat.Light"
        android:background="@android:color/transparent"
        android:layout_toEndOf="@id/imageView1"/>

    <ImageView
        android:id="@+id/imageView2"
        app:layout_widthPercent="40%"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:src="@drawable/ic_image2"
        android:layout_toEndOf="@id/switch_tgl"/>
</android.support.percent.PercentRelativeLayout>

Solution

  • It might look like a bug, but actually it doesn't relate to SwitchCompat (as issue is reproduced for Switch as well. But it also doesn't relate to PercentRelativeLayout. And even doesn't relate to RelativeLayout. It relates to Switch with width different from wrap_content (as far as I can see).

    Simple example:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">
    
        <android.support.v7.widget.SwitchCompat
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"/>
    </FrameLayout>
    

    Neither gravity nor layout_gravity has effect on switch's position - it is aligned to the right. One can replace FrameLayout with LinearLayout and result will be the same. To understand why this happens one should try to find answer in Switch/SwitchCompat source code (sorry, I haven't tried to do so...)

    So, to resolve your issue the only thing I could come up with is a hack: wrap SwitchCompat with some layout. And use wrap_content as SwitchCompat width.

    <android.support.percent.PercentRelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="10"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp">
        <ImageView
            android:id="@+id/imageView1"
            app:layout_widthPercent="40%"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:src="@drawable/avatar" />
    
        <FrameLayout
            android:id="@+id/switch_tgl"
            app:layout_widthPercent="20%"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:layout_toRightOf="@id/imageView1">
            <android.support.v7.widget.SwitchCompat
                android:layout_gravity="center_horizontal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:theme="@style/Theme.AppCompat.Light"
                android:background="@android:color/transparent" />
        </FrameLayout>
    
        <ImageView
            android:id="@+id/imageView2"
            app:layout_widthPercent="40%"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:src="@drawable/avatar"
            android:layout_toRightOf="@id/switch_tgl"/>
    </android.support.percent.PercentRelativeLayout>
    

    Hope it helps