作者givemepass (〆)
看板AndroidDev
标题Re: [问题] onClickListener的事件处理?
时间Tue Jan 10 16:41:50 2012
我也来提供一些本身研究过的经验好了,
有时候不知道你会不会出现一些疑问?
当你为一些元件加入事件以後, 而这些元件产生变化的时候,
为什麽系统会知道是哪一个元件产生变化的呢?
其实他是由一种设计模式产生的, 这种设计模式称作为"观察者模式"
什麽叫做观察者模式,
观察者模式由三个角色所构成, 分别是观察者、观察者物件、主题物件,
假设有4个观察者物件,其中3个观察者物件加入了观察者名单,
每当主题物件发布了某些讯息,
有加入观察者名单的观察者物件就会透过观察者收到该讯息,
没有加入观察者名单的观察者物件当然就不会收到讯息,
而如果已经在观察者名单内的物件或者不在观察者名单内的物件,
仍然可以自由的加入观察者名单或者从观察者名单内移除。
呵呵,有点头昏脑胀了吗?举个白话点的例子,
现在假设大家都有玩过facebook的经验,
而facebook有一种模式叫做粉丝团,
当你加入某一个粉丝团的时候, 当该粉丝团发布某项讯息时,
该粉丝团的粉丝都会收到这项讯息,
而当你退出这个粉丝团的时候, 就在也收不到该粉丝团的讯息了!
这样就称作一个观察者模式。
现在把角色换成Button物件、Listener和Event物件,
Event物件就像是粉丝, Button物件的角色就像粉丝团,
当你把某一个Event物件加入了Button物件的Listener名单,
当button物件产生变化的时候, Listener就会去通知加入的Event物件。
button1.setOnClickListener(new OnClickListener(){
public void onClick(View v){
textView1.setText("textview1");
}
});
button1就是主题物件
setOnClickListener的行为就是加入观察名单
new OnClickListener() 就是观察者物件
当button产生变化的时候,
观察者就去观察者名单内查看有哪些观察者物件加入,
然後逐一的通知它们。
我们来模拟一下Button按下去的情节,
这个程式用来模拟Android的Button按下的时候, 要处理什麽样的动作,
首先你还是一样要先宣告一个事件,然後把这个事件加入button的监听器,
button1.setOnClickListener(new OnClickListener(){
public void onClick(View v){
textView1.setText("textview1");
}
});
可是我们模拟的button并不是android内建的,
如果要让android显示出来这两个button,
还要在写一些button的描述, 这样太复杂了,
因此我们就真的宣告android内建的button,
当button按下的时候, 就去呼叫我们做出来的"假Button"里面的"onclick",
以达到模拟的效果。
而我们的重点放在模拟
android的button到底是怎麽实作出setOnClickListener()这个方法,
想像一下setOnClickListener是被Button的实体物件呼叫,
因此, 我们可以猜到上层Button这个类别一定有一个方法叫做setOnClickLister(),
并且会传入OnClickListener这个物件的方法,
所以我们作出一个假button的类别,
interface FButton{
public void setOnClickListener(FakeOnLister listener);
}
这样一来, 我们就可以知道有一个类别会继承这个介面,
然後实作setOnClickListener这个方法。
在来我们想一下既然有传入OnClickListener这个物件,
而且会实作onClick()这个方法
那麽我们也来定义一个假的Listener
interface FakeOnLister {
void onClick(int index);
}
由前面知道观察者模式, 因此我们的Button里面会出现几个必要的方法,
首先是加入观察者物件,移除观察者物件,以及通知所有观察者,
所以类别可以这样写出来,
class FakeButton implements FButton{
private List<FakeOnLister> listenerList;
public FakeButton(){
listenerList = new ArrayList<FakeOnLister>();
}
public void setOnClickListener(FakeOnLister listener) {
listenerList.add(listener);
}
public void removeOnClickListener(FakeOnLister listener){
int index = listenerList.indexOf(listener);
if(index>=0){
listenerList.remove(index);
}
public void onClick() {
for (int i=0; i<listenerList.size(); i++) {
listenerList.get(i).onClick(i);
}
}
}
加入观察者物件
public void setOnClickListener(FakeOnLister listener)
移除观察者物件
public void removeOnClickListener(FakeOnLister listener)
通知所有观察者
public void onClick()
所以可以开始使用这个"假Button"了
private FakeButton fakeButton1;
private FakeButton fakeButton2;
public void onCreate(Bundle savedInstanceState) {
fakeButton1 = new FakeButton();
fakeButton2 = new FakeButton();
fakeButton1.setOnClickListener(new FakeOnLister(){
@Override
public void onClick(int index) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "button1 click",
Toast.LENGTH_SHORT).show();
}
});
fakeButton2.setOnClickListener(new FakeOnLister(){
@Override
public void onClick(int index) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "button2 click",
Toast.LENGTH_SHORT).show();
}
});
}
当我们按下假button 1号就会跳出Toast讯息显示我们按下的是假button 1号
同理, 假button 2号。
接着我们重复刚刚所说的用真的button去模拟我们写出来的假button,
借用一下他们的onClick动作来证实我们的button是可以动的。
button1 = (Button)findViewById(R.id.a_button);
button2 = (Button)findViewById(R.id.b_button);
button1.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
fakeButton1.onClick();
}
});
button2.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
fakeButton2.onClick();
}
});
如此一来, 我们可以在画面看到两个button,
http://uploadingit.com/file/wa6dhpapqo8ifzbs/button1.png
http://uploadingit.com/file/ak5fyrsmnhakrlmz/button2.png
当按下去的时候, 的确可以跑到我们一开始所期望的情况。
如果观念有错 请指教 谢谢:)
完整程式码
http://uploadingit.com/file/zqfevrlk7miglqqx/ButtonEventSimulateDemo.zip
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.221.115.4
1F:→ LaPass:很仔细 推 01/10 17:48
2F:推 tericky:推推推 01/10 18:07
3F:推 eplis:真的很实用,厘清好多观念 01/11 00:41
※ 编辑: givemepass 来自: 61.221.115.4 (01/11 10:30)
4F:推 godpro:感谢~又学习到了~! 01/13 22:35
5F:推 ENEP:实用 这篇该m! 01/16 17:47
6F:推 mamaya3:一讲到m文 就想到我们的版主空缺... 01/17 10:50