Using style= tag on the spinner didnt work for me to override the styles, so i just changed the background.
First a custom drawable selector with the appropiate images.
drawable/btn_dropdown.xml
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/btn_dropdown_normal" />
<item android:state_pressed="true" android:drawable="@drawable/btn_dropdown_pressed" />
<item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_dropdown_pressed" />
<item android:state_enabled="true" android:drawable="@drawable/btn_dropdown_normal" />
<item android:drawable="@drawable/btn_dropdown_normal" />
</selector>
Next, i just reworked the btn_dropdown_* images that ships with the Android SDK. They should be located in ~androidsdkroot/platforms/android-(yourversion)/data/res/drawable-hdpi. There's 5 different states that can be used but i just made images for two. Normal & pressed.
Okay, the images done! Just need to change the spinner background to @drawable/btn_dropdown.xml to get our own look! I still use the android.R.layout.simple_spinner_item to display the objects in my spinner.
Lets get going, the main layout:
layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Custom Spinner with custom data" />
<Spinner android:id="@+id/SpinnerOrginal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Spinner android:id="@+id/SpinnerCustom"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/btn_dropdown"
/>
<Button android:id="@+id/buttonUseItem"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Use Selection"/>
<TextView android:id="@+id/myTextView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"/>
</LinearLayout>
Next up our helper class from the previous entry with a little modification.src/CountryInfo.java
public class CountryInfo {
private String countryName;
private long countryPopulation;
private int countryFlag; // Populate it with our resource ID for the correct image.
public CountryInfo(String cName, long cPopulation, int flagImage)
{
countryName = cName;
countryPopulation = cPopulation;
countryFlag = flagImage;
}
public String getCountryName()
{
return countryName;
}
public long getCountryPopulation()
{
return countryPopulation;
}
public int getCountryFlag()
{
return countryFlag;
}
public String toString()
{
return countryName;
}
}
And lastly our main activity with our CountryAdapter class that will implement the view.src/SpinnerTest.java (First part)
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import java.util.ArrayList;
public class SpinnerTest extends Activity
{
Button button_UseSelectedItem;
Spinner mySpinner;
TextView myTextView;
ArrayList<CountryInfo> myCountries;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
myCountries = populateList();
setContentView(R.layout.main);
mySpinner = (Spinner) findViewById(R.id.SpinnerCustom);
Spinner OrginalSpinner = (Spinner) findViewById(R.id.SpinnerOrginal);
button_UseSelectedItem = (Button) findViewById(R.id.buttonUseItem);
myTextView = (TextView) findViewById(R.id.myTextView);
CountryAdapter myAdapter = new CountryAdapter(this, android.R.layout.simple_spinner_item, myCountries);
mySpinner.setAdapter(myAdapter);
OrginalSpinner.setAdapter(myAdapter);
button_UseSelectedItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Can also use mySpinner.setOnItemClickListener(......)
// Using a separate button here as there's often other data to select
// or if you choose the wrong item.
CountryInfo myCountry;
if(mySpinner.getSelectedItem() != null)
{
myCountry = (CountryInfo) mySpinner.getSelectedItem();
myTextView.setText(String.format("Country: " + myCountry.getCountryName() + "\t Population: " + myCountry.getCountryPopulation()));
}
}
});
}
public ArrayList<CountryInfo> populateList()
{
ArrayList<CountryInfo> myCountries = new ArrayList<CountryInfo>();
myCountries.add(new CountryInfo("USA", 308745538, R.drawable.usa)); // Image stored in /drawable
myCountries.add(new CountryInfo("Sweden", 9482855, R.drawable.sweden));
myCountries.add(new CountryInfo("Canada", 34018000, R.drawable.canada));
return myCountries;
}
As you see it looks like the previous one except we have created a custom adapter for our new spinner. populateList() method also gets the ints from the icons i have in the drawable/ directory.
Okay lets continue with the adapter!
src/SpinnerTest.java (2nd part)
public class CountryAdapter extends ArrayAdapter<CountryInfo>
{
private Activity context;
ArrayList<CountryInfo> data = null;
public CountryAdapter(Activity context, int resource, ArrayList<CountryInfo> data)
{
super(context, resource, data);
this.context = context;
this.data = data;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{ // Ordinary view in Spinner, we use android.R.layout.simple_spinner_item
return super.getView(position, convertView, parent);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{ // This view starts when we click the spinner.
View row = convertView;
if(row == null)
{
LayoutInflater inflater = context.getLayoutInflater();
row = inflater.inflate(R.layout.spinner_layout, parent, false);
}
CountryInfo item = data.get(position);
if(item != null)
{ // Parse the data from each object and set it.
ImageView myFlag = (ImageView) row.findViewById(R.id.imageIcon);
TextView myCountry = (TextView) row.findViewById(R.id.countryName);
if(myFlag != null)
{
myFlag.setBackgroundDrawable(getResources().getDrawable(item.getCountryFlag()));
}
if(myCountry != null)
myCountry.setText(item.getCountryName());
}
return row;
}
}
}
getView() method could be skipped, typed it along for clarity. getDropDownView() inflates my own layout for the drop down list. I just inflate it and set the corresponding ImageView & TextView from each object in the ArrayList. Plenty of information if you google ListView and custom adapters.
layout/spinner_layout.xml ( LinearLayout with a ImageView and TextView )
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/bluegradient">
<ImageView android:id="@+id/imageIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/canada"/>
<TextView android:id="@+id/countryName"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:ellipsize="marquee"
style="@style/SpinnerText"/>
</LinearLayout>
drawable/bluegradient.xml (Our background in the dropdown view, changes when item is pressed)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<solid
android:color="#2183b0" />
<stroke
android:width="1dp"
android:color="#adc6e8" />
<corners
android:radius="4dp" />
<padding
android:left="4dp"
android:top="4dp"
android:right="4dp"
android:bottom="4dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#2183b0"
android:endColor="#7cbfde"
android:angle="270"
android:type="linear"
/>
<stroke
android:width="1dp"
android:color="#2183b0" />
<corners
android:radius="4dp" />
<padding
android:left="0dp"
android:top="4dp"
android:right="0dp"
android:bottom="4dp" />
</shape>
</item>
</selector>
That's it! Final result, spinner closed, and open!