In Android, Whenever we need to display a spinner item with image, text etc (i.e. creating more custom list) then we have to implement a custom adapter like base adapter. For customization we need to create a custom adapter class and then extends our default adapter in that class. Here we create a custom list using the overrided functions of adapter and display custom spinner. For more clarification about how’s an custom adapter implemented firstly we need to understand spinner.
Important Note: Spinner is associated with Adapter view so to fill the data in spinner we need to use one of the adapter class.
XML code of Spinner in Android:
<Spinner android:id="@+id/simpleSpinner " android:layout_width="fill_parent" android:layout_height="wrap_content" />
In above code snippet we implement a simple spinner in our xml file. Now to fill the data in this spinner we need to use one of the adapter class. Here we will use custom adapters so as to fill customize data with images in spinner.
Here is how’s CustomAdapter class extends BaseAdapter:
public class CustomAdapter extends BaseAdapter { @Override public int getCount() { return 0; } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { return null; }
BaseAdapter class in Android is Abstract class. So while extending it in CustomAdapter we override its methods based on requirement. In above code snippet the overridden functions of base adapter are used to set the data in spinner, listview or a gridview. These functions are already described in BaseAdapter tutorial.
Sample code of Custom Adapter class when we extends ArrayAdapter in that:
public class MyAdapter extends ArrayAdapter { public MyAdapter(Context context, int resource, int textViewResourceId, List objects) { super(context, resource, textViewResourceId, objects); } @Override public int getCount() { return super.getCount(); } @Override public View getView(int position, View convertView, ViewGroup parent) { return super.getView(position, convertView, parent); } }
In above code snippet we see the overrided functions of ArrayAdapter which are used to set the data in a list, grid or a spinner. These functions are already described in Custom ArrayAdapter tutorial.
Custom Spinner Example in Android Studio
Example 1: Example of custom spinner using BaseAdapter
Below is the example in which we displayed the country names with images in a spinner and whenever you click on a item, country name will be displayed as a message using toast. Below is the final output and code:
Select File -> New -> New Project. Fill the requirements and click "Finish" button.
Step 2: Open res -> layout -> xml (or) activity_main.xml and add following code. Here we are creating Spinner inside Relative Layout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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=".MainActivity"> <Spinner android:id="@+id/simpleSpinner" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginTop="50dp" /> </RelativeLayout>
Step 3: Create a new layout activity in res-> layout and name it custom_spinner_items.xml. Add following code. Here we are defining basic layout for custom items that will be displayed inside Spinner.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/imageView" android:layout_width="50dp" android:layout_height="50dp" android:padding="5dp" android:src="@drawable/ic_launcher" /><!--Make sure image is present in Drawable folder--> <TextView android:id="@+id/textView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:padding="@dimen/activity_horizontal_margin" android:text="Demo" android:textColor="#000" /> </LinearLayout>
Step 4: Open app -> java -> package -> MainActivity.java and add the following code. Explanation is included in the code itself.
package example.abhiandriod.customspinnerexample; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Spinner; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{ String[] countryNames={"India","China","Australia","Portugle","America","New Zealand"}; int flags[] = {R.drawable.india, R.drawable.china, R.drawable.australia, R.drawable.portugle, R.drawable.america, R.drawable.new_zealand}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Getting the instance of Spinner and applying OnItemSelectedListener on it Spinner spin = (Spinner) findViewById(R.id.simpleSpinner); spin.setOnItemSelectedListener(this); CustomAdapter customAdapter=new CustomAdapter(getApplicationContext(),flags,countryNames); spin.setAdapter(customAdapter); } //Performing action onItemSelected and onNothing selected @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int position,long id) { Toast.makeText(getApplicationContext(), countryNames[position], Toast.LENGTH_LONG).show(); } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }
Step 5: Create a new Class app -> java-> package and new class name CustomAdapter.java and add the following code. Here we will override the methods of BaseAdapter to fill data in Spinner.
package example.abhiandriod.customspinnerexample; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class CustomAdapter extends BaseAdapter { Context context; int flags[]; String[] countryNames; LayoutInflater inflter; public CustomAdapter(Context applicationContext, int[] flags, String[] countryNames) { this.context = applicationContext; this.flags = flags; this.countryNames = countryNames; inflter = (LayoutInflater.from(applicationContext)); } @Override public int getCount() { return flags.length; } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { view = inflter.inflate(R.layout.custom_spinner_items, null); ImageView icon = (ImageView) view.findViewById(R.id.imageView); TextView names = (TextView) view.findViewById(R.id.textView); icon.setImageResource(flags[i]); names.setText(countryNames[i]); return view; } }
Output:
Now run the app in Emulator/AVD and you will see the custom spinner displaying flags and country names together. Change country names inside spinner and you will see Toast displaying message which country is selected.
thanks for the tutorial, it’s amazing. but about instead of providing both items “countryname” and “flag” manually i call the countryname from array-string. because i’m using two languages in my application and if i manually insert country names, it will not be changed when the language is changed. so can anyone help me how i can call array-string in my spinner along with images.?
Thank’s A lot. Good Working
hello , i am getting an error
java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.widget.Spinner.setOnItemSelectedListener(android.widget.AdapterView$OnItemSelectedListener)’ on a null object reference
I think you forget to initialize your Spinner ,
just write this lines
Spinner yourSpinnerName = (Spinner)findViewById(R.id.spinnerId);
Thank you
I have two activity…Inside first activity spinner is there . if i select any spinner value from list then i want get click listener into second activity. Using spinner value i want to display data which is related to selected spinner but not toast message ..
Have you seen the solution to this
Thank you so much(Nandri)
#oldbutgold
Thank you so much really helpfull
value resource action setting red
if (id == R.id.action_settings)
not working
getMenuInflater().inflate(R.menu.menu_main, menu);
also this line menu red
for action_settings you need to give a resource value. and u need to create an menu_main.xml file
Hello, I’m having a java.lang.OutOfMemoryError: Failed to allocate a 95976012 byte allocation with 16777120 free bytes and 31MB until OOM error with my implementation of your code and I’m just wondering how to use bitmap in custom spinners ?
It’s okay. I resized my images .
Hi, I followed this example in to the letter but my code doesn’t work on some emulators and phones. Just one ; the custom phone. Where could the problem be ?
If i replace
String[] countryNames={“India”,”China”,”Australia”,”Portugle”,”America”,”New Zealand”};
int flags[] = {R.drawable.india, R.drawable.china, R.drawable.australia, R.drawable.portugle, R.drawable.america, R.drawable.new_zealand};
to
String[] country_phonecode = getResources().getStringArray(R.array.country_phonecode);
int flags[] = getResources().getIntArray(R.array.country_icon);
this example went on error, what’s the difference and how to create custom spinner like this one using resource array?
Thank you, it works so good
well explain
Great ! Thanks bro
It keeps marking R with red in layout resource
Hi,
Try clicking on R and press Alt+Enter. Also make sure you have added all the images in drawable folder with the specified naming used in this project.
Alternatively you can download the code which is given on the website and import it in Android Studio. Here we tested again and found everything is fine.
If you still found any problem, don’t hesitate to ask.
Thanks
Abhishek