Java 在 Android 中设置微调器 onClickListener()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3928071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting a spinner onClickListener() in Android
提问by blindstuff
I'm trying to get an onClickListener to fire on a Spinner, but I get the following error:
我试图让 onClickListener 在 Spinner 上触发,但出现以下错误:
Java.lang.RuntimeException is "Don't call setOnClickListener for an AdapterView. You probably want setOnItemClickListener instead,"
Java.lang.RuntimeException 是“不要为 AdapterView 调用 setOnClickListener。你可能想要 setOnItemClickListener,”
I'm sure I want to call onClickListener and NOT onItemClickListener. I found a question asked by someone else on Stack Overflow, Is there a way to use setOnClickListener with an Android Spinner?
我确定我想调用 onClickListener 而不是 onItemClickListener。我在 Stack Overflow 上发现了其他人提出的一个问题,有没有办法将 setOnClickListener 与 Android Spinner 一起使用?
The answer stated there is:
那里说的答案是:
You will have to set the Click listener on the underlying view (normally a TextView with id: android.R.id.text1) of the spinner. To do so:
Create a custom Spinner In the constructor (with attributes) create the spinner by supplying the layout android.R.layout.simple_spinner_item Do a findViewById(android.R.id.text1) to get the TextView Now set the onClickListener to the TextView
您必须在微调器的底层视图(通常是带有 id: android.R.id.text1 的 TextView)上设置 Click 侦听器。这样做:
创建自定义微调器在构造函数(带有属性)中通过提供布局来创建微调器 android.R.layout.simple_spinner_item 执行 findViewById(android.R.id.text1) 以获取 TextView 现在将 onClickListener 设置为 TextView
I have tried the answer noted there, but it doesn't seem to work. I get a null pointer to the TextView after I do the findViewById().
我已经尝试了那里提到的答案,但它似乎不起作用。在执行 findViewById() 后,我得到一个指向 TextView 的空指针。
This is what I'm doing:
这就是我正在做的:
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
}
});
}
File layoutspinner.xml
文件 layoutspinner.xml
<?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"/>
What am I doing wrong?
我究竟做错了什么?
I'm new to Stack Overflow, I didn't find any way to post an aditional question to the other thread (or comment since I have to little rep) so I started a new question.
我是 Stack Overflow 的新手,我没有找到任何方法向另一个线程发布附加问题(或评论,因为我的代表很少)所以我开始了一个新问题。
Per recomendation I tried this:
根据推荐,我试过这个:
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
}
});
}
}
But LogCatisn't showing promising results.
但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
I have tested this on API levels 7 and 8 with the same results.
我已经在 API 级别 7 和 8 上对此进行了测试,结果相同。
采纳答案by Dave.B
The following works how you want it, but it is not ideal.
以下工作如何你想要它,但它并不理想。
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);
}
}
Let me know exactly how you need the spinner to behave, and we can work out a better solution.
让我确切地知道您需要微调器的行为方式,我们可以制定出更好的解决方案。
回答by OferR
Here is a working solution:
这是一个有效的解决方案:
Instead of setting the spinner's OnClickListener, we are setting OnTouchListener and OnKeyListener.
我们没有设置微调器的 OnClickListener,而是设置 OnTouchListener 和 OnKeyListener。
spinner.setOnTouchListener(Spinner_OnTouch);
spinner.setOnKeyListener(Spinner_OnKey);
and the listeners:
和听众:
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;
}
}
};
回答by sumit pandey
First of all, a spinner does not support item click events. Calling this method will raise an exception.
首先,微调器不支持项目点击事件。调用此方法将引发异常。
You can use setOnItemSelectedListener:
您可以使用 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
}
});
回答by Gaurav Arora
Whenever you have to perform some action on the click of the Spinner in Android, use the following method.
每当您必须在 Android 中对 Spinner 的点击执行某些操作时,请使用以下方法。
mspUserState.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
doWhatIsRequired();
}
return false;
}
});
One thing to keep in mind is always to return Falsewhile using the above method. If you will return Truethen the dropdown items of the spinner will not be displayed on clicking the Spinner.
要记住的一件事是在使用上述方法时始终返回False。如果您将返回True,则在单击微调器时不会显示微调器的下拉项。
回答by Lumi
Personally, I use that:
就个人而言,我使用的是:
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) {
}
});
回答by Slava
I suggest that all events for Spinner are divided on two types:
我建议 Spinner 的所有事件都分为两种类型:
User events (you meant as "click" event).
Program events.
用户事件(您的意思是“点击”事件)。
节目活动。
I also suggest that when you want to catch user event you just want to get rid off "program events". So it's pretty simple:
我还建议,当您想捕获用户事件时,您只想摆脱“程序事件”。所以这很简单:
private void setSelectionWithoutDispatch(Spinner spinner, int position) {
AdapterView.OnItemSelectedListener onItemSelectedListener = spinner.getOnItemSelectedListener();
spinner.setOnItemSelectedListener(null);
spinner.setSelection(position, false);
spinner.setOnItemSelectedListener(onItemSelectedListener);
}
There's a key moment: you need setSelection(position, false). "false" in animation parameter will fire event immediately. The default behaviour is to push event to event queue.
有一个关键时刻:您需要 setSelection(position, false)。动画参数中的“false”将立即触发事件。默认行为是将事件推送到事件队列。
回答by Bad Loser
The Spinner class implements DialogInterface.OnClickListener
, thereby effectively hiHymaning the standard View.OnClickListener
.
Spinner 类实现DialogInterface.OnClickListener
,从而有效地劫持了标准View.OnClickListener
。
If you are not using a sub-classed Spinner or don't intend to, choose another answer.
如果您不使用子类 Spinner 或不打算使用,请选择另一个答案。
Otherwise just add the following code to your custom Spinner:
否则只需将以下代码添加到您的自定义微调器:
@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
// [ Do anything you like here ]
return super.performClick();
}
Example: Display a pre-supplied hint via Snackbar whenever the Spinner is opened:
示例:每当打开 Spinner 时,通过 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();
}
A custom Spinner is a terrific starting point for programmatically standardising Spinner appearance throughout your project.
自定义 Spinner 是在整个项目中以编程方式标准化 Spinner 外观的绝佳起点。
If interested, looky here
如果有兴趣,请看这里