Android动态创建Spinner存入ArrayList后获取选中位置恒为0
问题根因
- 变量名混淆+索引逻辑错误:
onItemSelected回调的第三个参数本身就是选中项位置,你把这个参数命名为i,和外部for循环的集合索引变量重名,回调内读取到的i永远是选中位置,不是当前Spinner在列表里的序号,所有回调触发时只会修改numbers[选中位置],根本对应不到Spinner本身的存储位置。 - 监听绑定时机完全错误:你没有在Spinner创建时绑定监听,而是点击查询按钮时才批量绑定。每次点击都会重新初始化
numbers数组(int数组默认填充0),而给Spinner绑定监听的瞬间,控件默认选中第0项会立刻触发回调,此时选中位置为0,所有回调只会反复修改numbers[0]的值,其余数组元素永远保持初始0值。 - 缺少Spinner身份匹配逻辑:回调中没有标识区分当前触发事件的是哪一个Spinner,无法把选中位置存入数组对应的下标位。
修复方案
- 把监听绑定逻辑移到
createList()方法中,Spinner创建、设置完Adapter后立刻绑定监听,不要等到点击查询按钮时才绑定。 - 每个Spinner创建时,通过
setTag()存储它在集合中的索引,回调时读取tag拿到对应数组下标,避免索引混淆。 numbers数组跟随Spinner列表的创建同步扩容,不要每次点击查询都重新创建数组覆盖已存储的选中值。- 重命名回调参数,避免和外部变量重名引发逻辑错误。
修复后的完整代码如下:
public class MainActivity extends AppCompatActivity { LinearLayout linearLayout; ArrayList<Spinner> myList = new ArrayList<>(); int[] numbers; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); linearLayout = findViewById(R.id.root); numbers = new int[0]; } // 点击按钮只做结果读取,不做监听绑定 public void showPosition(View view) { StringBuilder logBuilder = new StringBuilder("各Spinner选中位置:"); for (int pos : numbers) { logBuilder.append(pos).append(" "); } Log.d("SpinnerCheck", logBuilder.toString()); } public void createList(View view) { ArrayAdapter<CharSequence> arrayAdapter = ArrayAdapter.createFromResource(this, R.array.city, android.R.layout.simple_spinner_item); arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); Spinner spinner = new Spinner(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(500, 50); spinner.setLayoutParams(params); spinner.setAdapter(arrayAdapter); // 记录当前Spinner在列表中的索引,设为tag final int spinnerIndex = myList.size(); spinner.setTag(spinnerIndex); // 创建时直接绑定选中监听 spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int selectedPos, long id) { int currentIndex = (int) adapterView.getTag(); numbers[currentIndex] = selectedPos; } @Override public void onNothingSelected(AdapterView<?> adapterView) {} }); myList.add(spinner); // 扩容存储位置的数组,保留之前已存的选中值 numbers = Arrays.copyOf(numbers, myList.size()); // 新Spinner默认选中第0项,初始化对应位置的值 numbers[spinnerIndex] = 0; linearLayout.addView(spinner); } }
注意:使用
Arrays.copyOf需要在文件头部导入java.util.Arrays依赖。
内容的提问来源于stack exchange,提问作者peerzada burhan
相关产品推荐
相关产品推荐

