4

好的,我已经阅读并看到 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) {
    // 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");

它找到带有 id 的微调器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 更改不同实例成员的值?这是最重要的代码行: object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name));

我不能使用最终字符串,因为当用户选择不同的值时,变量显然会发生变化。我已经阅读了很多内容,并且很难找到解决方案。我可以复制并粘贴此代码 6 次而忘记重构,但我真的很想知道优雅的解决方案。如果您不理解我的问题,请发表评论,我不确定我是否解释得很好。

4

3 回答 3

1

将您的听众重构为一个新的“类”。根据需要使用正确的参数/实例进行初始化,以便重复的“代码”可重用。

于 2012-01-18T05:05:32.900 回答
1

您可以通过将附加类作为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);
    }
});
于 2012-01-21T04:17:57.240 回答
0

是的,这就是我管理它的方式,但我仍然愿意接受新的建议以获得可接受的答案,并且我还创造了一个赏金。

我没有像panzerschreck建议的那样创建一个新课程,所以我将其发布为我自己问题的新答案。有点 hack,但我只是在侦听器中创建了一个 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;

有点hack,但没有Java允许对象通过引用真正传递,这就是我能做的。

于 2012-01-18T20:13:19.157 回答