Android View的onClick回调机制

本文将解析Android View的onClick事件的回调机制,通过这个设计,可以明白接口和对象组合是非常重要的。记得我们在写Button的onClick事件是往往会这样来写:

button.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
				
	}
});


为什么要这样写呢?我在点击button时为什么能调用到Override的onClick方法? 如果java面向对象基础没学好的话,还真是想不明白,比如像我一样。不得不看源码才知道,到底是怎样一会事儿。穿梭在源码中是件非常快乐的事情,第一:SDK编码风格很规范,看起来舒坦!第二:注释写得很精。好现在来分析一下是怎么实现回调的,这里我就用我写的一个小程序来说明:

首先定义个类,姑且就叫它BaseView,跟Android SDK里面的View对应

package com.example.callbacktest;

public class BaseView {
	interface OnClickMyListener {
		public void onClick(BaseView view);
	};
}
该类里面有个内部接口,叫OnClickMyListener在,这与Android SDK中OnClickListener对应。接下来写两个BaseView的子类ViewA、ViewB

package com.example.callbacktest;

public class ViewA extends BaseView{
	private OnClickMyListener mLinstener ;
	
	public void click(){
		mLinstener.onClick(this);
	}
	
	public void setOnClickMyListener(OnClickMyListener linstener){
		mLinstener = linstener ;
	}
}

package com.example.callbacktest;

public class ViewB extends BaseView{
	private OnClickMyListener mLinstener ;
	
	public void click(){
		mLinstener.onClick(this);
	}
	
	public void setOnClickMyListener(OnClickMyListener linstener){
		mLinstener = linstener ;
	}
}


在主类中这样来调用:

package com.example.callbacktest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ViewA viewA = new ViewA();
		ViewB viewB = new ViewB();
		
		viewA.setOnClickMyListener(new BaseView.OnClickMyListener() {
			@Override
			public void onClick(BaseView view) {
				Log.e("MainActivity","viewA-->onClick");
			}
		});
		
		viewB.setOnClickMyListener(new BaseView.OnClickMyListener() {
			@Override
			public void onClick(BaseView view) {
				Log.e("MainActivity","viewB-->onClick");
			}
		});
		
		Log.e("MainActivity","now click A:");
		viewA.click();
		Log.e("MainActivity","now click B:");
		viewB.click();
	}
}

现在来说一下这个流程,首先在View中定义一个接口,接口中的方法就是回调方法,即onClick(BaseView view),这个方法的参数是BaseView类型,也就是说凡是继承自BaseView的子类并且需要用这个接口来实例化回调监听器的类都可以响应这个回调方法。就像这里的ViewA、ViewB一样,这相当于Android SDK里面的Button或ImageView等等,他们都是继承自View,并且需要OnClickListener去实例化onClick事件监听器。

这里的ViewA、ViewB有自己的click方法,这个方法按理由来说不应该在主程序中主动调用,这个方法应该是屏幕捕捉到一个点击屏幕的动作之后转换成坐标,如果这个坐标对应的是该View,那么才调用它的click方法,也就是说是屏幕获取点击事件,来触发View的click事件,进而调用了事件监听器的onClick方法,而onClick方法是在外部实现的,所以就会调用onClick里面的打印信息。这就是整个调用的流程。



你可能感兴趣的:(android)