android回调接口的两种方式

熟悉MS-Windows和X Windows事件驱动设计模式的开发人员,通常是把一个方法的指针传递给事件源,当某一事件发生时来调用这个方法(也称为“回调”)。Java的面向对象的模型目前不支持方法指针,似乎不能使用这种方便的机制。

但是java本身拥有interface,我们可以用interface实现相同的效果。在android中,如果我们需要对一个button的点击事件往外传,可以有两种实现方式。

第一种方式的大体步骤是:

1、定义一个回调接口,用来捕捉和“存放”点击事件。

public interface UIBtnInterface {
    //按钮事件:
    //参数:
    //   1)idEvent是事件: 
    //            UIDef.EVT_CLICKED …… 等
    //   2) idButton是按钮的ID;
    public void OnButtonEvent(int idEvent,int idButton);

}

2、在事件源类中,定义一个回调接口的成员变量,构造函数中设置一个回调接口参数用来实例化此接口,在button的点击事件发生后,立即通过成员变量调用自定义接口的方法,把点击事件“存放”在接口中。

  public NodeTree(Context context, AttributeSet attrs, int defStyle,UITreeInterface interface1){
        super(context, attrs, defStyle);
        this.context = context;
        Log.d("TAG", "NodeTree");
        this.interface1 = interface1;
    }
viewHolder.operate.setOnClickListener(new OnClickListener() {
            //onClick管理按钮的点击事件添加解除popupwindow
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
            if (nodeTree.uiTreeInterface != null) {
                    nodeTree.uiTreeInterface.onNodeChanged(node, Constant.IDBTN.ID_OPERATE);
                }
            if (((UIButton)v).uiBtnInterface != null) {
                ((UIButton)v).uiBtnInterface.OnButtonEvent(Constant.IDEVENT.EVT_CLICKED, ((UIButton)v).getId());
            }

3、目标类中,new一个事件源类,传入一个匿名类实现接口即可。

NodeTree nodeTree = new Nodetree(this,null,0,
new UITreeInterface() {
            
            @Override
            public void onSearchEvent(String queryText, List<Node> result) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void onNodeEvent(Node node, int idEvent) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void onNodeChanged(Node node, int idEvent) {
                // TODO Auto-generated method stub
                
            }
            
            @Override
            public void onButtonEvent(int idEvent, int idButton) {
                // TODO Auto-generated method stub
                
            }
        };
);

 

第二种方式其实差不多,只是回掉接口参数的传入时机有所变化。

1、定义一个回调接口,用来捕捉和“存放”点击事件。

public interface UIBtnInterface {
    //按钮事件:
    //参数:
    //   1)idEvent是事件: 
    //            UIDef.EVT_CLICKED …… 等
    //   2) idButton是按钮的ID;
    public void OnButtonEvent(int idEvent,int idButton);

}

2、在事件源类中,定义一个回调接口的成员变量,定义register和unregister方法用来实例化此接口。在button的点击事件发生后,立即通过成员变量调用自定义接口的方法,把点击事件“存放”在接口中。

    }
    /**
     * 提供给接口实现方注册自己
     * 
     * @param listener
     */
    public void registerUITreeListener(UITreeInterface listener) {
        //LogUtils.LOGD(TAG, CommonFunction.getFileLineMethod());
        this.uiTreeInterface = listener;
    }

    /**
     * 提供给接口实现方来取消注册自己
     * 
     * @param listener
     */
    public void unRegisterUITreeListener() {
        if (this.uiTreeInterface != null) {
            this.uiTreeInterface = null;
        }
    }

 

viewHolder.operate.setOnClickListener(new OnClickListener() {
            //onClick管理按钮的点击事件添加解除popupwindow
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
            if (nodeTree.uiTreeInterface != null) {
                    nodeTree.uiTreeInterface.onNodeChanged(node, Constant.IDBTN.ID_OPERATE);
                }
            if (((UIButton)v).uiBtnInterface != null) {
                ((UIButton)v).uiBtnInterface.OnButtonEvent(Constant.IDEVENT.EVT_CLICKED, ((UIButton)v).getId());
            }

3、目标类实现这个接口,new一个事件源类,通过register和unregister方法来绑定和解绑。

nodeTree.registerUITreeListener(new UITreeInterface()//回调接口
                {
                    @Override
                    public void onNodeEvent(Node node,int event)
                    {   
                        switch (event) {
                        case Constant.IDEVENT.EVT_CLICKED:
                            Log.d("CLICK", "CLICKED");
                        if (node.isLeaf())
                            {
                                Toast.makeText(getApplicationContext(), node.getName(),
                                Toast.LENGTH_SHORT).show();
                            }
                            break;
                        case Constant.IDEVENT.EVT_DRAG:
                            Log.d("DRAG", "DRAG");
                            break;
                        case Constant.IDEVENT.EVT_SWIPELEFT:
                            Log.d("SWIPELEFT", "SWIPELEFT");
                            break;
                        case Constant.IDEVENT.EVT_SWIPERIGHT:
                            Log.d("SWIPERIGHT", "SWIPERIGHT");
                            break;
                        default:
                            break;
                        }

                    }
                    @Override
                    public void onNodeChanged(Node node, int idEvent) {
                        // TODO Auto-generated method stub
                        switch (idEvent) {
                        case Constant.IDBTN.ID_DEL:
                            Log.d("del", "del");
                            break;
                        case Constant.IDBTN.ID_EDIT:
                            Log.d("edit", "edit");
                            break;
                        case Constant.IDBTN.ID_NEW:
                            Log.d("new", "new");
                            break;
                        case Constant.IDBTN.ID_OPERATE:
                            Log.d("new", node.getName());
                            break;
                        default:
                            break;
                        }
                    }
                    @Override
                    public void onButtonEvent(int idEvent, int idButton) {
                        // TODO Auto-generated method stub
                        Log.d("button", String.valueOf(idButton));
                        switch (idButton) {
                        case 42031://管理、插入、删除、重命名、复制
                            
                            break;
                        case 5://复选
                            break;
                        case 0x1110://新建
                            Node newNode = new Node(4, 2, "蓝花瓷",true,beans);
                            nodeTree.replaceNode(4, newNode);
                            nodeTree.replaceCommit();
                            break;
                        case 0x1111://确定
                            
                            break;
                        case 0x1112://取消
                            
                            break;
                        default:
                            break;
                        }
                    }
                    @Override
                    public void onSearchEvent(String queryText,
                            List<Node> result) {
                        // TODO Auto-generated method stub
                        Log.d("search", queryText);
                    }

                });

两者的应用场合区别在于:前者适合必须绑定的接口,那样可以少定义两个方法,后者则提供了解绑机制,耦合性较低。

posted @ 2015-06-29 13:33  钢面公爵  阅读(1349)  评论(0编辑  收藏  举报