Custom spinner inside ConstrainLayout not aligning right

Viewed 230

I have a custom spinner inside a ConstrainLayout, The spinner selected value is not aligning right. This works right when I display the spinner in a relative layout. I want to display it correctly in the constrainlayout

Expected Output (First item is the selected item) :

This is the expected result

activity.xml

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/constrainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <com.esri.arcgisruntime.mapping.view.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </com.esri.arcgisruntime.mapping.view.MapView>

    <Spinner
        android:id="@+id/spinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#00000000"
        android:overlapAnchor="false"
        android:popupBackground="#00000000"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

spinner_layout.xml

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

<TextView
    android:id="@+id/txt"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingTop="5dp"
    android:textColor="#FFF"
    android:textSize="20sp"
    android:gravity="right"
    android:textStyle="bold|normal"
    android:singleLine="true"
    android:layout_weight="0.9"/>

<ImageView
    android:id="@+id/img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:layout_weight="0.1"
    android:contentDescription="@null"/>

UPDATE JAVA CODE:

    ArrayList<ItemData> list = new ArrayList<>();
    list.add(new ItemData("Stop", R.drawable.locationdisplaydisabled));
    list.add(new ItemData("On", R.drawable.locationdisplayon));
    list.add(new ItemData("Re-Center", R.drawable.locationdisplayrecenter));
    list.add(new ItemData("Navigation", R.drawable.locationdisplaynavigation));
    list.add(new ItemData("Compass", R.drawable.locationdisplayheading));
    SpinnerAdapter adapter = new SpinnerAdapter(this, R.layout.spinner_layout, R.id.txt, list);
    mSpinner.setAdapter(adapter);
    mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            switch (position) {
                case 0:
                    // Stop Location Display
                  
                    break;
                case 1:
                    // Start Location Display
                    break;
                case 2:
                    // Re-Center MapView on Location
                    break;
                case 3:
                    // Start Navigation Mode
                    break;
                case 4:
                    // Start Compass Mode
                    break;
            }
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }

    });

}

Current Output

Current result

3 Answers
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintVertical_bias="1"

Try Adding these four lines to your spinner in XML.

You need to add the attribute android:gravity="end" inside your Spinner to right align its content so the selected item should always be on the right side. So the spinner layout it should look like this:

<Spinner
    android:id="@+id/spinner"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#00000000"
    android:overlapAnchor="false"
    android:gravity="end"
    android:popupBackground="#00000000"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

And the results before and after are:

before after

I have noticed also a small alignment issue in your Spinner Item layout (spinner_layout.xml) where some icons are not fully align right in relation with other row icons and the selected icon. This can be fixed when you use android:layout_weight="1" to android:id="@+id/txt" and android:layout_weight="0" to android:id="@+id/img" like below:

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

    <TextView
        android:id="@+id/txt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:textColor="#FFF"
        android:textSize="20sp"
        android:gravity="right"
        android:textStyle="bold|normal"
        android:singleLine="true"
        android:layout_weight="1"/>

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_weight="0"
        android:contentDescription="@null"/>
</LinearLayout>

Final Result:

final

You need to add the attribute android:gravity="end" inside your LinearLayout to right align its content so the selected item should always be on the right side. So the spinner_layout it should look like this:

<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="end"
>

Or you can use a relative layout to create a custom spinner.

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

<TextView
    android:id="@+id/txt"
    android:text="hello"
    android:layout_width="match_parent"
    android:layout_toStartOf="@id/img"
    android:layout_height="wrap_content"
    android:paddingTop="5dp"
    android:textSize="20sp"
    android:layout_centerInParent="true"
    android:gravity="right"
    android:textStyle="bold|normal"
    android:singleLine="true"/>

    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:contentDescription="@null"
        android:padding="10dp"
        android:src="@android:drawable/ic_delete" />
</RelativeLayout>

Note: MariosP answer is also right you can choose anyone.

Related