Spinner(3): OnItemSelectedListener 触发时机

本文深入探讨了Android中Spinner组件的各种事件触发机制,包括OnItemSelectedListener、OnTouchListener及OnFocusChangeListener的使用场景与注意事项。通过实例演示了不同情况下的事件响应行为。

博客 Spinner(1): 由SDK引发的问题Spinner(2): 动态添加资源 简单介绍了spinner,但是 Spinner 还有陷阱,所以使用时应该注意。

本篇博客继续探讨Spinner及其注意事项,欢迎拍砖。

 


推荐一个网站,关于人工智能教程,教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点 这里 可以跳转到教程。


 

为 Spinner 设置 OnItemSelectedListener、OnTouchListener、OnFocusChangeListener 事件,看看在什么情况下触发这些事件。

 

看代码,如下:

package mark.zhang;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;

public class SpinnerTestActivity extends Activity {
	private static final String[] strArrays = {"w" , "x", "y", "z"};
	private Spinner mSpinner;
	private ArrayAdapter<String> adapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mSpinner = (Spinner) findViewById(R.id.mySpinner);
		adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, strArrays);
		// 自定义spinner下拉样式
		adapter.setDropDownViewResource(R.layout.myspinner_dropdown);
		mSpinner.setAdapter(adapter);
		// 设置选择条目事件
		mSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {

					@Override
					public void onItemSelected(AdapterView<?> arg0, View arg1,
							int arg2, long arg3) {
						Log.d("mark", "onItemSelected() is invoked!");
						arg0.setVisibility(View.VISIBLE);
					}

					@Override
					public void onNothingSelected(AdapterView<?> arg0) {
					}
				});
		// 设置触摸事件监听
		mSpinner.setOnTouchListener(new Spinner.OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				Log.d("mark", "onTouch() is invoked!");
				v.setVisibility(View.INVISIBLE);
				return false;
			}
		});
		// 设置焦点变化事件监听
		mSpinner.setOnFocusChangeListener(new Spinner.OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				Log.d("mark", " onFocusChange() is invoked!");
			}
		});
	}
}

代码中,创建 ArrayAdapter 对象的同时,为 spinner 添加备选项目:

 

 

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, strArrays);

直接运行该 Android project,看看效果:

 

 

D/mark    ( 1799): onItemSelected() is invoked!

 

 

 

 

 

注意:此时spinner中有默认显示值。

 

可以看出,OnItemSelectedListener 监听事件 onItemSelected 被调用。这就很让人奇怪,根本没有点击 Spinner,为何会触发该事件呢???

 

如果您好奇的话,跟我一起测试吧!

 

这样来创建ArrayAdapter对象:

 

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);

运行,没有任何信息出现。说明此时没有触发上述的任何监听器设置的监听器。

 

 

 

 

 

注意:此时 spinner 中没有任何默认显示值。

 

再做一个测试,修改代码如下:

 

adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
for(int i = 0; i<5; i++) {
	adapter.add("mark" + i);
}

运行:

 

 

D/mark    ( 5890): onItemSelected() is invoked!

 

 

 

 

 

呵呵,OnItemSelectedListener 监听事件 onItemSelected 被调用。

 

当我们点击 Spinner 的下拉列表时,一定会触发 OnTouchListener的onTouch 事件。但是不一定会触发 OnItemSelectedListener的onItemSelected 事件。

 

如果,当前 Spinner 的默认显示是 mark0,那么再次点击 mark0 的话,打印结果:

 

D/mark    ( 5890): onTouch() is invoked!
D/mark    ( 5890): onTouch() is invoked!

可以看出,OnItemSelectedListener 的 onItemSelected 事件没有被触发,但是 OnTouchListener的onTouch 事件被触发两次。

 

如果,你点击选项列表的其它值如 mark1,打印结果:

 

D/mark    ( 5890): onTouch() is invoked!
D/mark    ( 5890): onTouch() is invoked!
D/mark    ( 5890): onItemSelected() is invoked!

呵呵,很戏剧化!

 

最后一个问题,何时触发 OnFocusChangeListener 事件,很简单,运行 App 之后,随便改变当前焦点,就会触发该事件。

 

知道这样的结果之后,很无语!但是知道总比不知道好,至少您可以采取一点措施来避免一些不必要的麻烦。

 

比如,每次都想获取 spinner 的值,就可以为其绑定 onTouch 事件(因为该事件每次点击都会被触发),但是注意,点击 spinner 一次,会触发该事件很多次(touch 包括很多动作如 down、up、move),那麽我们就在 event 事件的 down 事件里面写我们的代码。即按下有效,up、move 等无效即可。

 

评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值