Android 2.2 Spinner Looks Old In Actionbar
Solution 1:
When you create the SpinnerArrayAdapter
, you should use R.layout.sherlock_spinner_item
; then you should call setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item)
on the adapter. Note the difference between the two resource names.
From the sample code:
Contextcontext= getSupportActionBar().getThemedContext();
ArrayAdapter<CharSequence> list = ArrayAdapter.createFromResource(context, R.array.locations, R.layout.sherlock_spinner_item);
list.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
For your code this would be:
spinner = newSpinner(getSupportActionBar().getThemedContext());
ArrayAdapter<String> spinnerArrayAdapter = newArrayAdapter<String>
(
getSupportActionBar().getThemedContext(),
R.layout.sherlock_spinner_item,
newString[]{"All", "Solved", "Unsolved"}
);
spinnerArrayAdapter.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
spinner.setAdapter(spinnerArrayAdapter);
Solution 2:
I created a solution that uses ICS styled Spinner in MenuItem. Android support library has SpinnerICS widget and it is used in list navigation mode but they decided to make it internal so we can't use it directly. My solution is to access SpinnerICS widget through reflection.
First create SpinnerICS.java:
package com.example.widget;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
publicclassSpinnerICS
{
privateSpinnerspinner=null;
privateViewspinnerICS=null;
privateMethodsetAdapterICS=null;
privateMethodsetSelectionICS=null;
privateMethodgetAdapterICS=null;
privateMethodgetSelectedItemPositionICS=null;
privateMethodgetSelectedItemICS=null;
private Class<?> OnItemSelectedListenerICS = null;
privateMethodsetOnItemSelectedListenerICS=null;
publicSpinnerICS(Context context)
{
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
try {
Class<?> c = Class.forName("android.support.v7.internal.widget.SpinnerICS");
Constructor<?> ctor = c.getDeclaredConstructor(Context.class, AttributeSet.class, int.class);
ctor.setAccessible(true);
setAdapterICS = c.getMethod("setAdapter", SpinnerAdapter.class);
setSelectionICS = c.getMethod("setSelection", int.class);
getAdapterICS = c.getMethod("getAdapter");
getSelectedItemPositionICS = c.getMethod("getSelectedItemPosition");
getSelectedItemICS = c.getMethod("getSelectedItem");
OnItemSelectedListenerICS = Class.forName("android.support.v7.internal.widget.AdapterViewICS$OnItemSelectedListener");
setOnItemSelectedListenerICS = c.getMethod("setOnItemSelectedListener", OnItemSelectedListenerICS);
spinnerICS = (View)ctor.newInstance(context, null, android.support.v7.appcompat.R.attr.actionDropDownStyle);
} catch (Exception e) {
e.printStackTrace();
}
}
if (spinnerICS == null) {
spinner = newSpinner(context);
}
}
public View getView()
{
return (spinnerICS != null ? spinnerICS : spinner);
}
publicvoidsetAdapter(SpinnerAdapter adapter)
{
if (spinnerICS != null) {
try {
setAdapterICS.invoke(spinnerICS, adapter);
} catch (Exception e) {
e.printStackTrace();
}
} elseif (spinner != null) {
spinner.setAdapter(adapter);
}
}
publicvoidsetSelection(int position)
{
if (spinnerICS != null) {
try {
setSelectionICS.invoke(spinnerICS, position);
} catch (Exception e) {
e.printStackTrace();
}
} elseif (spinner != null) {
spinner.setSelection(position);
}
}
public SpinnerAdapter getAdapter()
{
if (spinnerICS != null) {
try {
return (SpinnerAdapter)getAdapterICS.invoke(spinnerICS);
} catch (Exception e) {
e.printStackTrace();
}
} elseif (spinner != null) {
return spinner.getAdapter();
}
returnnull;
}
publicintgetSelectedItemPosition()
{
if (spinnerICS != null) {
try {
return (Integer)getSelectedItemPositionICS.invoke(spinnerICS);
} catch (Exception e) {
e.printStackTrace();
}
} elseif (spinner != null) {
return spinner.getSelectedItemPosition();
}
return -1;
}
public Object getSelectedItem()
{
if (spinnerICS != null) {
try {
return getSelectedItemICS.invoke(spinnerICS);
} catch (Exception e) {
e.printStackTrace();
}
} elseif (spinner != null) {
return spinner.getSelectedItem();
}
returnnull;
}
publicclassOnItemSelectedListenerProxyListenerimplementsjava.lang.reflect.InvocationHandler
{
private OnItemSelectedListener listener;
publicOnItemSelectedListenerProxyListener(OnItemSelectedListener listener)
{
this.listener = listener;
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable
{
if (method.getName().equals("onItemSelected")) {
listener.onItemSelected(null, (View)args[1], (Integer)args[2], (Long)args[3]);
} elseif (method.getName().equals("onNothingSelected")) {
listener.onNothingSelected(null);
}
returnnull;
}
}
publicvoidsetOnItemSelectedListener(OnItemSelectedListener listener)
{
if (spinnerICS != null) {
try {
Objectobj= Proxy.newProxyInstance(OnItemSelectedListenerICS.getClassLoader(), newClass<?>[] { OnItemSelectedListenerICS } , newOnItemSelectedListenerProxyListener(listener));
setOnItemSelectedListenerICS.invoke(spinnerICS, obj);
} catch (Exception e) {
e.printStackTrace();
}
} elseif (spinner != null) {
spinner.setOnItemSelectedListener(listener);
}
}
}
and then use this SpinnerICS like this:
publicbooleanonCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
String[] items = newString[] { "one", "two", "three" };
ArrayAdapter<String> adapter = newArrayAdapter<String>(this, android.support.v7.appcompat.R.layout.support_simple_spinner_dropdown_item, items);
adapter.setDropDownViewResource(android.support.v7.appcompat.R.layout.support_simple_spinner_dropdown_item);
SpinnerICSspinner=newSpinnerICS(this);
MenuItemitem= menu.add("Sample:");
MenuItemCompat.setActionView(item, spinner.getView());
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
spinner.setAdapter(adapter);
returntrue;
}
Solution 3:
Just adding to the above answer. It works perfectly, but you need to set the context to themed context like below:
Contextctx= getSupportActionBar().getThemedContext();
Otherwise the theme won't match.
Solution 4:
The SpinnerICS solution works well as shown but using it is a little different from a normal Spinner.
For example, you cannot do:
In the xml:
<TableRow><TextViewandroid:text="@string/textview_abc"android:layout_width="80sp"android:gravity="center"android:inputType="textMultiLine"
/><SpinnerICSandroid:id="@+id/spinner_abc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="14sp"android:prompt="@string/spinner_abc"
/></TableRow>
In the java:
SpinnerICSspinner= (SpinnerICS) view.findViewById(R.id.spinner_abc);
It errors like this:
[javac] /home/androidin/build/Project/src/com/example/FragmentTab.java:77: error: inconvertible types
[javac] SpinnerICS spinner = (SpinnerICS) view.findViewById(R.id.spinner_abc);
[javac] ^
[javac] required: SpinnerICS
[javac] found: View
Post a Comment for "Android 2.2 Spinner Looks Old In Actionbar"