ath*_*hos 28 android android-widget android-spinner
当我创建我的活动时,我设置了一个Spinner,为它分配一个监听器和一个初始值.我知道onItemSelected在应用程序初始化期间会自动调用回调.我觉得很奇怪的是,当设备旋转时会发生两次这种情况,这会导致我遇到一些问题,我不得不绕过它.如果微调器初始选择为零,则不会发生这种情况.我能够隔离问题,这是触发它的最简单的活动:
public class MainActivity extends Activity implements OnItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("Test","Activity onCreate");
setContentView(R.layout.activity_main);
((Spinner)findViewById(R.id.spinner1)).setSelection(2);
((Spinner)findViewById(R.id.spinner1)).setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> spin, View selview, int pos, long selId)
{
Log.i("Test","spin:"+spin+" sel:"+selview+" pos:"+pos+" selId:"+selId);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {}
}
Run Code Online (Sandbox Code Playgroud)
这是启动应用程序然后旋转设备时显示的logcat:
I/Test( 9881): spin:android.widget.Spinner@4052f508 sel:android.widget.TextView@40530b08 pos:2 selId:2
I/Test( 9881): Activity onCreate
I/Test( 9881): spin:android.widget.Spinner@40535d80 sel:android.widget.TextView@40538758 pos:2 selId:2
I/Test( 9881): spin:android.widget.Spinner@40535d80 sel:android.widget.TextView@40538758 pos:2 selId:2
Run Code Online (Sandbox Code Playgroud)
这是预期的行为吗?我错过了什么吗?
Rap*_*ira 46
管理在另一个stackoverflow问题中找到解决方案:
spinner.post(new Runnable() {
public void run() {
spinner.setOnItemSelectedListener(listener);
}
});
Run Code Online (Sandbox Code Playgroud)
小智 20
通常,似乎有许多事件触发onItemSelected调用,并且很难跟踪所有事件.此解决方案允许您仅使用OnTouchListener响应用户启动的更改.
为微调器创建监听器:
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) {
// Your selection handling code here
userSelect = false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
将侦听器作为OnItemSelectedListener和OnTouchListener添加到微调器:
SpinnerInteractionListener listener = new SpinnerInteractionListener();
mSpinnerView.setOnTouchListener(listener);
mSpinnerView.setOnItemSelectedListener(listener);
Run Code Online (Sandbox Code Playgroud)
只需在设置侦听器之前使用 setSelection(#, false) :
@Override
protected void onCreate(Bundle savedInstanceState) {
...
spinner.setSelection(2, false);
spinner.setOnItemSelectedListener(this);
}
Run Code Online (Sandbox Code Playgroud)
关键是第二个参数。它说不要为过渡设置动画,立即执行操作并防止 onItemSelected 被触发两次,因为系统已经进行了调用。
第一次onItemSelected运行时,view尚未充气。第二次它已经膨胀了。解决方案是将方法onItemSelected用if (view != null).
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (view != null) {
//do things here
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11726 次 |
| 最近记录: |