android学习笔记-接口回调简析

来源:互联网 发布:宁波用友软件代理商 编辑:程序博客网 时间:2024/06/05 12:07

以前怎么也不能够理解android中的回调事件,比方说点击事件的实现为什么要通过:
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
这样的形式来调用呢。

下面是我上一篇文章中那个试类代码

链接

1.首先是MainActivity.java

public class MainActivity extends Activity {private MyTextView text;private MyTopBar topBar;@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    text = (MyTextView) findViewById(R.id.text);    topBar = (MyTopBar) findViewById(R.id.topBar);    topBar.setOnTopBarClickListener(new OnTopBarClickListener() {        @Override        public void rightClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "rightButton被点击", Toast.LENGTH_SHORT).show();        }        @Override        public void leftClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "leftButton被点击", Toast.LENGTH_SHORT).show();        }    });}

}

2.然后是MyTopBar

public class MyTopBar extends RelativeLayout{public static  final int LEFT = 0;public static  final int RIGHT = 1;private String title;private int titleSize;private int titleColor;private String leftText;private int leftTextSize;private Drawable leftBackground;private String rightText;private int rightTextSize;private Drawable rightBackground;private TextView titleText;private TextView leftButton;private TextView rightButton;private LayoutParams titleParams;private LayoutParams leftParams;private LayoutParams rightParams;private OnTopBarClickListener topBarListener;public MyTopBar(Context context, AttributeSet attrs) {    super(context, attrs);    // TODO Auto-generated constructor stub    //当你在xml布局文件中填写属性时,他会动态查找这个类中的相对应的属性来匹配类型    TypedArray typeArray = getResources().obtainAttributes(attrs, R.styleable.TopBar);    title = typeArray.getString(R.styleable.TopBar_title);    titleSize = (int) typeArray.getDimension(R.styleable.TopBar_titleSize, 0);    titleColor= typeArray.getColor(R.styleable.TopBar_titleColor,Color.WHITE);    leftText = typeArray.getString(R.styleable.TopBar_leftText);    leftTextSize = (int) typeArray.getDimension(R.styleable.TopBar_leftTextSize, 0);    leftBackground = typeArray.getDrawable(R.styleable.TopBar_leftBackground);    rightText = typeArray.getString(R.styleable.TopBar_rightText);    rightTextSize = (int) typeArray.getDimension(R.styleable.TopBar_rightTextSize, 0);    rightBackground = typeArray.getDrawable(R.styleable.TopBar_rightBackground);    titleText = new TextView(context);    leftButton = new TextView(context);    rightButton = new TextView(context);    titleText.setText(title);    titleText.setTextSize(titleSize);    titleText.setTextColor(titleColor);    leftButton.setText(leftText);    leftButton.setTextSize(leftTextSize);    leftButton.setBackground(leftBackground);    rightButton.setText(rightText);    rightButton.setTextSize(rightTextSize);    rightButton.setBackground(rightBackground);    titleParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);    titleParams.addRule(RelativeLayout.CENTER_IN_PARENT);    leftParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);    leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);    rightParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);    rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);    typeArray.recycle();    addView(titleText, titleParams);    addView(leftButton, leftParams);    addView(rightButton, rightParams);    leftButton.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            topBarListener.leftClick();        }    });    rightButton.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            topBarListener.rightClick();        }    });}public interface OnTopBarClickListener{    void leftClick();    void rightClick();}public void setOnTopBarClickListener(OnTopBarClickListener topBarListener){    this.topBarListener = topBarListener;}public void setBtnVisible(int id,boolean flag){    if(id == LEFT){        if(flag){            leftButton.setVisibility(View.VISIBLE);        }else{            leftButton.setVisibility(View.GONE);        }    }else{        if(flag){            rightButton.setVisibility(View.VISIBLE);        }else{            rightButton.setVisibility(View.GONE);        }    }}

}

上面的代码太多,我把代码拿出来看,

1 . 首先在MyTopBar中定义一个public 的接口如下

public interface OnTopBarClickListener{    void leftClick();    void rightClick();}

2. 然后提供一个公众方法用以设置接口的实例对象

public void setOnTopBarClickListener(OnTopBarClickListener topBarListener){    this.topBarListener = topBarListener;}

3. 当左右俩边的按钮被点击时,调用回调的方法。

leftButton.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            topBarListener.leftClick();        }    });    rightButton.setOnClickListener(new OnClickListener() {        @Override        public void onClick(View v) {            // TODO Auto-generated method stub            topBarListener.rightClick();        }    });

可是,有人会这样问,当左右俩边的按钮被点击时,他们下的topBarListener.rightClick(),并没有看到此方法的定义啊,这个就是重点了,往下看。
4. 在MainActivity中

topBar.setOnTopBarClickListener(new OnTopBarClickListener() {        @Override        public void rightClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "rightButton被点击", Toast.LENGTH_SHORT).show();        }        @Override        public void leftClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "leftButton被点击", Toast.LENGTH_SHORT).show();        }    });

可以看到MyTopBar中的方法实现在这里,这就令人很纳闷了,这时怎么回事。

首先我们来分析一下:new OnTopBarClickListener() {

        @Override        public void rightClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "rightButton被点击", Toast.LENGTH_SHORT).show();        }        @Override        public void leftClick() {            // TODO Auto-generated method stub            Toast.makeText(MainActivity.this, "leftButton被点击", Toast.LENGTH_SHORT).show();        }    }

这段代码是new 实例化了一个匿名内部对象类。

什么事匿名内部对象类?

匿名对象类:一般是一个对象只会被用到一次,如果单独放到一个文件中,觉得没必要。然后匿名对象类用于 :

某个抽象类或者接口的实例只会被用到一次。

然后通过 new 关键字产生一个匿名对象类。

接着看上面的topBar.setOnTopBarClickListener();
通过这个方法我们将昕创建的匿名对象类传递给了MyTopBar,这样的话,当按钮被点击的时候,他调用的是我们匿名对象的方法。

使用匿名对象内部类的好处:匿名对象类可以使用当前类中任何私有属性与方法,这种方式非常方便,我们在另外一个类里面面调用方法,然后回调过来可以使用当前类中的方法,是不是很变态啊。

完整试类在前面一篇博客中有完整的代码。

0 0