您的位置:首页 > 移动开发 > Android开发

android开发笔记之从Button点击说起

2016-09-11 14:06 351 查看


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()方法。

接口是将一个行为操作的实现放到后面具体类,具体位置来实现,并且此行为操作还可以改变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息