接口回调与方法回调

1.1 接口回调

简介:
笔者查阅了大量资料,接口回调没有定义,可以理解为是一种设计思想。
其本质是将实现接口的类通过向上转型接口类型,通过传入不同的子类,实现调用相应的子类重写的父类接口方法
详情见:https://blog.csdn.net/qq_43530326/article/details/126261199?spm=1001.2014.3001.5501

什么是方法回调?

是将功能定义与功能分开的一种手段,一种解耦合的设计思想;
在Java中回调是通过接口来实现的,。不同的用户调用同一种方法可以满足其对应的不用需求。

例子:

有狗,猫,鸟三种动物,需要调用一个名为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类型,但是在实例化时却是实现的某个子类。

1.2 Android回调的事件处理机制详解

在Android中基于回调的事件处理机制使用场景有两个:

转载自:https://www.runoob.com/w3cnote/android-tutorial-callback-event-handle.html

1.2.1自定义view

当用户在GUI组件上激发某个事件时,组件有自己特定的方法会负责处理该事件 。

通常用法:

  1. 继承基本的GUI组件。
  2. 重写该组件的事件处理方法,即自定义view 。
    注意:在xml布局中使用自定义的view时,需要使用"全限定类名"

实现代码: 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文件中进行 事件监听器的绑定就可以完成回调,即组件会处理对应的事件,即事件由事件源(组件)自身处理!

1.2.2基于回调的事件传播

img

综上,就是如果是否向外传播取决于方法的返回值是时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;  
    }  
} 

运行截图:

img

结果分析: 从上面的运行结果,我们就可以知道,传播的顺序是: 监听器—>view组件的回调方法—>Activity的回调方法了;

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值