According to Android documentation, Material Design style is supported for Spinner widget.
So I decided to use it in my app placing it on top of the Toolbar.
<
I spent two days on this problem, but now after reading many answers, I can post my solution. I've implemented two custom layouts for the spinner item and popup. Setting this attribute for spinner: android:background="?android:selectableItemBackground"
the default spinner black arrow is hidden and we can use what we prefer. I used the method setDropDownVerticalOffset(int) to manage the popup position on pre Lollipop Android versions.
My app global theme is
Now, the activity layout that contains the toolbar and the spinner:
activity_main.xml
custom_spinner_toolbar.xml
custom_spinner_dropdown_item.xml
SpinnerAdapter.java
public class SpinnerAdapter extends BaseAdapter
{
private Context mContext;
private List mValuesList;
public SpinnerAdapter(Context mContext, List mValuesList)
{
this.mContext = mContext;
this.mValuesList = mValuesList;
}
@Override
public int getCount()
{
return mValuesList.size();
}
@Override
public Object getItem(int position)
{
return mValuesList.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public View getDropDownView(int position, View view, ViewGroup parent)
{
if (view == null || !view.getTag().toString().equals("DROPDOWN"))
{
LayoutInflater inflater = LayoutInflater.from(mContext);
view = inflater.inflate(R.layout.custom_spinner_dropdown_item, parent, false);
view.setTag("DROPDOWN");
}
TextView textView = (TextView) view.findViewById(R.id.spinner_item_text);
textView.setText(getTitle(position));
return view;
}
@Override
public View getView(int position, View view, ViewGroup parent)
{
if (view == null || !view.getTag().toString().equals("NON_DROPDOWN"))
{
LayoutInflater inflater = LayoutInflater.from(mContext);
view = inflater.inflate(R.layout.custom_spinner_toolbar, parent, false);
view.setTag("NON_DROPDOWN");
}
TextView textView = (TextView) view.findViewById(R.id.spinner_item_text);
textView.setText(getTitle(position));
return view;
}
private String getTitle(int position)
{
return position >= 0 && position < mValuesList.size() ? mValuesList.get(position) : "";
}
}
Finally, the relevant part of activity source code:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
actionBar.setDisplayHomeAsUpEnabled(true);
mSpinner = (Spinner) findViewById(R.id.spinner_rss);
String[] items = getResources().getStringArray(R.array.spinner_rss_items);
List spinnerItems = new ArrayList();
for(int i = 0; i < items.length; i++)
{
spinnerItems.add(items[i]);
}
SpinnerAdapter adapter = new SpinnerAdapter(actionBar.getThemedContext(), spinnerItems);
mSpinner.setAdapter(adapter);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
{
mSpinner.setDropDownVerticalOffset(-116);
}
}
These are the results on Lollipop and Kitkat:
Hope it helps! :)