为了账号安全,请及时绑定邮箱和手机立即绑定

如何制作带有初始文本“SelectOne”的Android旋转器?

如何制作带有初始文本“SelectOne”的Android旋转器?

慕的地10843 2019-05-30 15:50:39
如何制作带有初始文本“SelectOne”的Android旋转器?我想使用一个最初(当用户还没有做出选择时)显示文本“SelectOne”的旋转器。当用户单击旋转器时,将显示项目列表,并且用户选择其中一个选项。用户做出选择后,所选项目将显示在旋转器中,而不是“选择一”。我有以下代码来创建一个旋转器:String[] items = new String[] {"One", "Two", "Three"};Spinner spinner = (Spinner) findViewById(R.id.mySpinner);ArrayAdapter<String>  adapter = new ArrayAdapter<String>(this,             android.R.layout.simple_spinner_item, items);adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);             spinner.setAdapter(adapter);使用此代码,首先显示“One”项。我可以添加一个新的项目“选择一”到项目,但“选择一”也将显示在下拉列表作为第一项,这不是我想要的。我怎样才能解决这个问题?
查看完整描述

3 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

下面是一个通用的解决方案,它覆盖Spinner视野。它覆盖了setAdapter()将初始位置设置为-1,并代理所提供的SpinnerAdapter若要显示位置小于0的提示字符串,请执行以下操作。

这已经在Android1.5到4.2上测试过了,但是买家要小心!因为此解决方案依赖于反射来调用私有AdapterView.setNextSelectedPositionInt()AdapterView.setSelectedPositionInt(),它不能保证在将来的操作系统更新中工作。这似乎是可能的,但这并不能得到保证。

通常情况下,我不会容忍这样的事情,但这个问题已经被问了足够多次,而且似乎是一个足够合理的要求,我认为我会张贴我的解决方案。

/**
 * 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);
        }
    }}


查看完整回答
反对 回复 2019-05-30
  • 3 回答
  • 0 关注
  • 489 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信