Android Spinner - 如何将列表选择默认为无

时间:2010-12-13 00:19:26

标签: android spinner listeners

我有一个需要根据某些选择更新自己的Android表单。该表格目前由2个Spinners(A和B)组成。在完成Spinner A的选择之前,不会创建微调器B.选择完成后,B将显示在视图中,并根据A的选择动态填充内容。这是我的代码:

public class MyForm extends Activity 
{   
    private final int SEL_ACTIVATE = 0;
    private final int SEL_DEACTIVATE = 1;

    private static final String[] actionList = {"Activate", "Deactivate" };

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        table = (TableLayout) findViewById(R.id.table);

        showListA(table);
    }

    public void showListA(View v)
    {        
        rowAction = new TableRow(this);

        Spinner spinner = new Spinner(this);
        spinner.setPrompt("Select...");
        spinner.setOnItemSelectedListener(
            new OnItemSelectedListener() 
            {
                public void onItemSelected(AdapterView<?> parent, View v, int position, long id) 
                {
                    switch (position)
                    {
                    case SEL_ACTIVATE:
                    case SEL_DEACTIVATE:
                        showListB(v);
                        break;
                    }
                }

                public void onNothingSelected(AdapterView<?> arg0) 
                {
                    // TODO Auto-generated method stub
                }
        });

        ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, actionList);
        adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
        spinner.setAdapter(adapter);

        rowAction.addView(tvAction);
        rowAction.addView(spinner);

        table.addView(rowAction, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    }

    ...
}

此代码正常运行。从列表中选择“激活”或“取消激活”时,showListB()执行与showListA()非常相似的创建包含Label和Spinner的新行的方式。

问题在于,默认情况下,“激活”显示在Spinner中,它执行showListB()并立即执行,表单的第二部分基于“激活”选项创建。我能想到的唯一解决方法是向Spinner添加第三个字段,如下所示:

private static final String[] actionList = {"None", "Activate", "Deactivate" };

...

switch (position)
{
case SEL_NONE:
    break;
case SEL_ACTIVATE:
case SEL_DEACTIVATE:
    showListB(v);
    break;
}

这有效......但我不希望列表中有第三个选项。我只是希望它默认为空白或显示某种“提示”文本,一旦按下它就不是列表中的选项。这可能吗?

由于

编辑:

xml内容:

<Spinner
    android:id="@+id/spinnerAction"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>  

5 个答案:

答案 0 :(得分:5)

我的data-sizes.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="chunks">
        <item>2</item>
        <item>4</item>
        <item>8</item>
        <item>16</item>
        <item>32</item>
    </string-array>
</resources>

在main.xml中:

<Spinner android:id="@+id/spinnerSize"  
android:layout_marginLeft="50px"
android:layout_width="fill_parent"                  
android:drawSelectorOnTop="true"
android:layout_marginTop="5dip"
android:prompt="@string/SelectSize"
android:layout_marginRight="30px"
android:layout_height="35px" /> 

在Java代码中:

Spinner spinnerSize;
ArrayAdapter adapter;

...

