`
445822357
  • 浏览: 735664 次
文章分类
社区版块
存档分类
最新评论

Android--自定义带点击事件监控的Spinner控件

 
阅读更多

Spinner是没有点击事件接口的,如果你用setOnClickListener(),程序将会发生运行时异常。一般情况下,无需监控Spinner的点击事件,因为默认的处理方式是点击Spinner出现列表对话框,而某些时候,我们是需要处理点击事件的,比如:我们想在点击Spinner时更新它的列表项,更新完毕之后才显示新的列表框。那么这种情况下用Spinner显然行不通,针对这种情况,我做了一个继承自Spinner含点击事件监控接口的子控件。

代码如下:

import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Spinner;

/**
 * 继承自Spinner的自定义下拉列表框。该下拉列表有如下特点:
 * <ol>
 * <li>使用{@link #setOnClickMyListener(OnClickMyListener)}可监控点击事件,并可自行实现点击后的响应动作(原来Spinner的响应动作是打开列表选择框)。</li>
 * <li>点击事件发生后,默认不再打开列表选择框,如需打开,请调用{@link #performClick()}</li>
 * </ol>
 * 该控件的目地在于弥补Spinner对于点击事件不能自定义响应的不足,Spinner对应点击的响应有自己的内在方案,
 * 对外屏蔽了{@link #setOnClickListener(OnClickListener)}接口, 
 * 如果我们需要在点击控件后列表选择框出现前做某些事情(如:更新列表),
 * 那么我们发现用Spinner根本无从下手,此控件弥补了这些不足。在监控到点击事件后,我们可执行一些动作,
 * 动作执行完毕,只需要手动使用{@link #performClick()}显示列表选择框即可。
 * <p />
 * 
 * The class inherited from Spinner. The drop-down list has the following characteristics:
 * <ol>
 * <li> Use {@link #setOnClickMyListener(OnClickMyListener)} to listen the click event and can implement self-fulfilling click response action (Spinner's default response action is to open the list selection box). </ li>
 * <li> Click event occurs, the default response is no longer open the list selection box, please call {@link #performClick()} instead. </ li>
 * </ol>
 * The purpose of the control is to compensate for that Spinner click event can not be caught, the Spinner has its own solution with the click event response, 
 * and {@link #setOnClickListener(OnClickListener)} interface is shielded, 
 * if we need to do something (such as update list) after click event happened and before the list selection box appears,
 * we'll find no way, but ClickControlledSpinner did, it listens the click event, can let us perform some actions after this,
 * after actions finished, we must revoke {@link #performClick()} to display the list selection box.
 * 
 * @date 2012/08/24
 * @author Wison Xu
 */
public class ClickControlledSpinner extends Spinner {

	public ClickControlledSpinner(Context context) {
		super(context);
	}

	public ClickControlledSpinner(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public ClickControlledSpinner(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	private boolean isMoved = false;
	private Point touchedPoint = new Point();
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int x = (int) event.getRawX();
		int y = (int) event.getRawY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			touchedPoint.x = x;
			touchedPoint.y = y;
			break;
		case MotionEvent.ACTION_MOVE:
			isMoved = true;
			break;
		case MotionEvent.ACTION_UP:
			if (isMoved) {
				// 从上向下滑动
				if (y - touchedPoint.y > 20) {
				} 
				// 从下向上滑动
				else if (touchedPoint.y - y > 20) {
				}
				// 滑动幅度小时,当作点击事件
				else {
					onClick();
				}
				isMoved = false;
			} else {
				onClick();
			}
			break;
		default:
			break;
		}
		return true;
	}
	
	private void onClick() {
		if (onClickMyListener != null && isEnabled()) {
			// use a thread to do something which maybe spend many times.
			new Thread() {
				public void run() {
					onClickMyListener.onClick();
				}
			}.start();
		}
	}

	
	private OnClickMyListener onClickMyListener;
	
	/**
	 * 注册自定义的点击事件监听
	 * Register the click event self-fulfilling listener.
	 * @param onClickMyListener
	 */
	public void setOnClickMyListener(OnClickMyListener onClickMyListener) {
		this.onClickMyListener = onClickMyListener;
	}
	
	/**
	 * 自定义点击事件监听.
	 * Click event self-fulfilling listener.
	 * @author Wison Xu
	 */
	public interface OnClickMyListener {
		/**
		 * 点击时触发
		 * 警告:该方法在非UI线程中执行
		 * 
		 * Triggers when click event occurs.
		 * Warning: this method does not run in UI thread.
		 */
		public void onClick() ;
	}
}





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics