android開發筆記之從Button點擊說起

分類:編程 時間:2016-11-08
[摘要:Button應用 日常平凡,我們開辟,Button控件一樣平常便是以下應用: 先正在結構文件中界說Button控件: <Button android:id="@+id/button" a]

這裏寫圖片描述

Button使用

平時,我們開發,Button控件一般就是如下使用:

先在布局文件中定義Button控件:

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TestButton" />

再在Java文件中使用此Button控件:

//定義Button
private Button button = null;
//定義接口OnClickListener
private View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.i(TAG,"View.OnClickListener--onClick");
        }
};
//獲取button對象
button = (Button)findViewById(R.id.button);
//設置button點擊事件監聽接口
button.setOnClickListener(onClickListener);

執行程序,當button點擊時,執行接口OnClickListener中的onClick方法,打印Log:

View.OnClickListener--onClick

android是怎麽樣設計此功能的

我們查看源碼—View.java

OnClickListener 接口定義:

因此,響應點擊Button後的操作,各個控件,各個場景都不一樣,是一個可變的動作,所以android定義了一個接口OnClickListener來應對這個可變的因素:

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

定義內部的OnClickListener變量mOnClickListener:

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

setOnClickListener方法:

public void setOnClickListener(OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        //給mOnClickListener變量賦值
        getListenerInfo().mOnClickListener = l;
}

執行click的方法performClick:

    /**
     * Call this view's OnClickListener, if it is defined.  Performs all normal
     * actions associated with clicking: reporting accessibility event, playing
     * a sound, etc.
     *
     * @return True there was an assigned OnClickListener that was called, false
     *         otherwise is returned.
     */
    public boolean performClick() {
        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            //播放點擊聲音
            playSoundEffect(SoundEffectConstants.CLICK);
            //執行點擊的回調方法onClick
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }

        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
        return result;
    }

執行click的方法callOnClick:

/**
* Directly call any attached OnClickListener.  Unlike {@link #performClick()},
* this only calls the listener, and does not do any associated clicking
* actions like reporting an accessibility event.
*
* @return True there was an assigned OnClickListener that was called, false
*         otherwise is returned.
*/
public boolean callOnClick() {
        ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            //執行點擊的回調方法onClick
            li.mOnClickListener.onClick(this);
            return true;
        }
        return false;
}

點擊button是在什麽時候點擊監聽回調接口:

boolean performAccessibilityActionInternal(int action, Bundle arguments) {
        switch (action) {
            //ACTION_CLICK  點擊Button
            case AccessibilityNodeInfo.ACTION_CLICK: {
                if (isClickable()) {
                    //執行點擊button監聽接口
                    performClick();
                    return true;
                }
            } break;
......
......
public boolean onTouchEvent(MotionEvent event) {
......
        //可以點擊
        if (((viewFlags & CLICKABLE) == CLICKABLE ||
                (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
            switch (event.getAction()) {
                //button ACTION_UP
                case MotionEvent.ACTION_UP:
                   ......
                   if (mPerformClick == null) {
                       mPerformClick = new PerformClick();
                    }
                    if (!post(mPerformClick)) {
                       //執行點擊button監聽接口
                       performClick();
                    }
......

再修改Button使用方法:

我們為了讓大家真正看明白android為什麽如此設計Button是這樣響應點擊事件,我們再定義一個MyButtonOnClickListener類:

//類MyButtonOnClickListener實現接口View.OnClickListener,實現方法onClick:

public class MyButtonOnClickListener implements View.OnClickListener {
    public static final String TAG = "MyButtonOnClickListener";

    @Override
    public void onClick(View v) {
        Log.i(TAG,"MyButtonOnClickListener--onClick");
    }
}

然後,我們再實現點擊Button代碼:

//定義Button
private Button button = null;
//定義MyButtonOnClickListener
private MyButtonOnClickListener myButtonOnClickListener = new MyButtonOnClickListener();
//獲取button對象
button = (Button)findViewById(R.id.button);
//設置button點擊事件監聽接口myButtonOnClickListener
button.setOnClickListener(myButtonOnClickListener);

現在,我們列出uml類圖:

這裏寫圖片描述

大家看類圖,應該是不是覺得有一點眼熟呢?是不是和策略模式的類圖相似呢?
對,這就是一個最簡單的策略模式。

接口在android開發中的樣例

android開發筆記之監聽者模式—http://blog.csdn.net/hfreeman2008/article/details/37568615

這是我以前寫的一篇文章,非常好的應用了接口。

接口在java開發中的樣例

定義接口:

接口IListener:

public interface IListener {
    public void run();
}

定義一個Body類:

public class Body {
    //定義一個IListener類型的變量listener
    private IListener listener = null;
    //設置Listener
    public void setListener(IListener listener){
        this.listener = listener;
    }
    //執行方法
    public void dosomething(){
        system.out.println("Body--dosomething()--before");
        if(listener != null){
            //這才是接口方法的調用的地方,也是用於後面的地方實現的地方
            listener.run();
        }
        System.out.println("Body--dosomething()--after");
    }

}

我們再定義一個接口實現類ListenerTest01:

public class ListenerTest01 implements IListener {

    //ListenerTest01實現接口IListener中run方法
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("ListenerTest01---run()");
    }
}

我們在Client中使用:


public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //定義一個對象listener,大家常用這一種方式,實現接口IListener中run方法
        IListener listener = new IListener() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("listener---run()");
            }
        };
        //定義一個對象listenerTest01 
        IListener listenerTest01 = new ListenerTest01();

        //我們沒有設置Listener
        System.out.println("---------------------");
        Body body = new Body();
        body.dosomething();

        //我們設置Listener為listener
        System.out.println("---------------------");
        body.setListener(listener);
        body.dosomething();

        //我們設置Listener為listenerTest01
        System.out.println("---------------------");        
        body.setListener(listenerTest01);
        body.dosomething(); 
    }

}

輸出結果:

---------------------
Body--dosomething()--before
Body--dosomething()--after
---------------------
Body--dosomething()--before
listener---run()
Body--dosomething()--after
---------------------
Body--dosomething()--before
ListenerTest01---run()
Body--dosomething()--after

從輸出結果,我們可以看到:
如果不設置Listener,就直接執行對象的dosomething方法,而不執行listener.run()方法。
如果我們設置Listener為listener,則執行listener—run()方法。
如果我們設置Listener為ListenerTest01,則執行ListenerTest01—run()方法。

接口是將一個行為操作的實現放到後面具體類,具體位置來實現,並且此行為操作還可以改變。


Tags:

文章來源:


ads
ads

相關文章
ads

相關文章

ad