spinnerSize = (Spinner)findViewById(R.id.spinnerSize);
adapter = ArrayAdapter.createFromResource(this, R.array.chunks, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerSize.setAdapter(adapter);
spinnerSize.setOnItemSelectedListener(new MyOnItemSelectedListener());

...

class MyOnItemSelectedListener implements OnItemSelectedListener {

    public void onItemSelected(AdapterView<?> parent,
        View view, int pos, long id) {
        chunkSize = new Integer(parent.getItemAtPosition(pos).toString()).intValue();
    }
    public void onNothingSelected(AdapterView<?> parent) {
      // Dummy
    }
}

所以,虽然我可以看到2是我的第一个默认项目,但除非用户实际选择它,否则什么都不会发生。

希望这有帮助!

答案 1 :(得分:2)

如果需要,有一个decorater spinnerAdapter会自动添加一个默认值:



    protected class SpinnerAdapterWithNoValue implements SpinnerAdapter {

        private SpinnerAdapter _current;
        private final static String defaultValue = "Choisir";

        public SpinnerAdapterWithNoValue(SpinnerAdapter base) {
            _current = base;
        }

        @Override
        public int getCount() {
            return _current.getCount() + 1;
        }

        @Override
        public Object getItem(int position) {
            if (position == 0 || position == -1) {
                return null;
            }
            return _current.getItem(position - 1);
        }

        @Override
        public long getItemId(int position) {
            if (position == 0 || position == -1) {
                return -1;
            }
            return _current.getItemId(position - 1);
        }

        @Override
        public int getItemViewType(int position) {
            if (position == 0 || position == -1) {
                return -1;
            }
            return _current.getItemViewType(position - 1);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (position == 0 || position == -1) {
                final TextView v = (TextView) ((LayoutInflater) getContext().getSystemService(
                        Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.spinner_text, parent, false);
                v.setText(defaultValue);
                return v;
            }
            return _current.getView(position - 1, convertView, parent);
        }

        @Override
        public int getViewTypeCount() {
            return _current.getViewTypeCount();
        }

        @Override
        public boolean hasStableIds() {
            return _current.hasStableIds();
        }

        @Override
        public boolean isEmpty() {
            return _current.isEmpty();
        }

        @Override
        public void registerDataSetObserver(DataSetObserver observer) {
            _current.registerDataSetObserver(observer);
        }

        @Override
        public void unregisterDataSetObserver(DataSetObserver observer) {
            // TODO Auto-generated method stub
            _current.unregisterDataSetObserver(observer);
        }

        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            if (position == 0 || position == -1) {
                CheckedTextView v = (CheckedTextView) ((LayoutInflater) getContext().getSystemService(
                        Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.simple_spinner_dropdown_item, parent,
                        false);
                v.setText(defaultValue);
                return v;
            }
            return _current.getDropDownView(position - 1, convertView, parent);
        }
    }


然后你可以使用这个装饰器创建自己的微调器:



    public class SpinnerWithNoValue extends Spinner {

        public SpinnerWithNoValue(Context context) {
            super(context);
        }

        public SpinnerWithNoValue(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public SpinnerWithNoValue(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        @Override
        public void setAdapter(SpinnerAdapter orig) {
            final SpinnerAdapter adapter = new SpinnerAdapterWithNoValue(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);
            }
        }

        /*
         * getSelectedItem renvoi null si la valeur par defaut est séléctionnée
         * 
         * @see android.widget.AdapterView#getSelectedItem()
         */
        @Override
        public Object getSelectedItem() {
            return super.getSelectedItem();
        }
    }


您只需更改xml布局中的微调器声明:



com.myproject.SpinnerWithNoValue


如果需要,可以更改代码以设置微调器标签中的默认文本。

答案 2 :(得分:1)

Spinner将始终有一个选择。你可以做的是让Spinner显示类似“选择”或“选择一个选项”......

为此,您可以将列表选项设为

actionList = {"Select", "Desactivate" }

public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {               
        actionList[0] = "Activate";
        ...
 }

或者您可以执行更复杂的操作,例如覆盖Spinner视图 或者放一个按钮,而不是任何东西,当它被点击时,你创建你的微调器。

答案 3 :(得分:-1)

尝试使用提示属性

在xml中设置此项
android:prompt="@string/prompt"

这也将填充微调器对话框的顶部。

我在文档中忽略了这一点。提示无法直接应用。必须从另一个源引用prompt属性。尝试引用字符串值。

Android的文档:

android:prompt

Since: API Level
 The prompt to display when the spinner's dialog is shown.
 Must be a reference to another resource, in the form "@[+][package:]type:name" or to a       theme attribute in the form "?[package:][type:]name".
This corresponds to the global attribute resource symbol prompt.

答案 4 :(得分:-1)

我只是Android应用程序开发的初学者,并且面临着类似的问题;能够使用一个简单的解决方案对其进行排序 - 这对我有用,希望它也适合你:

public class AdmissionActivity extends Activity实现OnItemSelectedListener {

int i;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    i=0;
            .........

           }

........ .....

public void onItemSelected(AdapterView<?> parent, View view, 
        int pos, long id){

    if(i!=0){
        //do wat you want;
    }
    else i=1;
            }
            //initially the activity will be loaded and nothing  will happen (since
              // i=0); and then appropriate action will be taken since i would hav been

//改为sumtng else