public class Calculator extends Activity {
这行代码定义计算器类 Calculator是继承 Activity类。这是计算器主要管理类,从前面的XML资源里,就知道Calculator类是第一个运行的类,是运行代码的入口点。
下面开始创建和定义使用的变量和常量。
EventListener mListener = new EventListener();
private CalculatorDisplay mDisplay;
private Persist mPersist;
private History mHistory;
private Logic mLogic;
private PanelSwitcher mPanelSwitcher;
private static final int CMD_CLEAR_HISTORY = 1;
private static final int CMD_BASIC_PANEL = 2;
private static final int CMD_ADVANCED_PANEL = 3;
private static final int HVGA_HEIGHT_PIXELS = 480;
private static final int HVGA_WIDTH_PIXELS = 320;
static final int BASIC_PANEL = 0;
static final int ADVANCED_PANEL = 1;
private static final String LOG_TAG = "Calculator";
private static final boolean DEBUG = false;
private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
下面重载Activity类里的onCreate事件方法:
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
调用父类的方法运行。
setContentView(R.layout.main);
调用方法setContentView按 R.layout.main的配置进行窗口布局,也就是设置了窗口的显示方式。
mPersist = new Persist(this);
创建数据保存和加载对象, Persist类是本应用程序里用来保存和加载计算器输入的字符串,比如当计算器程序要暂停时,就需要把用户输入表达式字符串保存到存储里,以便恢复运行后再加载出来。
mHistory = mPersist.history;
获取保存用户已经输入的字符串对象。
mDisplay = (CalculatorDisplay) findViewById(R.id.display);
这里通资源ID找到CalculatorDisplay显示资源和窗口。 CalculatorDisplay窗口主要用来显示计算器计算参数和结果,以及用户输入的内容。
mLogic = new Logic(this, mHistory, mDisplay, (Button) findViewById(R.id.equal));
这里是创建逻辑处理对象,对于本应用程序就是计算器的逻辑处理,比如输入字符的响应,以及计算表达式的值。
HistoryAdapter historyAdapter = new HistoryAdapter(this, mHistory, mLogic);
创建查看历史的窗口。
mHistory.setObserver(historyAdapter);
设置历史查看的窗口。
View view;
mPanelSwitcher = (PanelSwitcher) findViewById(R.id.panelswitch);
创建计算器输入数字的面板,它是继承android.view.GestureDetector类,因此可以处理所有触摸事件。
mListener.setHandler(mLogic, mPanelSwitcher);
让输入面板与逻辑处理模块通过事件关联在一起。
mDisplay.setOnKeyListener(mListener);
显示窗口通过事件监听器获取事件显示。
if ((view = findViewById(R.id.del)) != null) {
// view.setOnClickListener(mListener);
view.setOnLongClickListener(mListener);
}
/*
if ((view = findViewById(R.id.clear)) != null) {
view.setOnClickListener(mListener);
}
*/
}
下面创建选项菜单。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuItem item;
item = menu.add(0, CMD_CLEAR_HISTORY, 0, R.string.clear_history);
item.setIcon(R.drawable.clear_history);
item = menu.add(0, CMD_ADVANCED_PANEL, 0, R.string.advanced);
item.setIcon(R.drawable.advanced);
item = menu.add(0, CMD_BASIC_PANEL, 0, R.string.basic);
item.setIcon(R.drawable.simple);
return true;
}
准备选项菜单。
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.findItem(CMD_BASIC_PANEL).setVisible(mPanelSwitcher != null &&
mPanelSwitcher.getCurrentIndex() == ADVANCED_PANEL);
menu.findItem(CMD_ADVANCED_PANEL).setVisible(mPanelSwitcher != null &&
mPanelSwitcher.getCurrentIndex() == BASIC_PANEL);
return true;
}
当选中菜单时响应。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case CMD_CLEAR_HISTORY:
mHistory.clear();
break;
case CMD_BASIC_PANEL:
if (mPanelSwitcher != null &&
mPanelSwitcher.getCurrentIndex() == ADVANCED_PANEL) {
mPanelSwitcher.moveRight();
}
break;
case CMD_ADVANCED_PANEL:
if (mPanelSwitcher != null &&
mPanelSwitcher.getCurrentIndex() == BASIC_PANEL) {
mPanelSwitcher.moveLeft();
}
break;
}
return super.onOptionsItemSelected(item);
}
保存实例状态。
@Override
protected void onSaveInstanceState(Bundle icicle) {
// as work-around for ClassCastException in TextView on restart
// avoid calling superclass, to keep icicle empty
}
暂停状态响应。
@Override
public void onPause() {
super.onPause();
mLogic.updateHistory();
mPersist.save();
}
按键按下响应。
@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& mPanelSwitcher.getCurrentIndex() == ADVANCED_PANEL) {
mPanelSwitcher.moveRight();
return true;
} else {
return super.onKeyDown(keyCode, keyEvent);
}
}
输出LOG调试信息。
static void log(String message) {
if (LOG_ENABLED) {
Log.v(LOG_TAG, message);
}
}
/**
* The font sizes in the layout files are specified for a HVGA display.
* Adjust the font sizes accordingly if we are running on a different
* display.
*/
调整字体的大小。
public void adjustFontSize(TextView view) {
float fontPixelSize = view.getTextSize();
Display display = getWindowManager().getDefaultDisplay();
int h = Math.min(display.getWidth(), display.getHeight());
float ratio = (float)h/HVGA_WIDTH_PIXELS;
view.setTextSize(TypedValue.COMPLEX_UNIT_PX, fontPixelSize*ratio);
}
}
//QQ: 9073204 EMAIL:[email protected]
//蔡军生 2011-05-29