web-dev-qa-db-ja.com

Android Spinner:初期化中にonItemSelected呼び出しを避ける

SpinnerTextViewでAndroidアプリケーションを作成しました。 TextViewのスピナーのドロップダウンリストから選択したアイテムを表示したい。 SpinnerをonCreateメソッドに実装したので、プログラムを実行しているときに、TextViewに値が表示されます(ドロップダウンリストから項目を選択する前)。

ドロップダウンリストから項目を選択した後にのみ、TextViewに値を表示したい。どうすればいいですか?

ここに私のコードがあります:

import Android.app.Activity;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.AdapterView;
import Android.widget.AdapterView.OnItemSelectedListener;
import Android.widget.ArrayAdapter;
import Android.widget.Spinner;
import Android.widget.TextView;

public class GPACal01Activity extends Activity implements OnItemSelectedListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Spinner spinner = (Spinner) findViewById(R.id.noOfSubjects);

        // Create an ArrayAdapter using the string array and a default spinner layout
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,R.array.noofsubjects_array, Android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
    }

    public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
        TextView textView = (TextView) findViewById(R.id.textView1);
        String str = (String) parent.getItemAtPosition(pos);
        textView.setText(str);
    }

    public void onNothingSelected(AdapterView<?> arg0) {
        // TODO Auto-generated method stub

    }
}
125
Grant
spinner.setOnItemSelectedListener(this); // Will call onItemSelected() Listener.

したがって、最初に任意の整数値でこれを処理します

例:最初にint check = 0;を取得

public void onItemSelected(AdapterView<?> parent, View arg1, int pos,long id) {
   if(++check > 1) {
      TextView textView = (TextView) findViewById(R.id.textView1);
      String str = (String) parent.getItemAtPosition(pos);
      textView.setText(str);
   }
}

ブール値を使用して、現在の位置と以前の位置を確認することでもできます。 こちらを参照

153
Abhi

設定する前にこの行を置くだけOnItemSelectedListener

spinner.setSelection(0,false)
78

APIレベル3以降、ブール値を持つアクティビティでonUserInteraction()を使用して、ユーザーがデバイスと対話しているかどうかを判断できます。

http://developer.Android.com/reference/Android/app/Activity.html#onUserInteraction()

@Override
public void onUserInteraction() {
     super.onUserInteraction();
     userIsInteracting = true;
}

アクティビティのフィールドとして:

 private boolean userIsInteracting;

最後に、私のスピナー:

      mSpinnerView.setOnItemSelectedListener(new OnItemSelectedListener() {

           @Override
           public void onItemSelected(AdapterView<?> arg0, View view, int position, long arg3) {
                spinnerAdapter.setmPreviousSelectedIndex(position);
                if (userIsInteracting) {
                     updateGUI();
                }
           }

           @Override
           public void onNothingSelected(AdapterView<?> arg0) {

           }
      });

アクティビティを行ったり来たりすると、ブール値はfalseにリセットされます。魔法のように機能します。

58
Bill Mote

これは私のために働いた

AndroidでのSpinnerの初期化には問題がある場合がありますが、このパターンによって上記の問題が解決されたことがあります。

Spinner.setAdapter();
Spinner.setSelected(false);  // must
Spinner.setSelection(0,true);  //must
Spinner.setonItemSelectedListener(this);

設定アダプタは最初の部分であり、スピナーを初期化するときはonItemSelectedListener(this)が最後になります。上記のパターンでは、スピナーの初期化中にOnItemSelected()が呼び出されません

16
saksham

ハハ...同じ質問があります。 initViews()がこのように動作する場合、シーケンスがキーとなり、リスナーが最後になります。幸運を !

spinner.setAdapter(adapter);
spinner.setSelection(position);
spinner.setOnItemSelectedListener(listener);
10
Treesouth

私の解決策:

protected boolean inhibit_spinner = true;


@Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                int pos, long arg3) {

            if (inhibit_spinner) {
                inhibit_spinner = false;
            }else {

            if (getDataTask != null) getDataTask.cancel(true);
            updateData();
            }

        }
7
codareee

これは次の方法で実行できます。

AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            //set the text of TextView
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

yourSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            yourSpinner.setOnItemSelectedListener(listener);
        }

        @Override
        public void onNothingSelected(AdapterView<?> adapterView) {

        }
    });

最初に、リスナーを作成し、変数コールバックに関連付けます。次に、匿名の2番目のリスナーを作成し、これが初めて呼び出されたときに、リスナーを変更します=]

6
Charleston

複数のスピナーを有効にする同様の簡単なソリューションは、onItemSelected(...)の最初の実行時に、AdapterViewをコレクション-Activitiesスーパークラスに配置し、実行する前にAdapterViewがコレクションにあるかどうかを確認することです。これにより、スーパークラスでメソッドのセットが1つ有効になり、複数のAdapterViewとそのための複数のスピナーがサポートされます。

スーパークラス...

private Collection<AdapterView> AdapterViewCollection = new ArrayList<AdapterView>();

   protected boolean firstTimeThrough(AdapterView parent) {
    boolean firstTimeThrough = ! AdapterViewCollection.contains(parent);
    if (firstTimeThrough) {
       AdapterViewCollection.add(parent);
     }
    return firstTimeThrough;
   }

サブクラス...

public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
      if (! firstTimeThrough(parent)) {
        String value = safeString(parent.getItemAtPosition(pos).toString());
        String extraMessage = EXTRA_MESSAGE;
        Intent sharedPreferencesDisplayIntent = new         Intent(SharedPreferencesSelectionActivity.this,SharedPreferencesDisplayActivity.class);
    sharedPreferencesDisplayIntent.putExtra(extraMessage,value);
    startActivity(sharedPreferencesDisplayIntent);
  }
  // don't execute the above code if its the first time through
  // do to onItemSelected being called during view initialization.

}

2
Jonathan Cole

これを試して

spinner.postDelayed(new Runnable() {
        @Override
        public void run() {
            addListeners();
        }
    }, 1000);.o
2

その後、onTouchメソッドでユーザーインタラクションフラグをtrueに設定し、選択の変更が処理されたらonItemSelected()でリセットできます。ユーザーインタラクションフラグはスピナーのみで処理され、目的の動作に影響を与える可能性のあるアクティビティ内の他のビューでは処理されないため、このソリューションが好まれます。

コード内:

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

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) { 
            userSelect = false;
            // Your selection handling code here
        }
    }

}

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

SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
2
Ranjith Kumar

初期化中にspinner.setOnItemSelectedListener()を呼び出さないようにするため

spinner.setSelection(Adapter.NO_SELECTION, true); //Add this line before setting listener
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
});
2
Ketan Ramani

ブール値フィールドを作成します

private boolean inispinner;

アクティビティの作成中

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if (!inispinner) {
                inispinner = true;
                return;
            }
            //do your work here
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });
2

最初にsetOnTouchListener、次にonTouchのsetOnItemSelectedListenerで実現できます。

@Override
public boolean onTouch(final View view, final MotionEvent event) {
 view.setOnItemSelectedListener(this)
 return false;
}
1
vviieett

同じ問題があり、これは私のために働いています:

2つのスピナーがあり、初期化中、他のコントロールとのやり取り中、またはサーバーからデータを取得した後にそれらを更新します。

これが私のテンプレートです:

public class MyClass extends <Activity/Fragment/Whatever> implements Spinner.OnItemSelectedListener {

    private void removeSpinnersListeners() {
        spn1.setOnItemSelectedListener(null);
        spn2.setOnItemSelectedListener(null);
    }

    private void setSpinnersListeners() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                spn1.setOnItemSelectedListener(MyClass.this);
                spn2.setOnItemSelectedListener(MyClass.this);
            }
        }, 1);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        // Your code here
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
}

クラスが開始するとき、リスナーを直接設定する代わりにsetSpinnersListeners()を使用します。

Runnableは、値を設定した直後にスピナーがonItemSelectedを発火させないようにします。

(サーバー呼び出しなどの後)スピナーを更新する必要がある場合は、更新行の直前にremoveSpinnersListeners()を使用し、更新行の直後にsetSpinnersListeners()を使用します。これにより、更新後にonItemSelectedが起動しなくなります。

1
RoyBS