Search code examples
androidandroid-spinner

custom formatting of individual Spinner items not working


I want to have a particular text appearance on the first item displayed in a Spinner. Although the code below is called and executed, the first item in the spinner is not formatted as expected.

public class ClubsAdapter extends ArrayAdapter<String> {
private static List<String> mClubs = null;
public TextView tv;

public ClubsAdapter(Context context, int textViewResourceId, List<String> dataset) {
    super(context, textViewResourceId, dataset);
    mClubs = dataset;

    ListIterator<String> listIterator = mClubs.listIterator();
    String s = listIterator.next();
    listIterator.set(s.substring(1));
}


public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;

    if (v == null) {
        LayoutInflater inflater =
                (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.club, null);
    }
    
    tv = v.findViewById(R.id.club);

    String club = mClubs.get(position);
    if (club != null) {
        if (position == 0) {
            tv.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                tv.setTextAppearance(android.R.style.TextAppearance_Medium);
            } else {
                tv.setTextAppearance(mContext, android.R.style.TextAppearance_Medium);
            }
        } else {
            tv.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                tv.setTextAppearance(android.R.style.TextAppearance_Large);
            } else {
                tv.setTextAppearance(mContext, android.R.style.TextAppearance_Large);
            }
        }

        tv.setText(club);
    }

    return v;
}

}

Here is the XML:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/club"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />

And this is how I use this adapter:

        Spinner clubSpinner = (Spinner) root.findViewById(R.id.clubSpinner);
        ArrayAdapter<String> clubsAdapter = new ClubsAdapter(getContext(), R.layout.club, clubNames);
        clubsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        clubSpinner.setAdapter(clubsAdapter);

*** EDIT *** This is the XML for the Spinner, as requested:

    <Spinner            android:id="@+id/clubSpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toTopOf="@id/courseSpinner"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

Solution

  • Move setTypeface after setTextAppearance. The latter also sets the type face. Simple and stupid...

    The correct code is

        if (position == 0) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                tv.setTextAppearance(android.R.style.TextAppearance_Medium);
            } else {
                tv.setTextAppearance(mContext, android.R.style.TextAppearance_Medium);
            }
            tv.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                tv.setTextAppearance(android.R.style.TextAppearance_Large);
            } else {
                tv.setTextAppearance(mContext, android.R.style.TextAppearance_Large);
            }
            tv.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
        }