Adding hint to a Spinner

In EditText one can easily add hint by setting a string into the hint property but there is no such a way to add hints in Spinner.
In this tutorial we are going to see how to add hint text into a Spinner.

At first we have to create layout file spinner_item.xml with TextView like the following.

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tvSpinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp" />

The above layout will be used as the component in our Spinner.

Now we are going to create a class SpinnerWithHintAdapter by extending the ArrayAdapter class.

 public class SpinnerWithHintAdapter extends ArrayAdapter<String>{
 
    Context context;
    public SpinnerWithHintAdapter(Context context, int resource) {
        super(context, resource);
        this.context = context;
    }
 }

We shall make the first item of the spinner to a different color (hint text color) and make the rest of the items to normal text color so that it seems like the first item is our hint text. This can be achieved by overriding getView and getDropDownView methods like the following way.

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        TextView tvSpinner = (TextView) view;
        if(position == 0){
            // setting the hint text color primary color
            if(Build.VERSION.SDK_INT < 23){
                tvSpinner.setTextColor(context.getResources().getColor(R.color.colorPrimary));
            }else {
                tvSpinner.setTextColor(ContextCompat.getColor(context, R.color.colorPrimary));
            }
        }else {
            tvSpinner.setTextColor(Color.BLACK);
        }
        return view;
    }
 
    @Override
    public View getDropDownView(int position, View convertView,
                                ViewGroup parent) {
        View view = super.getDropDownView(position, convertView, parent);
        TextView tvSpinner = (TextView) view;
        if(position == 0){
            // setting the hint text color primary color
            if(Build.VERSION.SDK_INT < 23){
                tvSpinner.setTextColor(context.getResources().getColor(R.color.colorPrimary));
            }else {
                tvSpinner.setTextColor(ContextCompat.getColor(context, R.color.colorPrimary));
            }
        }else {
            tvSpinner.setTextColor(Color.BLACK);
        }
        return view;
    }

Optionally by overriding the isEnabled method it is possible to prevent the user from selecting the hint item like the following way.

    @Override
    public boolean isEnabled(int position){
        // not going to enable the first item of the spinner as it is hint
        if(position == 0) {
            return false;
        }
        else {
            return true;
        }
    }

The full class looks like the following.

public class SpinnerWithHintAdapter extends ArrayAdapter<String>{
 
    Context context;
    public SpinnerWithHintAdapter(Context context, int resource) {
        super(context, resource);
        this.context = context;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        TextView tvSpinner = (TextView) view;
        if(position == 0){
            // setting the hint text color primary color
            if(Build.VERSION.SDK_INT < 23){
                tvSpinner.setTextColor(context.getResources().getColor(R.color.colorPrimary));
            }else {
                tvSpinner.setTextColor(ContextCompat.getColor(context, R.color.colorPrimary));
            }
        }else {
            tvSpinner.setTextColor(Color.BLACK);
        }
        return view;
    }
 
    @Override
    public View getDropDownView(int position, View convertView,
                                ViewGroup parent) {
        View view = super.getDropDownView(position, convertView, parent);
        TextView tvSpinner = (TextView) view;
        if(position == 0){
            // setting the hint text color primary color
            if(Build.VERSION.SDK_INT < 23){
                tvSpinner.setTextColor(context.getResources().getColor(R.color.colorPrimary));
            }else {
                tvSpinner.setTextColor(ContextCompat.getColor(context, R.color.colorPrimary));
            }
        }else {
            tvSpinner.setTextColor(Color.BLACK);
        }
        return view;
    }
 
    // optional
    @Override
    public boolean isEnabled(int position){
        // not going to enable the first item of the spinner as it is hint
        if(position == 0) {
            return false;
        }
        else {
            return true;
        }
    }
 
    @Override
    public int getCount() {
		// exclude first element as it is the hint text
        return super.getCount()==0?0:super.getCount()-1; 
    }
}

Now we are going to create a simple layout with a Spinner.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.spinnerhintdemo.MainActivity">
 
    <Spinner
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/spinner" />
</RelativeLayout>

We can use our SpinnerWithHintAdapter in the MainActivity like the following way.

public class MainActivity extends AppCompatActivity {
 
    private Spinner spinner;
    private SpinnerWithHintAdapter spinnerAdapter;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        spinner = (Spinner) findViewById(R.id.spinner);
        spinnerAdapter = new SpinnerWithHintAdapter(MainActivity.this, R.layout.spinner_item);
        spinnerAdapter.add("Genre");
        spinnerAdapter.add("Action");
        spinnerAdapter.add("Adventure");
        spinnerAdapter.add("Comedy");
        spinnerAdapter.add("Documentary");
        spinnerAdapter.add("Horror");
        spinnerAdapter.add("Mystery");
        spinnerAdapter.add("Sci-Fi");
        spinnerAdapter.add("Thriller");
        // setting the view that will be shown during the drop down
        spinnerAdapter.setDropDownViewResource(R.layout.spinner_item);
        spinner.setAdapter(spinnerAdapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view,
                                       int position, long id) {
                if(position == 0)
                    return;
                Toast.makeText(MainActivity.this, "Your selected movie genre is "+ parent.getItemAtPosition(position), Toast.LENGTH_LONG).show();
            }
 
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
 
            }
        });
    }
}

The resulting app looks like the following.

spinner-hint-sc-1spinner-hint-sc-2spinner-hint-sc-3

The source code of the app could be downloaded from here.

Leave a Comment

Your email address will not be published. Required fields are marked *