简介:
笔者查阅了大量资料,接口回调没有定义,可以理解为是一种设计思想。
其本质是将实现接口的类通过向上转型至接口类型,通过传入不同的子类,实现调用相应的子类重写的父类接口方法。
详情见:
例子:
有狗,猫,鸟三种动物,需要调用一个名为Animal 接口的call()方法。建立了三个类 dog类,cat类,bird类都实现Animal接口,且call()方法都不相同。现在三个类对应的三个实体都调用了接口的call()方法,需要让其实现不同的叫声。
代码实现:
public interface Animal {
public void call();
}
public class Dog implements Animal{
@override
public void call(){
//这里是Dog自己对接口方法的实现
...
...
}
}
public class Cat implements Animal{
@override
public void call(){
//这里是Cat自己对接口方法的实现
...
...
}
}
public class Bird implements Animal{
@override
public void call(){
//这里是Bird自己对接口方法的实现
...
...
}
}
public class Deal{
public void doSth(Animal animal){
animal.call();//此步骤需要用到接口animal的功能
//处理其他事务
... ...
}
}
//类Deal中用到了接口animal的功能,但是在定义时无法确定是哪一个实现Animal的子类,直接使用了接口Animal的句柄“Animal animal”,然后调用father的方法call()来处理,具体运行是再根据实例化对象调用相应的实现方法:
public static void main(String[] args){
Deal deal = new Deal();
Animal animalA = new Dog();
Animal animalB = new Cat();
Animal animalC = new Bird();
deal.doSth(animalA);//调用的是animalA对接口的实现
deal.doSth(animalB);//调用的是animalB对接口的实现
deal.doSth(animalC);//调用的是animalB对接口的实现
}
这就达到了具体实现与事务处理的解耦。在类Deal处理事务过程中不需要知道实现接口的子类,这样可以方便的扩充和维护代码,即设计模式的开闭原则(对扩展开放,对修改关闭)。上面的代码中,animalA、animalB、animalC都可以称为接口回调对象,它们虽然被声明为接口Animal类型,但是在实例化时却是实现的某个子类。
在Android中基于回调的事件处理机制使用场景有两个:
转载自:https://www.runoob.com/w3cnote/android-tutorial-callback-event-handle.html
当用户在GUI组件上激发某个事件时,组件有自己特定的方法会负责处理该事件 。
通常用法:
实现代码: MyButton.java
public class MyButton extends Button{
private static String TAG = "呵呵";
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
//重写键盘按下触发的事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode,event);
Log.i(TAG, "onKeyDown方法被调用");
return true;
}
//重写弹起键盘触发的事件
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
super.onKeyUp(keyCode,event);
Log.i(TAG,"onKeyUp方法被调用");
return true;
}
//组件被触摸了
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
Log.i(TAG,"onTouchEvent方法被调用");
return true;
}
}
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<example.jay.com.mybutton.MyButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮"/>
代码解析:
因为我们直接重写了Button的三个回调方法,当发生点击事件后就不需要我们在Java文件中进行 事件监听器的绑定就可以完成回调,即组件会处理对应的事件,即事件由事件源(组件)自身处理!
综上,就是如果是否向外传播取决于方法的返回值是时true还是false;
代码示例:
public class MyButton extends Button{
private static String TAG = "呵呵";
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
//重写键盘按下触发的事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode,event);
Log.i(TAG, "自定义按钮的onKeyDown方法被调用");
return false;
}
}
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<example.jay.com.mybutton.MyButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自定义按钮"
android:id="@+id/btn_my"/>
</LinearLayout>
MainActivity.java:
public class MyActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Button btn = (Button)findViewById(R.id.btn_my);
btn.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN)
{
Log.i("呵呵","监听器的onKeyDown方法被调用");
}
return false;
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
Log.i("呵呵","Activity的onKeyDown方法被调用");
return false;
}
}
运行截图:
结果分析: 从上面的运行结果,我们就可以知道,传播的顺序是: 监听器—>view组件的回调方法—>Activity的回调方法了;