我想用PureMVC for Java实现这样一个Android程序:点击按钮,在两个EditText中显示一些内容和点击总次数。
于是,我开始写了(当然这是我最后修改的正常版):
res/layout/main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android:editable="false"> </EditText> <EditText android:id="@+id/editText2" android:textColor="#FF0000" android:layout_width="match_parent" android:layout_height="wrap_content" android:editable="false"> </EditText> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
表面类:
package com.iteye.weimingtom.pmvc.test;
import org.puremvc.java.interfaces.IFacade;
import org.puremvc.java.patterns.facade.Facade;
import android.widget.EditText;
public class MyFacade extends Facade implements IFacade {
public MyFacade() {
this.registerCommand(SetTextCommand.NAME, new SetTextCommand());
this.registerMediator(new TextMediator());
this.registerMediator(new SimpleTextMediator());
this.registerProxy(new MyProxy());
}
public void setupReceivers(EditText editText1, EditText editText2) {
((TextMediator) this.retrieveMediator(TextMediator.NAME)).setEditText(editText1);
((SimpleTextMediator) this.retrieveMediator(SimpleTextMediator.NAME)).setEditText(editText2);
}
}
代理数据(共享数据)类:
package com.iteye.weimingtom.pmvc.test;
import org.puremvc.java.interfaces.IProxy;
import org.puremvc.java.patterns.proxy.Proxy;
public class MyProxy extends Proxy implements IProxy {
public static final String NAME = "MyProxy";
public MyProxy() {
super(NAME, null);
}
public int clickNum = 0;
public int getClickNum() {
return clickNum;
}
public void setClickNum(int clickNum) {
this.clickNum = clickNum;
}
}
消息类:
package com.iteye.weimingtom.pmvc.test;
import org.puremvc.java.interfaces.ICommand;
import org.puremvc.java.interfaces.INotification;
import org.puremvc.java.patterns.command.SimpleCommand;
public class SetTextCommand extends SimpleCommand implements ICommand {
public static final String NAME = "SET_TEXT_COMMAND";
@Override
public void execute(INotification n) {
MyProxy proxy = (MyProxy)this.facade.retrieveProxy(MyProxy.NAME);
proxy.setClickNum(proxy.getClickNum() + 1);
}
}
中介类(有两个):
package com.iteye.weimingtom.pmvc.test;
import org.puremvc.java.interfaces.IMediator;
import org.puremvc.java.interfaces.INotification;
import org.puremvc.java.patterns.mediator.Mediator;
import android.widget.EditText;
public class TextMediator extends Mediator implements IMediator {
public final static String NAME = "TextMediator";
private EditText editText;
public TextMediator() {
super(NAME, null);
}
public void setEditText(EditText editText) {
this.editText = editText;
}
@Override
public String[] listNotificationInterests() {
return new String[]{
SetTextCommand.NAME
};
}
@Override
public void handleNotification(INotification n) {
if (SetTextCommand.NAME.equals(n.getName())) {
if (this.editText != null) {
this.editText.setText(
"name:" + n.getName() + "\n" +
"body:" + n.getBody() + "\n" +
"proxy data: clickNum = " + ((MyProxy)this.facade.retrieveProxy(MyProxy.NAME)).getClickNum());
}
}
}
}
package com.iteye.weimingtom.pmvc.test;
import org.puremvc.java.interfaces.IMediator;
import org.puremvc.java.interfaces.INotification;
import org.puremvc.java.patterns.mediator.Mediator;
import android.widget.EditText;
public class SimpleTextMediator extends Mediator implements IMediator {
public final static String NAME = "SimpleTextMediator";
private EditText editText;
public SimpleTextMediator() {
super(NAME, null);
}
public void setEditText(EditText editText) {
this.editText = editText;
}
@Override
public String[] listNotificationInterests() {
return new String[]{
SetTextCommand.NAME
};
}
@Override
public void handleNotification(INotification n) {
if (SetTextCommand.NAME.equals(n.getName())) {
if (this.editText != null) {
this.editText.setText(
"clickNum = " + ((MyProxy)this.facade.retrieveProxy(MyProxy.NAME)).getClickNum());
}
}
}
}
对接到界面后:
package com.iteye.weimingtom.pmvc.test;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class PureMVCTestActivity extends Activity {
private MyFacade facade = new MyFacade();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button1 = (Button) this.findViewById(R.id.button1);
EditText editText1 = (EditText) this.findViewById(R.id.editText1);
EditText editText2 = (EditText) this.findViewById(R.id.editText2);
facade.setupReceivers(editText1, editText2);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
facade.sendNotification(SetTextCommand.NAME, "button1, onClick");
}
});
}
}
最令我不解的是,如果直接把TextView引用传给registerMediator的TextMediator和SimpleTextMediator对象(作为它们的构造函数的参数),那么响应SetTextCommand的中介类所持有的TextView引用可能不是界面上的TextView引用,因为:
1. 在调试模式下,registerMediator传入的对象引用等于retrieveMediator得到的对象引用。
2. 在直接运行时,registerMediator传入的对象引用不等于retrieveMediator得到的对象引用。
所以,我用这种方式传递EditText引用。
public MyFacade() {
this.registerCommand(SetTextCommand.NAME, new SetTextCommand());
this.registerMediator(new TextMediator());
this.registerMediator(new SimpleTextMediator());
this.registerProxy(new MyProxy());
}
public void setupReceivers(EditText editText1, EditText editText2) {
((TextMediator) this.retrieveMediator(TextMediator.NAME)).setEditText(editText1);
((SimpleTextMediator) this.retrieveMediator(SimpleTextMediator.NAME)).setEditText(editText2);
}
而非在注册时传入:
//这样写可能有问题
public MyFacade(EditText editText1, EditText editText2) {
this.registerCommand(SetTextCommand.NAME, new SetTextCommand());
this.registerMediator(new TextMediator(editText1));
this.registerMediator(new SimpleTextMediator(editText2));
this.registerProxy(new MyProxy());
}