当再次选择当前选定的项目时,如何在Android Spinner中获取事件?
我已经为微调器编写了一个setOnItemSelectedListener,以便在微调器项更改时作出响应。我的要求是,当我再次单击当前选定的项目时,应该会显示一个祝酒词。如何获得此活动?再次单击当前选定的项目时,微调器没有响应。`当再次选择当前选定的项目时,如何在Android Spinner中获取事件?,android,Android,我已经为微调器编写了一个setOnItemSelectedListener,以便在微调器项更改时作出响应。我的要求是,当我再次单击当前选定的项目时,应该会显示一个祝酒词。如何获得此活动?再次单击当前选定的项目时,微调器没有响应。` StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){ @Override public void onItemSe
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
试试这个
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
if(v.hasFocus() {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
}
希望它能起作用。我发现,如果在微调器中再次选择同一项,则不会调用OnItemSelectedListener。当我单击微调器并再次选择相同的值时,则不会调用OnItemSelectedListener方法。如果人们单击根据UI设计已经处于活动状态的选择,他们不会期望发生什么 当您再次单击当前选定的项目时,它将无法触发任何事件。因此,您无法捕获用于微调器响应的setOnItemSelectedListener 此微调器将始终告诉您选择已更改:
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
package com.mitosoft.ui.widgets;
import java.lang.reflect.Method;
import android.content.Context;
import android.content.DialogInterface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.AdapterView;
import android.widget.Spinner;
//com.mitosoft.ui.widgets.NoDefaultSpinner
public class NoDefaultSpinner extends Spinner {
private int lastSelected = 0;
private static Method s_pSelectionChangedMethod = null;
static {
try {
Class noparams[] = {};
Class targetClass = AdapterView.class;
s_pSelectionChangedMethod = targetClass.getDeclaredMethod("selectionChanged", noparams);
if (s_pSelectionChangedMethod != null) {
s_pSelectionChangedMethod.setAccessible(true);
}
} catch( Exception e ) {
Log.e("Custom spinner, reflection bug:", e.getMessage());
throw new RuntimeException(e);
}
}
public NoDefaultSpinner(Context context) {
super(context);
}
public NoDefaultSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoDefaultSpinner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void testReflectionForSelectionChanged() {
try {
Class noparams[] = {};
s_pSelectionChangedMethod.invoke(this, noparams);
} catch (Exception e) {
Log.e("Custom spinner, reflection bug: ", e.getMessage());
e.printStackTrace();
}
}
@Override
public void onClick(DialogInterface dialog, int which) {
super.onClick(dialog, which);
if(lastSelected == which)
testReflectionForSelectionChanged();
lastSelected = which;
}
}
@迪米特尔。哇,太棒了。谢谢你。我不能给你的解决方案投票(分数不够),但是NoDefaultSpinner类可以工作。只有一件事是个问题:因为您调用super.onClick,然后在“onClick”中调用testReflectionForSelectionChanged(),所以如果选择确实发生了更改,您将获得两次调用微调器的onItemSelected处理程序(而如果重新选择相同的项,则功能是正确的)。我通过破解解决了这个问题。我添加了一个onTouchEvent覆盖,记录了被触摸的项目,然后在“onClick”中检查是否发生了更改:
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
您好&感谢@Dimitar为这个问题提供了创造性的答案。我已经试过了,它在旧的Android版本(如2.x)上运行得很好,但不幸的是,它在3.0和更高版本(试过3.2和4.0.3)上不起作用。由于某些原因,在较新的平台上从未调用过onClick方法。有人在这里为此编写了错误报告:
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
不能在较新的平台上运行意味着我需要一个不同的解决方案。在我的应用程序中,模拟一个未选择的微调器,在开始时有一个隐藏的“虚拟”条目就足够了。然后,如果将“隐藏”项设置为选择项,则单击的每个项都将导致回调。对于某些人来说,一个缺点可能是不会显示任何选定项,但可以使用微调器类覆盖技巧来修复
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
请参阅了解更新的平台,尝试将此添加到Dimitar的解决方案中。我认为它有效:)
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
(您必须重写onLayout并删除onClick方法)
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
我花了好几个小时试图找到解决这个问题的方法。我的结论如下。我不确定它是否在所有情况下都有效,但它似乎对我有效。它只是Spinner类的扩展,它检查选择并在选择设置为相同值时调用侦听器
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Spinner;
/** Spinner extension that calls onItemSelected even when the selection is the same as its previous value */
public class NDSpinner extends Spinner {
public NDSpinner(Context context)
{ super(context); }
public NDSpinner(Context context, AttributeSet attrs)
{ super(context, attrs); }
public NDSpinner(Context context, AttributeSet attrs, int defStyle)
{ super(context, attrs, defStyle); }
@Override
public void setSelection(int position, boolean animate) {
boolean sameSelected = position == getSelectedItemPosition();
super.setSelection(position, animate);
if (sameSelected) {
// Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
}
}
@Override
public void setSelection(int position) {
boolean sameSelected = position == getSelectedItemPosition();
super.setSelection(position);
if (sameSelected) {
// Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
}
}
}
试试这个
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
公共类MySpinner扩展微调器{
我选择了一个听者;
公共MySpinner(上下文、属性集属性)
{
超级(上下文,attrs);
}
@凌驾
公共选举(内部职位)
{
超级选举(职位);
if(position==getSelectedItemPosition())
{
listener.onItemSelected(null,null,position,0);
}
}
public void setOnItemSelectedListener(OnItemSelectedListener侦听器)
{
this.listener=listener;
}
}
我想我应该给那些使用较新Android版本的人留下一个更新的答案
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
我根据上述答案编译了一个函数,它至少适用于4.1.2和4.3(我测试的设备)。此函数不使用反射,而是跟踪最后选择的索引本身,因此即使SDK更改了类彼此扩展的方式,也应该可以安全使用
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
import android.content.Context;
import android.util.AttributeSet;
import android.widget.Spinner;
public class SelectAgainSpinner extends Spinner {
private int lastSelected = 0;
public SelectAgainSpinner(Context context)
{ super(context); }
public SelectAgainSpinner(Context context, AttributeSet attrs)
{ super(context, attrs); }
public SelectAgainSpinner(Context context, AttributeSet attrs, int defStyle)
{ super(context, attrs, defStyle); }
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(this.lastSelected == this.getSelectedItemPosition() && getOnItemSelectedListener() != null)
getOnItemSelectedListener().onItemSelected(this, getSelectedView(), this.getSelectedItemPosition(), getSelectedItemId());
if(!changed)
lastSelected = this.getSelectedItemPosition();
super.onLayout(changed, l, t, r, b);
}
}
我的解决方案基于benoffi7的MySpinner。通过保存上次选择的父项和视图,修复了在同一项选择上传递空值的问题
StorageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView adapter, View v, int i, long lng) {
Toast.makeText(getApplicationContext(), (CharSequence) StorageSpinner.getSelectedItem(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView arg0) {
Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
}
});
public class MySpinner extends Spinner {
private OnItemSelectedListener listener;
private AdapterView<?> lastParent;
private View lastView;
private long lastId;
public MySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
initInternalListener();
}
public MySpinner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initInternalListener();
}
private void initInternalListener() {
super.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
lastParent = parent;
lastView = view;
lastId = id;
if (listener != null) {
listener.onItemSelected(parent, view, position, id);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
//lastParent = parent; // do we need it?
if (listener != null) {
listener.onNothingSelected(parent);
}
}
});
}
@Override
public void setSelection(int position) {
if (position == getSelectedItemPosition() && listener != null) {
listener.onItemSelected(lastParent, lastView, position, lastId);
} else {
super.setSelection(position);
}
}
@Override
public void setOnItemSelectedListener(OnItemSelectedListener listener) {
this.listener = listener;
}
}
公共类MySpinner扩展微调器{
私密的被选中的监听器;
私人AdapterView lastParent;
私有视图;
私人长拉斯蒂德;
公共MySpinner(上下文、属性集属性){
超级(上下文,attrs);
initInternalListener();
}
公共MySpinner(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
initInternalListener();
}
私有void initInternalListener(){
super.setOnItemSelectedListener(新的OnItemSelectedListener(){
@凌驾
已选择公共视图(AdapterView父视图、视图、,
内部位置,长id){
lastParent=父对象;
lastView=视图;
lastId=id;
if(侦听器!=null){
listener.onItemSelected(父级、视图、位置、id);
}
}
@凌驾
未选择公共无效(AdapterView父级){
//lastParent=parent;//我们需要它吗?
if(侦听器!=null){
listener.onNothingSelected(父级);
}
}
});
}
@凌驾
公共选举(内部职位){
if(position==getSelectedItemPosition()&&listener!=null){
listener.onItemSelected(lastParent、lastView、position、lastId);
}否则{
超级选举(职位);
}
}
@凌驾
public void setOnItemSelectedListener(OnItemSelectedListener侦听器){
this.listener=listener;
}
}
如果您确实想在微调器显示时在XML中执行此任务,请添加一个编辑文本并设置可见性属性;并在view.onclicklisner上为微调器和服装内适配器集创建服装适配器,然后单击事件激发EditText.setText(“0”);在活动集edittext textWatcher事件和事件块中,添加OnSpinerItem Ev
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatSpinner
class MoreSpinner : AppCompatSpinner {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun setSelection(position: Int, animate: Boolean) {
val sameSelected = position == selectedItemPosition
super.setSelection(position, animate)
if (sameSelected) {
onItemSelectedListener?.onItemSelected(
this,
selectedView,
position,
selectedItemId
)
}
}
override fun setSelection(position: Int) {
val sameSelected = position == selectedItemPosition
super.setSelection(position)
if (sameSelected) {
onItemSelectedListener?.onItemSelected(
this,
selectedView,
position,
selectedItemId
)
}
}
}