Android Spinner未选择时默认返回NIL 规避传值空指针异常方案
需求与问题说明
用户进入Activity后需要完成4个Spinner下拉框的选择,再点击提交按钮,此时会弹出进度对话框,处理完成后将跳转回上一个Activity。
当前遇到的问题:若用户未完成所有必填项选择就提交,应用会抛出NPE空指针异常。
需要实现的效果:如果用户未在Spinner中选择任何选项,默认取对应选项列表的第一个值作为参数传递到下一个Activity。所有Spinner的首个可选项均为"NIL"(是"Nothing in line"的缩写),即Spinner未选择时默认传值为NIL。
初始业务代码
submit.setOnClickListener(v -> { progressBar = new ProgressDialog(v.getContext()); progressBar.setCancelable(false); progressBar.setTitle("Sending Data ..."); progressBar.setMessage("Redirecting to previous page"); progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressBar.setProgress(0); progressBar.setMax(100); progressBar.show(); progressBarStatus = 0; fileSize = 0; progressBar.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { openwhatsActivity(); } }); new Thread(() -> { while (progressBarStatus <100) { progressBarStatus = doOperation(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } progressBarHandler.post(() -> progressBar.setProgress(progressBarStatus)); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } progressBar.dismiss(); }).start(); }); } public int doOperation() { while (fileSize <= 10000) { fileSize++; if (fileSize == 1000) { return 10; }else if (fileSize == 2000) { return 20; } } return 100; } public void openwhatsActivity() { String roadtext = roadwheelsspinner.getSelectedItem().toString(); String separationtext = separationspinner.getSelectedItem().toString(); String sprockettext = sprocketwheelspinner.getSelectedItem().toString(); String returntext = returnrollersspinner.getSelectedItem().toString(); Intent intent = new Intent(this, whatsActivity.class); intent.putExtra(EXTRA_ROADTEXT, roadtext); intent.putExtra(EXTRA_SEPARATIONTEXT, separationtext); intent.putExtra(EXTRA_SPROCKETTEXT, sprockettext); intent.putExtra(EXTRA_RETURNTEXT, returntext); startActivity(intent); }
补充说明
用户未交互时Spinner会显示提示文案,用户点击展开后第一个可选项为"NIL",用户无相关内容申报时可主动选择"NIL",现在需要实现用户未操作Spinner时,默认提交值也为"NIL"。
Spinner外观如下图:
含Spinner初始化的完整代码
Spinner roadwheelsspinner = findViewById(R.id.roadwheelsspinner); ArrayAdapter<CharSequence> roadadapter = ArrayAdapter.createFromResource(this, R.array.roadnumbers, android.R.layout.simple_spinner_item); roadadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); roadwheelsspinner.setAdapter(new NothingSelectedSpinnerAdapter(roadadapter, R.layout.contact_spinner_row_nothing_selected_road, this)); Spinner separationspinner = findViewById(R.id.separationspinner); ArrayAdapter<CharSequence> separationadapter = ArrayAdapter.createFromResource(this, R.array.separationnumbers, android.R.layout.simple_spinner_item); separationadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); separationspinner.setAdapter(new NothingSelectedSpinnerAdapter(separationadapter, R.layout.contact_spinner_row_nothing_selected_separation, this)); Spinner sprocketwheelspinner = findViewById(R.id.sprocketwheelspinner); ArrayAdapter<CharSequence> sprocketadapter = ArrayAdapter.createFromResource(this, R.array.sprocketwheelnumbers, android.R.layout.simple_spinner_item); sprocketadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); sprocketwheelspinner.setAdapter(new NothingSelectedSpinnerAdapter(sprocketadapter, R.layout.contact_spinner_row_nothing_selected_sprocket, this)); Spinner returnrollersspinner = findViewById(R.id.returnrollersspinner); ArrayAdapter<CharSequence> returnadapter = ArrayAdapter.createFromResource(this, R.array.returnrollersnumbers, android.R.layout.simple_spinner_item); returnadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); returnrollersspinner.setAdapter(new NothingSelectedSpinnerAdapter(returnadapter, R.layout.contact_spinner_row_nothing_selected_return, this)); Spinner axlesspinner = findViewById(R.id.axlesspinner); ArrayAdapter<CharSequence> axlesadapter = ArrayAdapter.createFromResource(this, R.array.axlesnumbers, android.R.layout.simple_spinner_item); axlesadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); axlesspinner.setAdapter(new NothingSelectedSpinnerAdapter(axlesadapter, R.layout.contact_spinner_row_nothing_selected_axles, this)); submit.setOnClickListener(v -> { progressBar = new ProgressDialog(v.getContext()); progressBar.setCancelable(false); progressBar.setTitle("Sending Data ..."); progressBar.setMessage("Redirecting to previous page"); progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressBar.setProgress(0); progressBar.setMax(100); progressBar.show(); progressBarStatus = 0; fileSize = 0; progressBar.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { openwhatsActivity(); } }); new Thread(() -> { while (progressBarStatus <100) { progressBarStatus = doOperation(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } progressBarHandler.post(() -> progressBar.setProgress(progressBarStatus)); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } progressBar.dismiss(); }).start(); }); } public int doOperation() { while (fileSize <= 10000) { fileSize++; if (fileSize == 1000) { return 10; }else if (fileSize == 2000) { return 20; } } return 100; } public void openwhatsActivity() { String roadtext = roadwheelsspinner.getSelectedItem().toString(); String separationtext = separationspinner.getSelectedItem().toString(); String sprockettext = sprocketwheelspinner.getSelectedItem().toString(); String returntext = returnrollersspinner.getSelectedItem().toString(); Intent intent = new Intent(this, whatsActivity.class); intent.putExtra(EXTRA_ROADTEXT, roadtext); intent.putExtra(EXTRA_SEPARATIONTEXT, separationtext); intent.putExtra(EXTRA_SPROCKETTEXT, sprockettext); intent.putExtra(EXTRA_RETURNTEXT, returntext); startActivity(intent); }
最终解决方案
通过自定义Spinner适配器实现需求,完整自定义适配器代码如下:
public class NothingSelectedSpinnerAdapter implements SpinnerAdapter, ListAdapter { protected static final int EXTRA = 1; protected SpinnerAdapter adapter; protected Context context; protected int nothingSelectedLayout; protected int nothingSelectedDropdownLayout; protected LayoutInflater layoutInflater; public NothingSelectedSpinnerAdapter( SpinnerAdapter spinnerAdapter, int nothingSelectedLayout, Context context) { this(spinnerAdapter, nothingSelectedLayout, -1, context); } public NothingSelectedSpinnerAdapter(SpinnerAdapter spinnerAdapter, int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context) { this.adapter = spinnerAdapter; this.context = context; this.nothingSelectedLayout = nothingSelectedLayout; this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout; layoutInflater = LayoutInflater.from(context); } @Override public final View getView(int position, View convertView, ViewGroup parent) { if (position == 0) { return getNothingSelectedView(parent); } return adapter.getView(position - EXTRA, null, parent); } protected View getNothingSelectedView(ViewGroup parent) { return layoutInflater.inflate(nothingSelectedLayout, parent, false); } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { if (position == 0) { return nothingSelectedDropdownLayout == -1 ? new View(context) : getNothingSelectedDropdownView(parent); } return adapter.getDropDownView(position - EXTRA, null, parent); } protected View getNothingSelectedDropdownView(ViewGroup parent) { return layoutInflater.inflate(nothingSelectedDropdownLayout, parent, false); } @Override public int getCount() { int count = adapter.getCount(); return count == 0 ? 0 : count + EXTRA; } @Override public Object getItem(int position) { return position == 0 ? "NIL" : adapter.getItem(position - EXTRA); } @Override public int getItemViewType(int position) { return 0; } @Override public int getViewTypeCount() { return 1; } @Override public long getItemId(int position) { return position >= EXTRA ? adapter.getItemId(position - EXTRA) : position - EXTRA; } @Override public boolean hasStableIds() { return adapter.hasStableIds(); } @Override public boolean isEmpty() { return adapter.isEmpty(); } @Override public void registerDataSetObserver(DataSetObserver observer) { adapter.registerDataSetObserver(observer); } @Override public void unregisterDataSetObserver(DataSetObserver observer) { adapter.unregisterDataSetObserver(observer); } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { return position != 0; } }
核心修改点:将适配器getItem方法中position为0时的返回值从0改为"NIL",即可实现Spinner未选择时默认传值"NIL"到下一个Activity。
内容的提问来源于stack exchange,提问作者gtnikqi
相关产品推荐
相关产品推荐

