Передать строковые переменные по ссылке на setOnItemSelectedListener нескольких спиннеров - PullRequest
4 голосов
/ 18 января 2012

ОК, я прочитал и вижу, что Java передается только по значению, а не по ссылке, поэтому я не знаю, как это сделать.

  • I 've 6 Spinner в Android Activity, которые заполнены различными запросами SQLite.
  • Код для заполнения каждого Spinner и установки OnItemSelectedListener очень похож, поэтому я надеялся реорганизовать один метод и вызвать его 6 раз для каждого идентификатора Spinner и запроса Sqlite.Как получить 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");.

Находит счетчик с идентификатором spinner1 и запрашивает базу данных для поля strength.field_name, которое является силой в этом примере, должно было быть объявлено как последняя переменная для использования в onItemSelectedListener, иначе я бы получил ошибку Cannot refer to a non-final variable field_name inside an inner class defined in a different method.

Но как я могу получить onItemSelectedListener, чтобы изменить значениедругой элемент экземпляра, когда используется каждый отдельный Spinner?Это самая важная строка кода: object_reference_to_clas_member_of_field_name = theCursor .getString(theCursor.getColumnIndex(field_name));

Я не могу использовать конечную строку, поскольку переменная, очевидно, изменится, когда пользователь выберет другое значение.Я прочитал много хорошего и нахожусь в тупике к решению.Я могу просто скопировать и вставить этот код 6 раз и забыть о рефакторинге, но мне бы очень хотелось узнать элегантное решение.Оставьте комментарий, если вы не поняли мой вопрос, я не уверен, хорошо ли я объяснил.

Ответы [ 3 ]

1 голос
/ 21 января 2012

Вы можете сделать это, передав дополнительный класс в качестве параметра 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);
    }
});
1 голос
/ 18 января 2012

Рефакторинг вашего слушателя в новый «класс». При необходимости инициализируйте правильными аргументами / экземплярами, чтобы повторный «код» можно было повторно использовать.

0 голосов
/ 19 января 2012

Правильно, это то, как мне это удалось, но я все еще открыт для новых предложений о принятом ответе, и я также создал награду.

Я не создал новый класс, такой как 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, позволяющего действительно передавать объекты по ссылке, это все, что я мог сделать.

...