我想用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()); }