可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm trying to get a Spinner to load up with no selected value. Once the user selects a value it then takes them to another page.
This is proving to be a problem because at present, the page just loads straight away before the user gets a choice to choose.
My spinner class is set up the same way as Google's: http://developer.android.com/resources/tutorials/views/hello-spinner.html
So basically, is it possible have a spinner that loads with nothing selected because at present, it loads the first item in my string array.
回答1:
is it possible have a spinner that loads with nothing selected
Only if there is no data. If you have 1+ items in the SpinnerAdapter
, the Spinner
will always have a selection.
Spinners
are not designed to be command widgets. Users will not expect a selection in a Spinner
to start an activity. Please consider using something else, like a ListView
or GridView
, instead of a Spinner
.
EDIT
BTW, I forgot to mention -- you can always put an extra entry in your adapter that represents "no selection", and make it the initial selected item in the Spinner
.
回答2:
Alternatively, you could override your spinner adapter, and provide an empty view for position 0 in your getView method, and a view with 0dp height in the getDropDownView
method.
This way, you have an initial text such as "Select an Option..." that shows up when the spinner is first loaded, but it is not an option for the user to choose (technically it is, but because the height is 0, they can't see it).
回答3:
This is a complete implementation of Paul Bourdeaux's idea, namely returning a special initial view (or an empty view) in getView()
for position 0.
It works for me and is relatively straightforward. You might consider this approach especially if you already have a custom adapter for your Spinner. (In my case, I was using custom adapter in order to easily customise the layout of the items, each item having a couple of TextViews.)
The adapter would be something along these lines:
public class MySpinnerAdapter extends ArrayAdapter { public MySpinnerAdapter(Context context, List items) { super(context, R.layout.my_spinner_row, items); } @Override public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) { if (position == 0) { return initialSelection(true); } return getCustomView(position, convertView, parent); } @NonNull @Override public View getView(int position, View convertView, @NonNull ViewGroup parent) { if (position == 0) { return initialSelection(false); } return getCustomView(position, convertView, parent); } @Override public int getCount() { return super.getCount() + 1; // Adjust for initial selection item } private View initialSelection(boolean dropdown) { // Just an example using a simple TextView. Create whatever default view // to suit your needs, inflating a separate layout if it's cleaner. TextView view = new TextView(getContext()); view.setText(R.string.select_one); int spacing = getContext().getResources().getDimensionPixelSize(R.dimen.spacing_smaller); view.setPadding(0, spacing, 0, spacing); if (dropdown) { // Hidden when the dropdown is opened view.setHeight(0); } return view; } private View getCustomView(int position, View convertView, ViewGroup parent) { // Distinguish "real" spinner items (that can be reused) from initial selection item View row = convertView != null && !(convertView instanceof TextView) ? convertView : LayoutInflater.from(getContext()).inflate(R.layout.my_spinner_row, parent, false); position = position - 1; // Adjust for initial selection item MyModel item = getItem(position); // ... Resolve views & populate with data ... return row; } }
That's it. Note that if you use a OnItemSelectedListener
with your Spinner, in onItemSelected()
you'd also have to adjust position
to take the default item into account, for example:
if (position == 0) { return; } else { position = position - 1; } MyModel selected = items.get(position);
回答4:
In my case, although size '2' is displayed in the spinner, nothing happens till some selection is done!
I have an xml file (data_sizes.xml) which lists all the spinner values.
- 2
- 4
- 8
- 16
- 32
In main.xml file: Spinner element
Then in my java code, I added:
In my activity: Declaration
Spinner spinnerSize; ArrayAdapter adapter;
In a public void function - initControls(): Definition
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());
My spinner listener:
/* Spinner Listener */
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 } }
回答5:
Using a custom spinner layout like this:
In the activity:
// populate the list ArrayList dataList = new ArrayList(); for (int i = 0; i dataAdapter = new ArrayAdapter(this, R.drawable.spinner_layout, dataList); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerObject.setAdapter(dataAdapter); spinnerObject.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { // to set value of first selection, because setOnItemSelectedListener will not dispatch if the user selects first element TextView spinnerTarget = (TextView)v.findViewById(R.id.spinnerTarget); spinnerTarget.setText(spinnerObject.getSelectedItem().toString()); return false; } }); spinnerObject.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { private boolean selectionControl = true; public void onItemSelected(AdapterView> parent, View view, int pos, long id) { // just the first time if(selectionControl){ // find TextView in layout TextView spinnerTarget = (TextView)parent.findViewById(R.id.spinnerTarget); // set spinner text empty spinnerTarget.setText(""); selectionControl = false; } else{ // select object } } public void onNothingSelected(AdapterView> parent) { } });
回答6:
you can put the first cell in your array to be empty({"","some","some",...}) and do nothing if the position is 0;
public void onItemSelected(AdapterView> parent, View view, int position, long id) { if(position>0) { label.setText(MainActivity.questions[position - 1]); } }
- if you fill the array by xml file you can let the first item empty
回答7:
My solution, in case you have a TextView as each row of the spinner:
// TODO: add a fake item as the last one of "items" final ArrayAdapter adapter=new ArrayAdapter(..,..,items) { @Override public View getDropDownView(final int position,final View convertView,final ViewGroup parent) { final View dropDownView=super.getDropDownView(position,convertView,parent); ((TextView)dropDownView.findViewById(android.R.id.text1)).setHeight(position==getCount()-1?0:getDimensionFromAttribute(..,R.attr.dropdownListPreferredItemHeight)); dropDownView.getLayoutParams().height=position==getCount()-1?0:LayoutParams.MATCH_PARENT; return dropDownView; } } ... spinner.setAdapter(adapter); _actionModeSpinnerView.setSelection(dataAdapter.getCount()-1,false); public static int getDimensionFromAttribute(final Context context,final int attr) { final TypedValue typedValue=new TypedValue(); if(context.getTheme().resolveAttribute(attr,typedValue,true)) return TypedValue.complexToDimensionPixelSize(typedValue.data,context.getResources().getDisplayMetrics()); return 0; }
回答8:
Merge this:
private long previousItemId = 0; @Override public long getItemId(int position) { long nextItemId = random.nextInt(Integer.MAX_VALUE); while(previousItemId == nextItemId) { nextItemId = random.nextInt(Integer.MAX_VALUE); } previousItemId = nextItemId; return nextItemId; }
With this answer:
public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener { private AdapterView.OnItemSelectedListener onItemSelectedListener; public SpinnerInteractionListener(AdapterView.OnItemSelectedListener selectedListener) { this.onItemSelectedListener = selectedListener; } boolean userSelect = false; @Override public boolean onTouch(View v, MotionEvent event) { userSelect = true; return false; } @Override public void onItemSelected(AdapterView> parent, View view, int pos, long id) { if(userSelect) { onItemSelectedListener.onItemSelected(parent, view, pos, id); userSelect = false; } } @Override public void onNothingSelected(AdapterView> parent) { if(userSelect) { onItemSelectedListener.onNothingSelected(parent); userSelect = false; } } }