Aligning Selected Spinner Item
Asked Answered
C

7

9

I'm trying to make a slight adjustment to the positioning of the selected item in the spinner. Not the dropdown list items, as I already have a custom view in my adapter for that, but the selected item specifically.

As you can see in the screenshot, "Any" is the currently selected item. But it is aligned oddly within the container because it has to accommodate the longest string in the dropdown, which is "Dark Purple Burnt Sienna" (or whatever). I want to align the selected text to the right so that "Any" is next to the dropdown indicator instead of way out in the middle.

I've attempted to make adjustments to my custom spinner-item view, but it doesn't have any affect on the selected item.

I've also attempted to set gravity and text alignment on the Spinner itself, but it has no effect.

Here's the image and the xml:

enter image description here

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/default_black"
        android:layout_centerVertical="true"
        android:text="Color" />

    <Spinner
        android:id="@+id/spn_color"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"/>

</RelativeLayout>

Edit: Here's my adapter:

public class ColorsAdapter<T> implements SpinnerAdapter {
    ArrayList<String> mColors;
    ArrayList<Integer> mValues;
    Context mContext;

    public ColorsAdapter(ArrayList<String> colors, ArrayList<Integer> values,
                              Context context) {
        mContext = context;
        mColors = colors;
        mValues = values;
    }

    @Override
    public int getCount() {
        return mColors.size();
    }

    @Override
    public Object getItem(int position) {
        return mColors.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemViewType(int position) {
        return R.layout.list_item_color;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView v = new TextView(mContext);
        v.setText(mColors.get(position));
        return v;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE );
        View row = inflater.inflate(getItemViewType(position), parent, false);
        TextView tvName = (TextView)row.findViewById(R.id.tv_name);
        tvName.setText(mColors.get(position));
        row.setTag(mValues.get(position));
        return row;
    }


    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

}

And here's the XML for the list item:

<TextView
    android:id="@+id/tv_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:gravity="right"/>
Coetaneous answered 27/10, 2017 at 14:41 Comment(0)
C
5

You can adjust the settings for selected item in getView(int position, View convertView, ViewGroup parent) method. If you just want to set the gravity and text alignment, you should set it to the TextView in the method like

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    TextView v = new TextView(mContext);
    v.setText(mColors.get(position));
    v.setGravity(Gravity.END); // OR v.setGravity(Gravity.RIGHT);
    return v;
}

Or you can simply inflate custom layout if you want to make further customization:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);
    View row = null;
    if (inflater != null) {
        row = inflater.inflate(R.layout.list_item_view_color, parent, false);
        TextView textView = row.findViewById(R.id.textview);
        textView .setText(mColors.get(position));
    }
    return row;
}

Where list_item_view_color.xml is your layout file for the selected value.
(NOTE: If you want to use options like autoSizeTextType, you can use them with app prefix for AppCompatTextView in xml files)

Cockroach answered 3/11, 2017 at 7:34 Comment(0)
P
4

Simple solution would be to build another Custom view for the spinner TextView layout, and specify the gravity for your TextView in that. Something like :

<!--spinner_layout.xml (in layout/)-->

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

Use that in initalising the ArrayAdapter of your spinner :

ArrayAdapter<String> adapter = new ArrayAdapter<String>
                                   (this, android.R.layout.spinner_layout,
                                    spinnerArray);

UI output :

enter image description here

Peirsen answered 29/10, 2017 at 17:11 Comment(2)
I already have a custom view for the spinner items, as I mentioned in the description. Setting a drop down view resource has no affect on the selected item layout whatsoever.Coetaneous
It literally looks exactly like what you wrote out in your answer. Were you able to manipulate the positioning of the selected item with your code?Coetaneous
S
1

You can creating the TextView for the getView method programmatically so no property for alignment is being set, easy thing to do is inflate it in the same way you are doing it on the getDropdownView, or simply set the proper gravity in the view you are instantiated.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    TextView v = new TextView(mContext);
    v.setText(mColors.get(position));
    v.setGravity(Gravity.RIGHT);
    return v;
}
Sparerib answered 4/11, 2017 at 0:15 Comment(0)
J
0

You can try this

 android:autoSizeTextType="uniform"
Jacobs answered 27/10, 2017 at 14:46 Comment(1)
Only available in API 26 unfortunately.Coetaneous
Z
0

I can give you a method that may work.

In XML

1) add a new text view called the_current_color text view

2) allign this text view above the spinner and to the start of the arrow icon or wherever you want it to be.

In your code

1) when you listen to (on item selected ) from the spinner simply get the current text and set it in the (the_current_color) text view.

2) and try to hide the texts in the spinner by changing color to transparent.

Hope it works

Edit

I might also suggest something maybe it changes things

lets say that we have a spinner that uses this string resource file to populate its adapter

<string-array name="my_adapter">

<item>Blue </item> 
<item>Red</item> 

 </string-array>

until now we have a spinner that shows (red item) and (blue item) at the far left from the arrow icon of the spinner.

create another string resources now like that

<string-array name="my_adapter_two">

<item>           Blue </item> 
<item>           Red</item> 

 </string-array>

as you can see now the added space will give an illusion that the strings are beside the arrow icon

you can add space that fit your need and you can maybe switch the files after you click a certain item and then switch them back.

Zootoxin answered 2/11, 2017 at 11:34 Comment(2)
This could work, but I'm looking for a more official solution that doesn't involve hiding views. If there is one.Coetaneous
@Coetaneous yes official is better but as you said all the item buttons are affected by the length of any other long string in the spinner, so I guess your only way is to hide and show views through codeZootoxin
E
0

Padding, Margins and Alignments get confusing when it comes to Spinners. I ran into a similar issue as well. But for me I wasn't using a custom view and adapter, so I managed to use styles to get around this issue. For you since you are already using custom view and adapter, you can make the background null for the spinner so that the dropdown arrow will not be visible.

android:background="@null"

Then in the TextView, you can assign drawableRight to be the dropdown arrow.

android:drawableRight="@drawable/ic_spinner_drop_arrow_white_24dp"

The icon can be a dropdown vector drawable. Also to specify particular margin between the arrow and text, you should be able to use drawablePadding

Hope this helps.

Evadne answered 2/11, 2017 at 16:21 Comment(0)
B
0

You can try the following Custom view.

<?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/textView1"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="right"
        android:padding="15dp"
        android:textAlignment="gravity"
        android:textColor="@color/black"
        android:textSize="10dp" />
Brownedoff answered 3/11, 2017 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.