0

I use the following function to resize the text on a spinner when an item is selected:

mySpinner.post(new Runnable()
{
    public void run()
    {
        mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
            {
                TextView tempView = ((TextView) parent.getChildAt(0));
                ((TextView) parent.getChildAt(0)).setTextSize(TypedValue.COMPLEX_UNIT_PX, SetTextSize(tempView.getText().toString(), tempView.getWidth() - tempView.getPaddingLeft() - tempView.getPaddingRight(), (int) fieldHeight - tempView.getPaddingTop() - tempView.getPaddingBottom()));
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent)
            {
                // Do nothing
            }
        });
    }
});

The problem is, before it resizes the text to the correct size, the text is drawn in the incorrect size. What I need to do is call my function SetTextSize as soon as the item is selected. I cannot find anyway to do this. setOnItemSelectedListener won't do because text is displayed in the incorrect size before the event runs.

I have changed:

mySpinner.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, CHOICES));

To:

mySpinner.setAdapter(new MyArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, CHOICES));

and added the following class:

public class MyArrayAdapter extends ArrayAdapter
{
    public MyArrayAdapter(Context context, int textViewResourceId, Object[] objects)
    {
        super(context, textViewResourceId, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        ((TextView) convertView).setTextSize(TypedValue.COMPLEX_UNIT_PX, SetTextSize(((TextView) convertView).getText().toString(), convertView.getWidth() - convertView.getPaddingLeft() - convertView.getPaddingRight(), (int) fieldHeight - convertView.getPaddingTop() - convertView.getPaddingBottom()));
        return convertView;
    }
}

Unfortunately, now my program crashes immediately when it starts.

I have created the following class:

class MySpinnerAdapter extends ArrayAdapter<String>
{
    MySpinnerAdapter()
    {
        super(MainActivity.this, R.layout.row, R.id.label, CHOICES);
    }
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = super.getView(position, convertView, parent);
        TextView label = (TextView)row.findViewById(R.id.label);
        if (label != null)
            label.setTextSize(TypedValue.COMPLEX_UNIT_PX, SetTextSize(label.getText().toString(), label.getWidth() - label.getPaddingLeft() - label.getPaddingRight(), (int) fieldHeight - label.getPaddingTop() - label.getPaddingBottom()));
        return(row);
    }
}

I now have 2 problems. Firstly, this line causes my program to crash:

label.setTextSize(TypedValue.COMPLEX_UNIT_PX, SetTextSize(label.getText().toString(), label.getWidth() - label.getPaddingLeft() - label.getPaddingRight(), (int) fieldHeight - label.getPaddingTop() - label.getPaddingBottom()));

Secondly, the styles that are in "row.xml" are applied to my spinner. If I don't specify any styles, then my program crashes. I simply do not want the xml file to alter the way my spinner looks because I do not know at compile time. I would like the spinner to use the default values that it was using before I created the XML file, and anything else I can then change in code.

Dan Bray
  • 7,242
  • 3
  • 52
  • 70
  • You could try my anser [here](http://stackoverflow.com/questions/16693941/spinner-text-size-does-not-change/16694058#16694058) – TronicZomB Jun 08 '13 at 17:43
  • That will not work because I am not using XML. I know of no way to make XML work dynamically, so I cannot use it. – Dan Bray Jun 08 '13 at 21:28

2 Answers2

1

Change your this code

mySpinner.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, CHOICES));

to

mySpinner.setAdapter(new ArrayAdapter<String>(this, R.layout.spinner_layout, CHOICES));

where the code for spinner_layout.xml is

 <?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:layout_width="fill_parent"
android:layout_height="48dp"
android:gravity="center_vertical"
android:textColor="@color/green"
android:paddingLeft="4dp"
android:textSize="18sp"
android:ellipsize="marquee"
android:singleLine="true" />

change layout_height and text size according to your need

Avinash Kumar Pankaj
  • 1,700
  • 2
  • 18
  • 27
  • I can't possibly set layout_height and text size according to my need in XML. I simply do not know the layout_height and text size until run time. If I have to use XML at all, I do not want my XML to have any effect on my styles. Maybe I should write the XML file dynamically, and set it with the same styles the spinner comes with by default. Then, I can use XML, but the XML won't affect how it looks. I know that defeats the purpose of XML, but all I'm wanting to do is run 1 line of code when an item is selected – Dan Bray Jun 10 '13 at 05:15
  • i am not able to understand what u need. But i think u should know what size you need – Avinash Kumar Pankaj Jun 10 '13 at 05:18
  • How can I know what size I need? I am making my program to be compatible on as many devices as possible, so I need to calculate the size at runtime based on the width and height of the screen. This line of code calculates the text size perfectly: ((TextView) parent.getChildAt(0)).setTextSize(TypedValue.COMPLEX_UNIT_PX, SetTextSize(tempView.getText().toString(), tempView.getWidth() - tempView.getPaddingLeft() - tempView.getPaddingRight(), (int) fieldHeight - tempView.getPaddingTop() - tempView.getPaddingBottom())); – Dan Bray Jun 10 '13 at 06:27
0

I finally have the text on my spinner resizing perfectly and I think the code is efficient. Thanks everyone who tried to help. :)

class MySpinnerAdapter extends ArrayAdapter<String>
{
    MySpinnerAdapter(int dropDownResource, String[] choices)
    {
        super(MainActivity.this, dropDownResource, choices);
    }
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        if (row == null)
            row = super.getView(position, convertView, parent);
        if (parent.getWidth() > 0)
        {
            TextView label = (TextView) row.findViewById(android.R.id.text1);
            label.setTextSize(TypedValue.COMPLEX_UNIT_PX, SetTextSize(label.getText().toString(), parent.getWidth() - label.getPaddingLeft() - label.getPaddingRight(), (int) fieldHeight - label.getPaddingTop() - label.getPaddingBottom()));
            label.setPadding(label.getPaddingLeft(), 0, 0, 0);
        }
        return(row);
    }
}
Dan Bray
  • 7,242
  • 3
  • 52
  • 70