Android 中的接口回调
在android中,接口回调是一种很常见的机制,它可以大大降低代码间耦合性,提高程序的复用性。我们经常碰到的点击事件就是利用的接口回调机制。
什么是接口回调
接口回调其本质与向上转型是一样的,不同的是:接口回调是利用接口句柄来得到并调用实现这个接口的子类引用;而向上转型则是用父类的句柄来得到并调用继承此类的子类的引用。接口回调,强调使用接口来实现回调对象方法,它并不关心方法的具体实现,而向上转型则牵涉到多态和运行期绑定。
为什么要使用接口回调
接口回调和java设置模式里面的模板方法模式(Template Method)有点类似,当我们不知道调用者具体要干什么的时候,我们只需要暴露出对应的接口或者抽象方法,让他们自己去实现方法就好的,所以说,接口回调能提高代码的复用性,降低耦合性。
如何实现接口回调
下面就简单的说说接口回调的思路:
首先创建一个接口,这个接口用于你在某个情景下执行相应的操作
public interface Test { //接口方法 public void doSomething(); }
创建一个功能类,然后,在这个类里面声明回调接口的对象,之后在这个类里面创建在某个情景下需要执行的方法,而且在这个方法里面为声明的接口对象赋值。
public class Function { //声明接口对象 Test onTest; public void setOnTest(Test onTest) { this.onTest = onTest; } public void show(){ if (onTest!=null) { onTest.doSomething(); } } }
还有一种方式,就是不声明接口对象,直接将接口对象以参数的形式传进去
public class Function { public void show(Test onTest){ if (onTest != null) { onTest.doSomething(); } } }
在其他的类中使用这个功能类就可以了。这里我们在MainActivity里面来进行测试,在布局文件中写了一个Button和TextView,当点击不同控件的时候进行不同操作。
布局文件:<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" android:orientation="vertical"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:padding="15dp" android:background="#00ffff" android:text="TextView" /> <Button android:id="@+id/bt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" />
MainActivity.java
public class MainActivity extends Activity implements OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.tv); Button bt = (Button) findViewById(R.id.bt); tv.setOnClickListener(this); bt.setOnClickListener(this); } @Override public void onClick(View v) { Function function =new Function(); switch (v.getId()) { //以第一种方式指定点击后执行的具体事件 case R.id.tv: //设置接口对象 function.setOnTest(new Test() { //被点击后要执行的具体事件 @Override public void doSomething() { Toast.makeText(MainActivity.this, "TextView被点击了", 0).show(); } }); //调用功能类里面的方法 function.show(); break; case R.id.bt: //以第二种方式指定点击后执行的具体事件 function.show(new Test() { @Override public void doSomething() { Toast.makeText(MainActivity.this, "Button被点击了", 0).show(); } }); break; } } }