user1651105 user1651105 - 23 days ago 11
Android Question

How to set text size programaticaly for the android Spinner items?

I am new to Android development.

My situation seems abit different from the 1 million problems(related to spinner) that are found on the google where main solution is just to create custom xml for spinner items.

In my application, i need spinner items' text to be sized according to device physical size, e.g. it should take a fixed percent of the screen height/width, which means, that neither Px nor Dp sizing can help me here. I should note, that development is performed on API 15.

Spinner mySpinner = FindViewById<Spinner>(Resource.Id.mySpinner);
List<string> languages = new List<string>();
Translation.LoadAvailableLanguages(out languages);
var adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleSpinnerItem, languages);
adapter.SetDropDownViewResource(Resource.Layout.spinner_item);
mySpinner.Adapter = adapter;


As you can see, i use a default spinner item layout for the selection display and a custom
spinner_item
for the dropdown list. The custom layout is nothing but a
TextView
.

I programatically calculate the exact pixel values for layout components when application starts, so that this application looks the same no matter what dpi,resolution and physical size a tablet/phone is.

The problem is with the spinner. I can't seem to figure out, how to change the size of a text for the selection and for the drop down list.

I found one function in the adapter object which is:

adapter.GetDropDownView(int position, View convertView, ViewGroup parent);


The documentation says:


Gets a View that displays in the drop down popup the data at the specified position in the data set.

position int: index of the item whose view we want.

convertView View:
the old view to reuse, if possible. Note: You should check that this
view is non-null and of an appropriate type before using. If it is not
possible to convert this view to display the correct data, this method
can create a new view.

parent ViewGroup: the parent that this view
will eventually be attached to


The
position
is clear to me.

The
convertView
is a mystery. Where do i get this old view? What exactly is this view? What should i use for this parameter?

The
parent
is again unclear to me. What is it? I would think that parent of the drop down list is the Spinner. In a worst case, parent may also be an activity, however they both do not belong to
ViewGroup
so i don't understand what is actually required here?

EDIT1:

I have also tried this:

(mySpinner.GetChildAt(n) as TextView).SetTextSize(Android.Util.ComplexUnitType.Px, 100);


But it turned out, that
mySpinner.ChildCount
is 0 while
adapter.Count
has 3 items in it.

EDIT2: The solution

Based on the accepted answer, i have converted the Java for android code to C#/Xamarin for android

class SpinnerStringAdapter: Android.Widget.ArrayAdapter {
/// <summary>
/// Array items' text height in screen pixels
/// </summary>
private int ActualTextSize = 20;
/// <summary>
/// Display items as bold text
/// </summary>
private bool IsBold = false;
/// <summary>
/// Creates array adapter with custom sized text.
/// </summary>
/// <param name="AContext">The current context.</param>
/// <param name="ALayoutID">The resource ID for a layout file containing a TextView to use when instantiating views.</param>
/// <param name="AStringList">The string objects to represent in the ListView.</param>
/// <param name="ADisplay">The display of the parent activity</param>
/// <param name="ATextSize">The size of a text for the array items. Size in percents of Display height</param>
public SpinnerStringAdapter(Context AContext, int ALayoutID, System.Collections.IList AStringList, Display ADisplay, double ATextSize, bool AIsBold):
base(AContext, ALayoutID, AStringList) {
Android.Graphics.Point size = new Android.Graphics.Point();
ADisplay.GetSize(size);
int width = size.X;
int height = size.Y;
ActualTextSize = Convert.ToInt32(height * ATextSize / 100); // Convert percent to fraction and calculate actual height
IsBold = AIsBold;
}

public override View GetDropDownView(int position, View convertView, ViewGroup parent) {
TextView tv = (LayoutInflater.From(Context).Inflate(Resource.Layout.spinner_item, parent, false) as TextView);
tv.SetTextSize(Android.Util.ComplexUnitType.Px, ActualTextSize);
tv.SetText(GetItem(position).ToString(), TextView.BufferType.Normal);
if ( IsBold ) {
tv.SetTypeface(null, Android.Graphics.TypefaceStyle.Bold);
}
return tv;
}

public override View GetView(int position, View convertView, ViewGroup parent) {
TextView tv = ( LayoutInflater.From(Context).Inflate(Resource.Layout.spinner_item, parent, false) as TextView );
tv.SetTextSize(Android.Util.ComplexUnitType.Px, ActualTextSize);
tv.SetText(GetItem(position).ToString(), TextView.BufferType.Normal);
if ( IsBold ) {
tv.SetTypeface(null, Android.Graphics.TypefaceStyle.Bold);
}
return tv;
}
}

Answer

First, you could create a custom Adapter class which extends ArrayAdapter. This way, inside you can make an override of that 'getDropDownView' in order to change the display of the drop down popup (note that you need to define 'customspinneritem.xml', in this case with just a TextView ej textview1)

@Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
    View v = getLayoutInflater().inflate(R.layout.customspinneritem, parent, false);
    TextView tv = (TextView) v.findViewById(R.id.textview1);
    tv.setTextSize(**whatever**);
    tv.setText(languages[position]);
    return v;
}

If you want to change the display of the spinner before clicking on it, the one function to override would be 'getView(int position, View convertView, ViewGroup parent)'

Comments