33

アクティビティを作成するときに、スピナーをセットアップし、リスナーと初期値を割り当てます。onItemSelectedアプリケーションの初期化中にコールバックが自動的に呼び出されることを知っています。私が奇妙だと思うのは、これがデバイスを回転させたときに2回発生し、何らかの問題を回避しなければならないという問題を引き起こしていることです。スピナーの初期選択がゼロの場合、これは発生しません。問題を特定することができました。これが、問題を引き起こす最も簡単なアクティビティです。

public class MainActivity extends Activity implements OnItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i("Test","Activity onCreate");
    setContentView(R.layout.activity_main);
    ((Spinner)findViewById(R.id.spinner1)).setSelection(2);
    ((Spinner)findViewById(R.id.spinner1)).setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> spin, View selview, int pos, long selId)
{
    Log.i("Test","spin:"+spin+" sel:"+selview+" pos:"+pos+" selId:"+selId);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {}
}

そして、アプリケーションが起動されてからデバイスが回転したときに表示されるログキャットは次のとおりです。

    I/Test( 9881): spin:android.widget.Spinner@4052f508 sel:android.widget.TextView@40530b08 pos:2 selId:2
    I/Test( 9881): Activity onCreate
    I/Test( 9881): spin:android.widget.Spinner@40535d80 sel:android.widget.TextView@40538758 pos:2 selId:2
    I/Test( 9881): spin:android.widget.Spinner@40535d80 sel:android.widget.TextView@40538758 pos:2 selId:2

これは予想される動作ですか?私は何かが足りないのですか?

4

10 に答える 10

25

一般に、onItemSelected 呼び出しをトリガーするイベントは多数あるようで、すべてを追跡することは困難です。このソリューションでは、OnTouchListener を使用してユーザーが開始した変更にのみ応答できます。

スピナーのリスナーを作成します。

public class SpinnerInteractionListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {

    boolean userSelect = false;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        userSelect = true;
        return false;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        if (userSelect) { 
            // Your selection handling code here
            userSelect = false;
        }
    }

}

リスナーを OnItemSelectedListener と OnTouchListener の両方としてスピナーに追加します。

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
于 2015-02-11T23:38:05.807 に答える
2

これは私がしたことです:

ローカル変数を実行する

Boolean changeSpinner = true;

saveInstanceMethod で、スピナーの選択されたアイテムの位置を保存します

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("ItemSelect",mySpinner.getSelectedItemPosition());
}

次に、作成されたアクティビティで、savedInstanceState からその int を取得し、int が != 0 の場合は、ブール変数を false に設定します。

@Override
    public void onActivityCreated(Bundle savedInstanceState) {

    if (savedInstanceState!=null) {
        if (savedInstanceState.getInt("ItemSelect")!=0) {
           changeSpinner = false;
        }
    }

}

最後に、スピナーの OnItemSelected でこれを行います

mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    public void onItemSelected(AdapterView<?> parent,android.view.View v, int position, long id) {
        if (changeSpinner) {
           [...]
        } else {
           changeSpinner= true;
        }
    });

したがって、最初に呼び出されたときは何もせず、boolean 変数を true にするだけで、2 回目はコードを実行します。最善の解決策ではないかもしれませんが、うまくいきます。

于 2015-02-14T23:56:46.370 に答える
0

これを試して:

boolean mConfigChange = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    mConfigChange = false;
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_mainf);

    Log.i("SpinnerTest", "Activity onCreate");
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.colors,
            android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    ((Spinner) findViewById(R.id.spin)).setAdapter(adapter);

     ((Spinner) findViewById(R.id.spin)).setSelection(2);
    ((Spinner) findViewById(R.id.spin)).setOnItemSelectedListener(this);

}

@Override
protected void onResume() {
    mConfigChange = true;
    super.onResume();
}

@Override
public void onItemSelected(AdapterView<?> spin, View selview, int pos, long selId) {
    if (!mConfigChange)
        Log.i("Test", "spin:" + spin + " sel:" + selview + " pos:" + pos + " selId:" + selId);
    else
        mConfigChange = false;
}
于 2013-01-28T13:32:57.047 に答える