天天看点

针对于Button的OnClickListener监听器的三种绑定监听器的源码分析感想

监听器的三种绑定

在xml中绑定

<pre style="background-color:#2b2b2b;color:#a9b7c6;font-family:'OCR A Std';font-size:9.0pt;"><span style="color:#e8bf6a;"><Button
</span><span style="color:#e8bf6a;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:id=</span><span style="color:#a5c261;">"@+id/btn_confirm"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_width=</span><span style="color:#a5c261;">"fill_parent"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_height=</span><span style="color:#a5c261;">"46dp"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_below=</span><span style="color:#a5c261;">"@+id/firstBlock"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_marginLeft=</span><span style="color:#a5c261;">"12dp"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:background=</span><span style="color:#a5c261;">"@drawable/button_style"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_marginRight=</span><span style="color:#a5c261;">"12dp"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:layout_marginTop=</span><span style="color:#a5c261;">"30dp"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:text=</span><span style="color:#a5c261;">"</span><span style="color:#a5c261;font-family:'宋体';">保存</span><span style="color:#a5c261;">"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:textColor=</span><span style="color:#a5c261;">"#FFFFFF"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:textSize=</span><span style="color:#a5c261;">"18sp"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:focusable=</span><span style="color:#a5c261;">"true"
</span><span style="color:#a5c261;">    </span><span style="color:#9876aa;">android</span><span style="color:#bababa;">:onClick=</span><span style="color:#a5c261;">"push"</span><span style="color:#e8bf6a;">/></span>
           

在xml中为它绑定了"bt_push",然后我们在activity中这样调用

public class ChangeNickname extends Activity {
    Button push;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_change_nickname);
        push = (Button)findViewById(R.id.btn_confirm);

    }

    public void push (View view)
    {
        Intent intent = new Intent();
        intent.setClass(ChangeNickname.this,ForgottenPassword.class);
        startActivity(intent);

    }
           

就实现了一个漂亮的页面跳转

在onCreate方法中指定

back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
           

这样进入界面就会创建一个对象,浪费资源!那么我们用一种节省资源的方法

findViewById(R.id.btn_confirm).setOnClickListener(onclick);  //在activity里

OnClickListener onclick = new OnClickListener(){  
    @Override  
    public void onClick(View v) {  
        Intent intent = new Intent(ChangeNickname.this, ForgottenPhonenumber.class);  
        startActivity(intent);    
    }  
};  
           

这样点击再创建对象要好的多

第三种,也是我最想说的一种:这种方法可以实现一个监听器监听多个按钮!

public class MainActivity extends Activity implements View.OnClickListener {

    @InjectView(R.id.btn_1)
    Button btn1;
    @InjectView(R.id.btn_2)
    Button btn2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn1.setTag(1);
        btn2.setTag(2);
    }

    @Override
    public void onClick(View v) {
        int tag = (Integer) v.getTag();
        switch (tag) {
            case 1: {
                Intent intent = new Intent(MainActivity.this,Appointment.class);
                startActivity(intent);
                break;
            }
            case 2: {
                Intent intent = new Intent(MainActivity.this,ChangPasswordByCode.class);
                startActivity(intent);
                break;
            }
            default: {
                break;
            }
        }

    }
}
           

butterknife是一个jar,主要实现一键绑定(findviewbyid)这里不对他进行详细讲解,只要知道

@InjectView(R.id.btn_1)
    Button btn1;
           

是实现了findviewbyid即可,我们用tag来标记不同的button,然后用switch、case实现绑定

监听器的源码分析

有没有感觉到监听器很神奇??他是怎么实现的?其实绑定监听器的方法会一两种就好(强烈推荐最后一种) 下面,我们走进源代码世界~

我们一步一步走,先进入setonclicklistener

public void setOnClickListener(OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }
           

如果不能点击,设置为能点击的,我们不太明白的是OnClickListener l 是什么? getListenerInfo.mOnClickListener又是什么? 继续:

public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }
           

当被点击时调用这个方法!!当然,类型?onClick?View?这些源码我们都还没看,由于其内容过多,我们日后再详解,现在只要知道当这个View被点击时调用该方法就好了!!

ListenerInfo getListenerInfo() {
        if (mListenerInfo != null) {
            return mListenerInfo;
        }
        mListenerInfo = new ListenerInfo();
        return mListenerInfo;
    }
           

如果mListenerInfo不为空,返回,否则,新建一个返回,那么,这个mListenerInfo是何方神圣?

static class ListenerInfo {
        /**
         * Listener used to dispatch focus change events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnFocusChangeListener mOnFocusChangeListener;

        /**
         * Listeners for layout change events.
         */
        private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;

        /**
         * Listeners for attach events.
         */
        private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;

        /**
         * Listener used to dispatch click events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        public OnClickListener mOnClickListener;

        /**
         * Listener used to dispatch long click events.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnLongClickListener mOnLongClickListener;

        /**
         * Listener used to build the context menu.
         * This field should be made private, so it is hidden from the SDK.
         * {@hide}
         */
        protected OnCreateContextMenuListener mOnCreateContextMenuListener;

        private OnKeyListener mOnKeyListener;

        private OnTouchListener mOnTouchListener;

        private OnHoverListener mOnHoverListener;

        private OnGenericMotionListener mOnGenericMotionListener;

        private OnDragListener mOnDragListener;

        private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
    }
           

层层剥丝抽茧,找到核心部分了!!发现事实没有那么简单...又出现了很多很多方法,我们不可能一一去介绍,这也是我第一次看源码,以后会逐渐了解,逐渐学习,但是我们从他的英文注释部分看到,它是用来分遣焦点来改变事件的,总结之前的,我们知道,Android用了一系列高大上的方法,获得用户点击的焦点,返回这个焦点所代表的View,然后就可以执行他想执行的操作了

感想

第一次看源代码,还不错,不会看的同学Ctrl加鼠标左键点击方法就可以了!好久没写博客了,总是一味的找借口拖延,忙着学生会工作,忙着实验室项目,忙着考试...其实一个人的路是挺孤独的,每次想放弃的时候总是想象着未来有一个明媚的女子在等着与你共度一生,你要为他的幸福负责...也不管这是不是幻想,还是魔障,幸好,这是我所热爱的事情...未来在我们眼里,太遥远,你会感觉到社会很残酷,你想要的东西一次又一次的被别人抢走,你敬仰的事物一次又一次被别人践踏,你爱的人....额....一个千年老光棍就不提这个了~ 但是,你可以有一技之长,你可以在几天几夜熬的眼睛通红之后攻破对方那一无是处的网络防线!你可以改变一些你想改变的,守护一些你可以守护的!只要,你有一技之长!  加油!! 强大自己,别让父母再受风霜,不管她在不在,要担负起和她的未来!  希望这篇博文可以激励自己,和少数人

继续阅读