You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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外观如下图:
Spinners

含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 14:21:01