通过引用多个Spinner的setOnItemSelectedListener传递字符串变量
好吧,我read around并且看到Java只通过值传递,而不是通过引用,所以我不知道如何实现这一点。通过引用多个Spinner的setOnItemSelectedListener传递字符串变量
- 我有6个Spinners在Android Activity中被填充了不同的SQLite查询。
- 填充每个Spinner并设置OnItemSelectedListener的代码非常相似,所以我希望重构为一个方法,并使用每个Spinner ID和Sqlite查询调用它6次。
-
如何获得微调onItemSelectedListener更改每个不同微调器上的正确实例成员?
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"); } });
}
调用此方法像这样fillSpinner("spinner1","strength");
。
它找到编号为spinner1
的微调框并在数据库中查询strength
字段。 field_name,这个例子中的强度必须被声明为在onItemSelectedListener中使用的最终变量,否则我会得到错误Cannot refer to a non-final variable field_name inside an inner class defined in a different method
。
但是,如何在使用每个不同的Spinner时,如何让onItemSelectedListener更改不同实例成员的值?这是所有重要的代码行:
我不能使用最终的字符串,因为当用户选择不同的值时,变量显然会改变。我已经读了很多,很难找到解决方案。我可以复制并粘贴这段代码6次,忘掉重构,但我真的很想知道这个优雅的解决方案。如果你不明白我的问题,请发表评论,我不确定我是否能够很好地解释自己。
你可以做到这一点,通过传递额外类为fillSpinner
方法的参数:
A.创建interface
public interface OnSpinnerValueSelected {
void onValueSelected(String selectedValue);
}
B.更改方法的位:
public void fillSpinner(String spinner_name, final String field_name,
final OnSpinnerValueSelected valueChangeListener) {
// Prepare spinner
s.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Cursor theCursor = (Cursor) parent.getSelectedItem();
valueChangeListener.onValueSelected(theCursor
.getString(theCursor.getColumnIndex(field_name)));
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
C.提供监听器:
fillSpinner("spinner1","strength", new OnSpinnerValueSelected() {
public void onValueSelected(String selectedValue) {
yourObject.setField(selectedValue);
}
});
太棒了,这个工作,似乎比在重构函数本身有硬编码变量名称更好。所以在Java中你不能通过引用传递一个String对象,但是你可以传递一个最终对象,它有一个方法来设置String对象的值。 – georgiecasey 2012-01-21 14:38:25
将您的听众重构为新的“课程”。根据需要使用正确的参数/实例进行初始化,以便重复的“代码”可重复使用。
是的,这听起来很正确。我会尝试并报告,欢呼 – georgiecasey 2012-01-18 14:27:37
对,这就是我如何管理它,但我仍然接受新的建议,以接受答案,我也创造了一个赏金。
我没有建立像panzerschreck这样的新课程,所以我将这个作为新答案发布给我自己的问题。一个黑客的位,但我只是在侦听器中创建了一个if..then..else语句,以检查选择哪个微调器,然后设置不同的实例成员。
s.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Cursor theCursor = (Cursor) parent.getSelectedItem();
if (field_name.equalsIgnoreCase("strength")) {
strength=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("ring")) {
ring_gauge=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("country")) {
country=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("wrapper")) {
wrapper=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("length")) {
length=theCursor.getString(theCursor.getColumnIndex(field_name));
} else if (field_name.equalsIgnoreCase("price")) {
price=theCursor.getString(theCursor.getColumnIndex(field_name));
}
// showToast(category);
}
public void onNothingSelected(AdapterView<?> parent) {
// showToast("Spinner2: unselected");
}
});
下面是类成员
private String strength,ring_gauge,country,wrapper,length,price;
黑客的Java位,但没有允许对象通过引用传递真的,这是我所能做的。
我必须说它不是一个很好的做法,如果'陈述。尽可能避免硬编码值,这是一个维护噩梦! – panzerschreck 2012-01-19 03:30:46
如果这就是你的意思,我无法在字符串上使用switch语句。我知道,我不想使用硬编码值,但还有其他选择。我很想知道这个优雅的解决方案。我尝试创建一个新的类作为你建议的监听器,但问题是我如何通过引用传递实例成员,而不是通过值来传递这个新监听器类的构造函数。 – georgiecasey 2012-01-19 03:50:37
实际上,目前尚不清楚你想要什么,什么问题你都面临着onItemSelected。请详细说明。 – jeet 2012-01-18 04:59:30
'不能在不同的方法中定义的内部类中引用非最终变量field_name',为什么不在主类中全局声明'field_name'。 – 2012-01-21 04:35:24