“回调/回调方法”这个词语对我们程序员来说肯定不陌生。在Android的学习及开发过程中,我们经常会听到也会用到“回调(回调方法)”这个词,那么什么是回调呢:在类A中定义了一个方法,这个方法中用到了一个接口(Interface)和该接口中的方法,但是这个方法方法没有具体的实现,需要在类B中去实现,类B实现该方法具体业务处理后,再传递给A类,供A类去调用,这种机制就称为回调。A来B去听起来有点拗口,下面我们用个简单的例子来实现。
我们在Activity中定义了一个ListView列表,列表的每一Item上有一个按钮Button,我们本可以在ListView的适配器类中直接实现Button的点击事件,但是我们没有,我们而是定义了个接口(Interface),调用接口中定义的方法,而方法本身是在Activity中实现的,再传递给ListView的Item,就实现了对Item上Button的点击事件。为什么可以直接在适配器为右点击操作,又何要无缘无故增加接口呢?一般情况下我们不需要这样操作,但很多时候我们要对数据进行灵活处理,如果直接在Item中实现点击的话达不到效果,用回调操作就显示很方便。简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
------------------小例子之xml-----------------------------------
<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"
android:background="#f0f0f0" >
<ListView
android:id="@+id/test_lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
android:scrollbars="none">
</ListView>
</RelativeLayout>
--------------------listView的item布局----------------------
<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="wrap_content"
android:background="#ffffff" >
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="10dp" />
<Button
android:id="@+id/item_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_marginRight="10dp"
android:text="点击我" />
</RelativeLayout>
--------------------Activity-------------------------------------------
public class MainActivity extends ActionBarActivity implements ITestImpl {
private ListView mTestLv;
private TestAdapter mAdapter;
private ArrayList<String> dataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initViewsById();
}
private void initViewsById() {
mTestLv = (ListView) findViewById(R.id.test_lv);
mAdapter = new TestAdapter(this, dataList, this);
mTestLv.setAdapter(mAdapter);
}
private void initData() {
dataList = new ArrayList<String>();
for (int i = 0; i < 10; i++) {
dataList.add("第" + i + "行数据");
}
}
@Override
public void onItemDo(int position) {
int index = position;
Toast.makeText(MainActivity.this, "您点击的是第" + index + "行", Toast.LENGTH_SHORT).show();
}
}
----------适配器---------------------------
ublic class TestAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> dataList;
private ITestImpl mTestImpl;
public TestAdapter(Context context, ArrayList<String> dataList, ITestImpl mTestImpl) {
this.context = context;
this.dataList = dataList;
this.mTestImpl=mTestImpl;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (null == convertView) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.test_item, null);
holder.tv = (TextView) convertView.findViewById(R.id.item_name);
holder.btn = (Button) convertView.findViewById(R.id.item_btn);
convertView.setTag(holder);
}else{
holder=(ViewHolder) convertView.getTag();
}
holder.tv.setText(dataList.get(position));
holder.btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//此处我们利用回调方法,在Activity中来操作
mTestImpl.onItemDo(position);
}
});
return convertView;
}
public class ViewHolder {
private TextView tv;
private Button btn;
}
}
----------定义的接口--------------------------------
public interface ITestImpl {
void onItemDo(int position);
}
不过现在Android组件间通信库框架如EventBus的应用,很时候不用自己实现回调,也能实现我们想要的效果,而且更方便更有效。