jwBurnside
jwBurnside

Reputation: 867

Aligning Selected Spinner Item

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"/>

Upvotes: 9

Views: 3033

Answers (7)

Kaushik NP
Kaushik NP

Reputation: 6781

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

Upvotes: 4

Rehan
Rehan

Reputation: 3285

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)

Upvotes: 6

Oscar Rene
Oscar Rene

Reputation: 361

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;
}

Upvotes: 1

Gopal909
Gopal909

Reputation: 7

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" />

Upvotes: 0

Hasan Bou Taam
Hasan Bou Taam

Reputation: 4035

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.

Upvotes: 0

theThapa
theThapa

Reputation: 631

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.

Upvotes: 0

John Joe
John Joe

Reputation: 12803

You can try this

 android:autoSizeTextType="uniform"

Upvotes: 0

Related Questions