通过引用多个 Spinner 的 setOnItemSelectedListener 传递 String 变量
好的,我已经阅读了,发现 Java 只按值传递,而不是按值传递参考,所以我不知道如何实现这一点。
- 我在 Android Activity 中有 6 个 Spinner,其中填充了不同的 SQLite 查询。
- 填充每个 Spinner 并设置 OnItemSelectedListener 的代码非常相似,因此我希望重构为一种方法,并使用每个 Spinner ID 和 Sqlite 查询调用它 6 次。
如何让 Spinner onItemSelectedListener 更改每个不同 Spinner 上的正确实例成员?
public void fillSpinner(String spinner_name, Final String field_name) { // 这会找到通过 spinner_name 传递到方法中的 Spinner ID // 来自资源文件。例如旋转器1 int resID = getResources().getIdentifier(spinner_name, "id", 获取包名()); Spinner s = (Spinner) findViewById(resID); 最终光标 cMonth; // 这获取数据来填充微调器,例如,如果 field_name 是 // 强度 = SELECT _id, 雪茄强度 GROUP BY 强度 cMonth = dbHelper.fetchSpinnerFilters(field_name); 开始管理光标(cMonth); String[] from = new String[] { 字段名称 }; int[] to = new int[] { android.R.id.text1 }; SimpleCursorAdapter 月 = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item,cMonth,从,到); Months.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); s.setAdapter(月); // 这是设置 Spinner Item Selected Listener 回调,其中 // 所有问题都会发生 s.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterViewparent, View view, int 位置,长 id) { Cursor theCursor = (Cursor)parent.getSelectedItem(); // 这是问题区域。 object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name)); } 公共无效onNothingSelected(AdapterView <?>父){ // showToast("Spinner1: 未选择"); } });
}
像 fillSpinner("spinner1","strength");
那样调用此方法。
它找到 ID 为 spinner1
的微调器,并在数据库中查询 strength
字段。 field_name,在本例中是一个强项,必须声明为在 onItemSelectedListener 中使用的最终变量,否则我会收到错误Cannot reference a non-final variable field_name inside an inside class Defined in a different method< /代码>。
但是,当使用每个不同的 Spinner 时,如何让 onItemSelectedListener 更改不同实例成员的值?这是最重要的代码行: object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name));
我无法使用最终字符串,因为当用户选择不同的值时,变量显然会发生变化。我已经阅读了很多内容并且很难找到解决方案。我可以复制并粘贴此代码 6 次,然后忘记重构,但我真的很想知道优雅的解决方案。如果您不明白我的问题,请发表评论,我不确定我是否解释得很好。
OK, I've read around and see that Java only passes by value, not by reference so I don't know how to accomplish this.
- I've 6 Spinners in an Android Activity that are populated with different SQLite queries.
- The code to populate each Spinner and set the OnItemSelectedListener is very similiar so I was hoping to refactor to one method and call it 6 times with each Spinner ID and Sqlite query.
How do I get the Spinner onItemSelectedListener to change the right instance member on each different Spinner?
public void fillSpinner(String spinner_name, final String field_name) { // This finds the Spinner ID passed into the method with spinner_name // from the Resources file. e.g. spinner1 int resID = getResources().getIdentifier(spinner_name, "id", getPackageName()); Spinner s = (Spinner) findViewById(resID); final Cursor cMonth; // This gets the data to populate the spinner, e.g. if field_name was // strength = SELECT _id, strength FROM cigars GROUP BY strength cMonth = dbHelper.fetchSpinnerFilters(field_name); startManagingCursor(cMonth); String[] from = new String[] { field_name }; int[] to = new int[] { android.R.id.text1 }; SimpleCursorAdapter months = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, cMonth, from, to); months.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); s.setAdapter(months); // This is setting the Spinner Item Selected Listener Callback, where // all the problems happen s.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { Cursor theCursor = (Cursor) parent.getSelectedItem(); // This is the problem area. object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name)); } public void onNothingSelected(AdapterView<?> parent) { // showToast("Spinner1: unselected"); } });
}
You call this method like this fillSpinner("spinner1","strength");
.
It finds the spinner with id spinner1
and queries the database for the strength
field. field_name, which is strength in this example had to be declared a final variable to be used in the onItemSelectedListener or I'd get the error Cannot refer to a non-final variable field_name inside an inner class defined in a different method
.
But how do I get the onItemSelectedListener to change the value of a different instance member when each different Spinner is used? This is the all important line of code:object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name));
I can't use a final String as the variable will obviously change when the user selects a different value. I've read around a good bit and am stumped to a solution. I can just copy and paste this code 6 times and forget about refactoring but I'd really like to know the elegant solution. Post a comment if you don't understand my question, I'm not sure if I explaned myself well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过传递附加类作为
fillSpinner
方法的参数来做到这一点:A. 创建
interface
B. 稍微更改您的方法:
C. 提供侦听器:
You can do it, by passing additional class as parameter of
fillSpinner
method:A. Create
interface
B. Change your method a bit:
C. provide listener:
将您的侦听器重构为新的“类”。根据需要使用正确的参数/实例进行初始化,以便重复的“代码”可重用。
Refactor your listener to a new "class". Initialize with the right arguments/instances as required so that the repeated "code" is reusuable.
是的,这就是我的管理方式,但我仍然愿意接受新的建议以接受答案,并且我还创建了赏金。
我没有创建像 panzerschreck 建议,所以我将其发布为我自己问题的新答案。有点黑客,但我只是在侦听器中创建了一个 if..then..else 语句来检查选择了哪个微调器,然后设置不同的实例成员。
这是类成员的
一些 hack,但是如果 Java 不允许对象真正通过引用传递,这就是我所能做的。
Right, this is how I managed it but I'm still open to new suggestions for an accepted answer and I also created a bounty.
I didn't create a new class like panzerschreck suggested so I'm posting this as a new answer to my own question. Bit of a hack but I just created an if..then..else statement in the listener to check what spinner was selected and then set a different instance member.
Here are the class members
Bit of hack but without Java allowing objects to be really passed by reference, it's all I could do.