天天看點

針對于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加滑鼠左鍵點選方法就可以了!好久沒寫部落格了,總是一味的找借口拖延,忙着學生會工作,忙着實驗室項目,忙着考試...其實一個人的路是挺孤獨的,每次想放棄的時候總是想象着未來有一個明媚的女子在等着與你共度一生,你要為他的幸福負責...也不管這是不是幻想,還是魔障,幸好,這是我所熱愛的事情...未來在我們眼裡,太遙遠,你會感覺到社會很殘酷,你想要的東西一次又一次的被别人搶走,你敬仰的事物一次又一次被别人踐踏,你愛的人....額....一個千年老光棍就不提這個了~ 但是,你可以有一技之長,你可以在幾天幾夜熬的眼睛通紅之後攻破對方那一無是處的網絡防線!你可以改變一些你想改變的,守護一些你可以守護的!隻要,你有一技之長!  加油!! 強大自己,别讓父母再受風霜,不管她在不在,要擔負起和她的未來!  希望這篇博文可以激勵自己,和少數人

繼續閱讀