OnClickListenerをSpinnerで起動しようとしていますが、次のエラーが表示されます。
Java.lang.RuntimeExceptionは「AdapterViewのsetOnClickListenerを呼び出さないでください。おそらく、代わりにsetOnItemClickListenerが必要です」
OnItemClickListenerではなく、onClickListenerを呼び出したいと確信しています。 Stack Overflowで他の誰かが質問したのを見つけましたAndroid Spinner?
答えは次のとおりです。
スピナーの基になるビュー(通常はid:Android.R.id.text1のTextView)でクリックリスナーを設定する必要があります。そうするには:
カスタムスピナーの作成コンストラクターで(属性を使用して)レイアウトAndroid.R.layout.simple_spinner_itemを指定してスピナーを作成しますfindViewById(Android.R.id.text1)を実行してTextViewを取得し、onClickListenerをTextViewに設定します
私はそこに記された答えを試しましたが、うまくいかないようです。 findViewById()を実行した後、TextViewへのNULLポインターを取得します。
これは私がやっていることです:
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.layoutspinner,dataArray);
spinner.setAdapter(adapter);
TextView SpinnerText = (TextView)findViewById(R.id.spinnerText);
if (SpinnerText == null) {
System.out.println("Not found");
}
else {
SpinnerText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
//Do something
}
});
}
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/spinnerText"
Android:singleLine ="true"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:textSize="6pt"
Android:gravity="right"/>
私は何を間違えていますか?
私はStack Overflowを初めて使用します。他のスレッドに追加の質問を投稿する方法を見つけることができなかった(または、ほとんど担当者がいないのでコメントする)ので、新しい質問を始めました。
推奨ごとに私はこれを試しました:
int a = spinnerMes.getCount();
int b = spinnerMes.getChildCount();
System.out.println("Count = " + a);
System.out.println("ChildCount = " + b);
for (int i = 0; i < b; i++) {
View v = spinnerMes.getChildAt(i);
if (v == null) {
System.out.println("View not found");
}
else {
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Click code
}
});
}
}
しかし、 LogCat は有望な結果を示していません。
10-14 16:09:08.127: INFO/System.out(3116): Count = 7
10-14 16:09:08.127: INFO/System.out(3116): ChildCount = 0
APIレベル7および8でこれをテストし、同じ結果を得ました。
以下はあなたが望むように動作しますが、理想的ではありません。
public class Tester extends Activity {
String[] vals = { "here", "are", "some", "values" };
Spinner spinner;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
spinner = (Spinner) findViewById(R.id.spin);
ArrayAdapter<String> ad = new ArrayAdapter<String>(this, Android.R.layout.simple_dropdown_item_1line, vals);
spinner.setAdapter(ad);
Log.i("", "" + spinner.getChildCount());
Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
int a = spinner.getCount();
int b = spinner.getChildCount();
System.out.println("Count =" + a);
System.out.println("ChildCount =" + b);
for (int i = 0; i < b; i++) {
View v = spinner.getChildAt(i);
if (v == null) {
System.out.println("View not found");
} else {
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i("","click");
}
});
}
}
}
}, 500);
}
}
スピナーがどのように動作する必要があるかを正確に教えてください。より良い解決策を見つけることができます。
実用的なソリューションは次のとおりです。
スピナーのOnClickListenerを設定する代わりに、OnTouchListenerとOnKeyListenerを設定しています。
spinner.setOnTouchListener(Spinner_OnTouch);
spinner.setOnKeyListener(Spinner_OnKey);
そしてリスナー:
private View.OnTouchListener Spinner_OnTouch = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
doWhatYouWantHere();
}
return true;
}
};
private static View.OnKeyListener Spinner_OnKey = new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
doWhatYouWantHere();
return true;
} else {
return false;
}
}
};
AndroidのSpinnerのクリックで何らかのアクションを実行する必要がある場合は常に、次の方法を使用します。
mspUserState.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
doWhatIsRequired();
}
return false;
}
});
上記のメソッドを使用している間は、常にFalseを返すことを忘れないでください。Trueその後、スピナーをクリックしてもスピナーのドロップダウン項目は表示されません。
個人的に、私はそれを使用します:
final Spinner spinner = (Spinner) (view.findViewById(R.id.userList));
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
userSelectedIndex = position;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
まず、スピナーはアイテムクリックイベントをサポートしていません。このメソッドを呼び出すと、例外が発生します。
SetOnItemSelectedListenerを使用できます。
Spinner s1;
s1 = (Spinner)findViewById(R.id.s1);
int selectionCurrent = s1.getSelectedItemPosition();
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
if (selectionCurrent != position){
// Your code here
}
selectionCurrent= position;
}
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {
// Your code here
}
});
Spinnerのすべてのイベントは、2つのタイプに分けられることをお勧めします。
ユーザーイベント(「クリック」イベントを意味します)。
プログラムイベント。
また、ユーザーイベントをキャッチする場合は、「プログラムイベント」を削除することをお勧めします。とても簡単です:
private void setSelectionWithoutDispatch(Spinner spinner, int position) {
AdapterView.OnItemSelectedListener onItemSelectedListener = spinner.getOnItemSelectedListener();
spinner.setOnItemSelectedListener(null);
spinner.setSelection(position, false);
spinner.setOnItemSelectedListener(onItemSelectedListener);
}
重要な瞬間があります:setSelection(position、false)が必要です。アニメーションパラメータの「false」は、すぐにイベントを発生させます。デフォルトの動作は、イベントをイベントキューにプッシュすることです。
SpinnerクラスはDialogInterface.OnClickListener
、標準を効果的にハイジャックView.OnClickListener
。
サブクラスのSpinnerを使用していない場合、または使用するつもりがない場合は、別の答えを選択してください。
それ以外の場合は、カスタムスピナーに次のコードを追加します。
@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
// [ Do anything you like here ]
return super.performClick();
}
例:スピナーが開かれるたびに、Snackbar経由で事前に提供されたヒントを表示します。
private String sbMsg=null; // Message seen by user when Spinner is opened.
public void setSnackbarMessage(String msg) { sbMsg=msg; }
@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
if (sbMsg!=null && !sbMsg.isEmpty()) { /* issue Snackbar */ }
return super.performClick();
}
カスタムスピナーは、プロジェクト全体でプログラムによってスピナーの外観を標準化するための素晴らしい出発点です。
興味があるなら、見栄えがいい here