4

OK、読んだところ、Javaは参照ではなく値でのみ渡されるので、これを実現する方法がわかりません。

  • Androidアクティビティに6つのスピナーがあり、さまざまなSQLiteクエリが入力されています。
  • 各スピナーにデータを入力してOnItemSelectedListenerを設定するコードは非常に似ているため、1つのメソッドにリファクタリングして、各スピナー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");

idspinner1を持つスピナーを見つけ、データベースにstrengthフィールドを照会します。この例で強みであるfield_nameは、onItemSelectedListenerで使用される最終変数として宣言する必要がありました。そうしないと、エラーが発生しますCannot refer to a non-final variable field_name inside an inner class defined in a different method

しかし、それぞれ異なるスピナーが使用されているときに、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が提案したような新しいクラスを作成しなかったため、これを自分の質問に対する新しい回答として投稿しています。ちょっとしたハックですが、リスナーに 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 がなければ、私にできることはそれだけです。

于 2012-01-18T20:13:19.157 に答える