New*_*ian 6 android user-interaction spinner onitemselectedlistener
我知道这个问题已经被回答过多次,但我没有发现任何一个令人满意,而且肯定不优雅。
问题是 OnItemSelected 不仅在用户选择某个项目时被触发,而且在以编程方式设置选择时也会被触发。
一些答案建议在程序员为微调器设置值时设置一个标志。然而,有时其他 Android 代码会在您的代码之外设置该值。
android 设置该值的常见位置是在微调器实例化时。一些答案解决了这个特定问题。然而,Android 有很多地方会崩溃并重新实例化旋转器。追踪所有这些人并不优雅。
所以问题是:如何将 OnItemSelectedListener 代码仅附加到用户与 UI 交互所做的选择?
下一步是扩展 Spinner 并开始覆盖方法,但这当然意味着弄乱 API(我不想这样做,或者我至少想让其他用户与我一起处理它)
所以我发布了一个答案,但欢迎任何批评、改进或其他更优雅的答案。
关键是重写 onClick 以设置一个标志,将 onItemSelectedListener 与用户交互联系起来并触发 onItemClickedListener。
如果您觉得使用 API setOnItemClickedListener 不舒服(也许是为了将来的兼容性),您当然可以替换您自己的方法。我只是觉得 onItemClickedListener 应该一直实现这种效果,所以这是我微妙的抗议。
另外,如果有人能想到 spinnerTouched 标志短路的原因(保持真实时间超过应有的时间),请告诉我们,以便解决该问题。不过到目前为止,它似乎运行得很好。
public class OnItemClickSpinner extends Spinner implements AdapterView.OnItemSelectedListener {
boolean spinnerTouched = false;
OnItemClickListener onItemClickListener = null;
OnItemSelectedListener onItemSelectedListener = null;
public OnItemClickSpinner(Context context) {
super(context);
super.setOnItemSelectedListener(this);
}
public OnItemClickSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
super.setOnItemSelectedListener(this);
}
public OnItemClickSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
super.setOnItemSelectedListener(this);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
spinnerTouched = true;
return super.onTouchEvent(event);
}
@Override
public void setOnItemClickListener(OnItemClickListener listener) {
onItemClickListener = listener;
}
@Override
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
this.onItemSelectedListener = onItemSelectedListener;
super.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(spinnerTouched && this.onItemClickListener!=null) this.onItemClickListener.onItemClick(parent,view,position,id);
if(this.onItemSelectedListener!=null) this.onItemSelectedListener.onItemSelected(parent,view,position,id);
spinnerTouched=false;
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
if(this.onItemSelectedListener!=null) this.onItemSelectedListener.onNothingSelected(parent);
spinnerTouched=false;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2115 次 |
| 最近记录: |