1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
   | /**
 * A modified Spinner that doesn't automatically select the first entry in the list.
 *
 * Shows the prompt if nothing is selected.
 *
 * Limitations: does not display prompt if the entry list is empty.
 */
public class NoDefaultSpinner extends Spinner {
 
    public NoDefaultSpinner(Context context) {
        super(context);
    }
 
    public NoDefaultSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    public NoDefaultSpinner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
 
    @Override
    public void setAdapter(SpinnerAdapter orig ) {
        final SpinnerAdapter adapter = newProxy(orig);
 
        super.setAdapter(adapter);
 
        try {
            final Method m = AdapterView.class.getDeclaredMethod("setNextSelectedPositionInt",int.class);
            m.setAccessible(true);
            m.invoke(this,-1);
 
            final Method n = AdapterView.class.getDeclaredMethod("setSelectedPositionInt",int.class);
            n.setAccessible(true);
            n.invoke(this,-1);
 
        } catch( Exception e ) {
            throw new RuntimeException(e);
        }
    }
 
    protected SpinnerAdapter newProxy(SpinnerAdapter obj) {
        return (SpinnerAdapter) java.lang.reflect.Proxy.newProxyInstance(
                obj.getClass().getClassLoader(),
                new Class[]{SpinnerAdapter.class},
                new SpinnerAdapterProxy(obj));
    }    
 
 
 
    /**
     * Intercepts getView() to display the prompt if position < 0
     */
    protected class SpinnerAdapterProxy implements InvocationHandler {
 
        protected SpinnerAdapter obj;
        protected Method getView;
 
 
        protected SpinnerAdapterProxy(SpinnerAdapter obj) {
            this.obj = obj;
            try {
                this.getView = SpinnerAdapter.class.getMethod("getView",int.class,View.class,ViewGroup.class);
            } catch( Exception e ) {
                throw new RuntimeException(e);
            }
        }
 
        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
            try {
                return m.equals(getView) && (Integer)(args[0])<0 ? getView((Integer)args[0],(View)args[1],(ViewGroup)args[2]) : m.invoke(obj, args);
            } catch (InvocationTargetException e) {
                throw e.getTargetException();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
 
 
        protected View getView(int position, View convertView, ViewGroup parent) throws IllegalAccessException {
            if( position<0 ) {
                final TextView v = (TextView) ((LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.simple_spinner_item,parent,false);
                v.setText(getPrompt());
                return v;
            }
 
            return obj.getView(position,convertView,parent);
        }
 
    }
 
 
} | 
Partager