本帖最后由 xiaoqing 于 2015-11-12 20:08 编辑
大家好,深圳校区福利来啦。不过不是美女图哦,是技术福利。 简单的说,就是深圳校区内网有一个便捷的问答平台(跟“知乎”很像)。就业指导老师不单止辅导就业哦,技术实力也是棒棒的,晚自习会帮助大家解决各种疑难杂症,解决好问题之后呢?就完了吗?当然要惠及大众呀。老师就从里面各种问答中找出一些典型的问答,分享给大家。这些问题是学员平时上课遇到的问题,也可能是去面试时面试官提出的问题。相信这些问题对大家的学习和就业肯定有帮助。 那么这一期的问题就是关于回调(CallBack)。 好了,不说废话,直接上精彩问答。在问答网里,师生对答是这样的:
看完是不是想说:然并卵?其实我们是有代码的。直接上原问答吧:
-------------------------------------------------------华丽的分割线------------------------------------------------------ 先讲讲怎么去写一个回调,举个例子比较容易解释。 这是一个真实的应用场景,就是类似微信的表情模块,点击选中某个表情,就可以显示在edittext上:- FaceRelativeLayout类 :怎么写一个回调接口
- /**
- * 表情控件
- * @author JIM
- *
- */
- public class FaceRelativeLayout extends RelativeLayout implements
- OnItemClickListener {
- /** 表情页的监听事件 */
- private OnCorpusSelectedListener listener;
- public void setOnCorpusSelectedListener(OnCorpusSelectedListener listener) {
- this.listener = listener;
- }
- /**
- * 表情选择监听
- *
- * @author naibo-liao
- * @时间: 2013-1-15下午04:32:54
- */
- public interface OnCorpusSelectedListener {
- void onCorpusSelected(ChatEmoji emoji);
- void onCorpusDeleted();
- }
-
- private void Init_viewPager() {
- ...
- ...
- ...省略
- view.setOnItemClickListener(new OnItemClickListener(){
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1,
- int arg2, long arg3) {
- ChatEmoji emoji = (ChatEmoji) faceAdapters.get(current).getItem(arg2);
- //System.out.println("mListener: "+listener);
- listener.onCorpusSelected(emoji);
- }
-
- });
- }
- }
- }
复制代码- ChatActivity类:写好了回调接口,怎么取去用
-
-
- private void callBack() {
- mListener = new OnCorpusSelectedListener() {
- @Override
- public void onCorpusSelected(ChatEmoji emoji) {
-
- //if (emoji.getFaceName() != "face_del.png")
- if (TextUtils.isEmpty(emoji.getFaceName())&&emoji.getId()==R.drawable.del_face_btn) {
- int selection = mContent.getSelectionStart();
- String text = mContent.getText().toString();
- if (selection > 0) {
- String text2 = text.substring(selection - 1);
- if ("]".equals(text2)) {
- int start = text.lastIndexOf("[");
- int end = selection;
- mContent.getText().delete(start, end);
- return;
- }
- mContent.getText().delete(selection - 1, selection);
- }
- }else {
- if(emoji.getCharacter() == null){
- return ;
- }
- SpannableString spannableString = FaceConversionUtil
- .getInstace().addFace(getApplicationContext(),
- emoji.getPath(), emoji.getCharacter());
- mContent.append(spannableString);
- }
-
- }
- @Override
- public void onCorpusDeleted() {
- // TODO Auto-generated method stub
- }
- };
- mFaceRelativeLayout.setOnCorpusSelectedListener(mListener);
- }
复制代码以上述代码为例子,总结一下: 写一个回调接口的步骤为 (1)定义一个接口: - public interface OnCorpusSelectedListener {
-
- void onCorpusSelected(ChatEmoji emoji);
-
- void onCorpusDeleted();
-
- }
复制代码 (2)声明该接口的成员变量 - private OnCorpusSelectedListener listener;
复制代码 (3)创建一个public权限的方法供外界设置改回调- public void setOnCorpusSelectedListener(OnCorpusSelectedListener listener) {
-
- this.listener = listener;
-
- }
复制代码 (4)使用该接口方法里的方法- listener.onCorpusSelected(emoji);
复制代码总结一下,怎么在别的类中使用该回调 步骤为: (1)声明该回调类的变量 - /** 表情页的监听事件 */
-
- private OnCorpusSelectedListener mListener;
复制代码 (2)调用该回调类中,对外暴露的设置该回调的方法- mFaceRelativeLayout.setOnCorpusSelectedListener(new OnCorpusSelectedListener() {
- @Override
- public void onCorpusSelected(ChatEmoji emoji) {
-
- //if (emoji.getFaceName() != "face_del.png")
- if (TextUtils.isEmpty(emoji.getFaceName())&&emoji.getId()==R.drawable.del_face_btn) {
- int selection = mContent.getSelectionStart();
- String text = mContent.getText().toString();
- if (selection > 0) {
- String text2 = text.substring(selection - 1);
- if ("]".equals(text2)) {
- int start = text.lastIndexOf("[");
- int end = selection;
- mContent.getText().delete(start, end);
- return;
- }
- mContent.getText().delete(selection - 1, selection);
- }
- }else {
- if(emoji.getCharacter() == null){
- return ;
- }
- SpannableString spannableString = FaceConversionUtil
- .getInstace().addFace(getApplicationContext(),
- emoji.getPath(), emoji.getCharacter());
- mContent.append(spannableString);
- }
-
- }
- @Override
- public void onCorpusDeleted() {
- // TODO Auto-generated method stub
- }
- };);
复制代码 完毕
其实对于这个表情模块,是可以不用回调实现的,我们把两个类合并,把功能都写到一个类中,那么同样可以实现功能,但是呢,会导致什么问题?这样会出现不能复用,并且带来一个很有严重的问题,耦合度太高,一个类中几千行代码。分开来写的话,这个模块就能够被复用,并且解耦合。把具体的实现留到给以后去实现。形象的形容一下方法回调,其实就是传递一个代码块。类比一下方法的调用,传递的是一个参数,方法的回调,传递的是一个代码块。
-------------------------------------------------------华丽的分割线------------------------------------------------------
感谢梁剑老师细致的回答,这是一个很接地气的技术问题。并且,回调经常被用于在封装模块时进行解耦,比如观察者模式就是用回调实现的哦,妈妈再也不用担心面试官问我观察者了。下回再见!
|