1.1 接口回调
简介: 笔者查阅了大量资料,接口回调没有定义,可以理解为是一种设计思想。
什么是方法回调?
是将功能定义与功能分开的一种手段,一种解耦合的设计思想; 在Java中回调是通过接口来实现的,。不同的用户调用同一种方法可以满足其对应的不用需求。
例子:
有狗,猫,鸟三种动物,需要调用一个名为Animal 接口的call()方法。建立了三个类 dog类,cat类,bird类都实现Animal接口,且call()方法都不相同。现在三个类对应的三个实体都调用了接口的call()方法,需要让其实现不同的叫声。
代码实现:
public interface Animal {
public void call();
}
public class Dog implements Animal{
@override
public void call(){
...
...
}
}
public class Cat implements Animal{
@override
public void call(){
...
...
}
}
public class Bird implements Animal{
@override
public void call(){
...
...
}
}
public class Deal{
public void doSth(Animal animal){
animal.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);
deal.doSth(animalB);
deal.doSth(animalC);
}
这就达到了具体实现与事务处理的解耦。在类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组件上激发某个事件时,组件有自己特定的方法会负责处理该事件 。
通常用法:
- 继承基本的GUI组件。
- 重写该组件的事件处理方法,即自定义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基于回调的事件传播
综上,就是如果是否向外传播取决于方法的返回值是时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的回调方法了;
|