Android中的接口回调

来源:互联网 发布:淘宝旺铺版本区别 编辑:程序博客网 时间:2024/05/24 00:57

在Android中到处可见接口回调机制,尤其是UI事件处理方面。举一个最常见的例子button点击事件,button有一个点击方法onClick(),我们知道onclick()是一个回调方法,当用户点击button就执行这个方法。在源码中是这样定义的:

    //这个是View的一个回调接口      /**      * Interface definition for a callback to be invoked when a view is clicked.      */      public interface OnClickListener {          /**           * Called when a view has been clicked.           *           * @param v The view that was clicked.           */          void onClick(View v);      }  

下面看一个简单的例子:

import android.os.Bundle;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.Toast;  public class MainActivity extends Activity implements OnClickListener{       private Button button;       @Override       public void onCreate(Bundle savedInstanceState) {            super.onCreate(savedInstanceState);            setContentView(R.layout.activity_main);            button = (Button)findViewById(R.id.button1);            button.setOnClickListener(this);       }       @Override       public void onClick(View v) {            Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show();       }  } 

这就是一个很典型的例子,当然也可以这样写:

import android.app.Activity;  import android.os.Bundle;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  public class SSSS extends Activity {       private Button button;       private OnClickListener clickListener = new OnClickListener() {            @Override            public void onClick(View v) {                 Toast.makeText(getApplication(), "OnClick", Toast.LENGTH_LONG).show();            }       };       @Override       protected void onCreate(Bundle savedInstanceState) {            // TODO Auto-generated method stub            super.onCreate(savedInstanceState);            button = (Button)findViewById(R.id.button1);            button.setOnClickListener(clickListener);         } }  

下面是View类的setOnClickListener方法,把和回调相关代码贴出来。为什么贴它呢,因为Button继承于TextView,而TextView继承于View,在View里面处理的回调:

    /**      *      */      public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {           /**           * Listener used to dispatch click events.           * This field should be made private, so it is hidden from the SDK.           * {@hide}           */          protected OnClickListener mOnClickListener;          /**           *           * Register a callback to be invoked when this view is clicked. If this view is not           * clickable, it becomes clickable.           *           * @param l The callback that will run           *           * @see #setClickable(boolean)           */          public void setOnClickListener(OnClickListener l) {              if (!isClickable()) {                  setClickable(true);              }              mOnClickListener = l;          }          /**           * Call this view's OnClickListener, if it is defined.           *           * @return True there was an assigned OnClickListener that was called, false           *         otherwise is returned.           */          public boolean performClick() {              sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);              if (mOnClickListener != null) {                  playSoundEffect(SoundEffectConstants.CLICK);                  mOnClickListener.onClick(this);                  return true;              }              return false;          }      }  

那现在一起来总结一下基本的回调是如何实现的 : 首先创建一个接口,这个接口用于你在某个情景下执行相应的操作 ; 接着创建一个功能类,比如这个类可以显示一个对话框、可以滑动菜单、可以下载数据等等 ; 然后,在这个类里面声明回调接口的对象,之后在这个类里面创建在某个情景下需要执行的方法,而且在这个方法里面为声明的接口对象赋值 ; 最后在其他的类中使用这个功能类就可以了。所以说,最少也是需要三个类共同来完成这个回调机制。
这下大家应该就比较明白了,那我们就自己按照这个方式和流程完成一个这样的例子。以Dialog为例,一般我们在开发时候,经常会用到Dialog。比如一个弹出框,里面有确认和取消。通常情况下,我们可能会这样写:

    final Dialog dialog = new Dialog(this, R.style.MyDialogStyle);               dialog.setContentView(R.layout.dialog_exit_train);               dialog.show();               ImageButton ib_affirm = (ImageButton) dialog                         .findViewById(R.id.dialog_exit_ib_affirm);               ImageButton ib_cancel = (ImageButton) dialog                         .findViewById(R.id.dialog_exit_ib_cancel);               ib_affirm.setOnClickListener(new View.OnClickListener() {                    @Override                    public void onClick(View v) {                         saveUserData();                         dialog.dismiss();                         TestActivity.this.finish();                    }               });               ib_cancel.setOnClickListener(new View.OnClickListener() {                    @Override                    public void onClick(View v) {                         dialog.dismiss();                    }               });  

也就是得到点击对象之后再去调用onClick(),这样有一个缺点就是你每次都要写,不利于重复使用。那我们就可以对此进行一个封装,看代码:

    import android.app.Dialog;      import android.content.Context;      import android.os.Bundle;      import android.text.TextPaint;      import android.view.View;      import android.view.Window;      import android.view.WindowManager;      import android.widget.Button;      import android.widget.TextView;      import com.fanfou.app.opensource.R;      /**      *       *      */      public class AlertInfoDialog extends Dialog implements View.OnClickListener {          //创建接口          public static interface OnOKClickListener {              public void onOKClick();          }          private final Context mContext;          private TextView mTitleView;          private TextView mTextView;          private Button mButtonOk;          private CharSequence mTitle;          private CharSequence mText;          //生命接口对象          private OnOKClickListener mClickListener;          public AlertInfoDialog(final Context context, final String title,                  final String text) {              super(context, R.style.Dialog);              this.mContext = context;              this.mTitle = title;              this.mText = text;          }          private void init() {              setContentView(R.layout.dialog_alert);              this.mTitleView = (TextView) findViewById(R.id.title);              final TextPaint tp = this.mTitleView.getPaint();              tp.setFakeBoldText(true);              this.mTitleView.setText(this.mTitle);              this.mTextView = (TextView) findViewById(R.id.text);              this.mTextView.setText(this.mText);              this.mButtonOk = (Button) findViewById(R.id.button_ok);              this.mButtonOk.setOnClickListener(this);          }          @Override          public void onClick(final View v) {              final int id = v.getId();              switch (id) {              case R.id.button_ok:                  cancel();//调用                  if (this.mClickListener != null) {                      this.mClickListener.onOKClick();                  }                  break;              default:                  break;              }          }          @Override          protected void onCreate(final Bundle savedInstanceState) {              super.onCreate(savedInstanceState);              setBlurEffect();              init();          }          protected void setBlurEffect() {              final Window window = getWindow();              final WindowManager.LayoutParams lp = window.getAttributes();              // lp.alpha=0.8f;              lp.dimAmount = 0.6f;              window.setAttributes(lp);              window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);              // window.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);          }          public void setMessage(final CharSequence message) {              this.mText = message;              this.mTextView.setText(this.mText);          }          public void setMessage(final int resId) {              this.mText = this.mContext.getResources().getText(resId);              this.mTextView.setText(this.mText);          }          //设置监听器 也就是实例化接口          public void setOnClickListener(final OnOKClickListener clickListener) {              this.mClickListener = clickListener;          }          @Override          public void setTitle(final CharSequence title) {              this.mTitle = title;              this.mTitleView.setText(this.mTitle);          }          @Override          public void setTitle(final int resId) {              this.mTitle = this.mContext.getResources().getText(resId);              this.mTitleView.setText(this.mTitle);          }      }  

方式和上面介绍的一样,感兴趣的朋友可以自己去实现其他效果的。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 竞彩足球投注后输了怎么办 英雄联盟鼠标箭头右键点不了怎么办 上古卷轴5数值修改错了怎么办 小时候打针把屁股脂肪打扁了怎么办 大繁盛满腹市场2对话时闪退怎么办 月经来了一个月了还不停怎么办 对办公室的异性老师产生好感怎么办 上古卷轴5任务NPC老打我怎么办 1岁半宝宝走路内八字怎么办 最近几个月例假周期都25天怎么办 从pr导出的视频大小不一样怎么办 合作医疗收据丢了不给报销怎么办 沧州新生医院—老人腹胀了该怎么办 内痔疮术后一个月吃了点辣椒怎么办 肛周脓肿手术后大便干怎么办 月经半个月了还没干净怎么办 房东出租违建房不退房租怎么办 上海公租房住满5年后怎么办 监狱对死缓犯人延长转为无期怎么办 手机号码办理的宽带不想要了怎么办 朋友诈骗罪被关看守所了该怎么办 打架被拘留家里有孩子没人看怎么办 刑事拘留满37天给逮捕了怎么办 因打架被拘留十五天释放后会怎么办 犯罪人在拘留所生了小孩怎么办 我申请了进京证更换车辆怎么办 丈夫去世前想把财产留给妻子怎么办 假货中通代收货款发现是假货怎么办 注册志愿者时身份证被使用该怎么办 双眼皮贴贴的皮肤送了怎么办? 满60岁社保末满十五年怎么办 眼角膜少了一块怎么办应该吃什么 左右胸相差一个罩杯左右怎么办 穿一字肩的裙子没有无肩内衣怎么办 农业网柑橘被奄24小时怎么办 钱包被偷了小偷抓到了钱不认怎么办 快高考了很想学却没有动力怎么办? 孩子高三了学习状态不好怎么办 离婚时对方说把钱都花了怎么办 挂科太多学校不给毕业证怎么办 大专挂科太多学校让延期毕业怎么办