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:
文章來源: