本文将解析Android View的onClick事件的回调机制,通过这个设计,可以明白接口和对象组合是非常重要的。记得我们在写Button的onClick事件是往往会这样来写:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } });
首先定义个类,姑且就叫它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(); } }
这里的ViewA、ViewB有自己的click方法,这个方法按理由来说不应该在主程序中主动调用,这个方法应该是屏幕捕捉到一个点击屏幕的动作之后转换成坐标,如果这个坐标对应的是该View,那么才调用它的click方法,也就是说是屏幕获取点击事件,来触发View的click事件,进而调用了事件监听器的onClick方法,而onClick方法是在外部实现的,所以就会调用onClick里面的打印信息。这就是整个调用的流程。