聯想et980小屏應用及輸入法的設計與開發
這篇文章中講述的內容來自於前幾個月我的乙個中途夭折的專案,專案的內容是為聯想的et980手機開發小屏應用和鍵盤輸入法。該手機基於windows mobile 5.0作業系統。下面是該手機的:
可以看到,該手機有乙個摺疊的鍵盤,鍵盤合上後遮住了一半螢幕,剩下的一半即是所謂的小屏:) 。
一.開發目標
開發的目標是為該小屏開發乙個好用的、可擴充套件的小屏應用系統,並配上乙個好用的鍵盤輸入法。
二.架構設計
看看這兩張處於半成品狀態的截圖:
下部黑色區域是被鍵盤遮住的部分我們不討論,就看上面部分,從上往下分為:狀態列區,其中顯示的狀態圖示可擴充套件增加,目前圖中可以看到的有時間和輸入法狀態,將來可以想到的有手機訊號、新簡訊等等;主視窗,分為三類,應用程式中心也就相當於是主選單,是各個應用程式的入口,應用程式視窗和螢幕保護;輸入法選字區;左右兩軟鍵顯示區。除此之外,還考慮到可能有不顯示任何介面的應用程式在執行,這類應用程式可能在需要的時候顯示各對話方塊什麼的,但一般都只在後台執行。
那麼為了要實現系統的可擴充套件性,系統的架構是如何設計的呢,請看下面的類圖:
這張類圖最關鍵的部分是左下角的這一塊,通過一些繼承,將前述所說的幾塊區域將要承載的控制項進行了描述。其中輸入法的介面也在這裡得到了描述。
這樣,作為第三方的開發人員,如果要開發相關的應用,如狀態列程式、主視窗程式、應用程式中心、螢幕保護、輸入法,就只需要從相應的類繼承即可。
類圖左上方的那些類則是用於對前述這些應用進行描述的,第三方開發人員開發好自己的程式之後需要遵循相應的規則在登錄檔中進行註冊,這樣,小屏系統就可以發現你的程式了。
三.一些技術細節
1. 如何監測小鍵盤的開合?其實是通過監測登錄檔實現的,軟體上檢視登錄檔項software/lenovo/keypadstatus,該項為0則表示蓋已翻開,對應gpio11中斷。
2.如何設定背景圖?我們知道.net cf的控制項是不支援背景圖的,那麼怎麼辦呢,我用如下的**:
首先重寫了panel控制項,這是提供整個螢幕的底圖:
protected
override
void onpaintbackground(painteventargs e)
}
但是這樣還不夠,因為上面放置的控制項會將這個panel遮住,所以我們就在controlbase (這個類在上面的類圖中可以找到)中寫入下的**:
protected
override
void onpaint(painteventargs e)
if (control is
mainpnl)
rectangle srcrect = new
rectangle(left, top, e.cliprectangle.width, e.cliprectangle.height);
if (backgroundimage != null)
} }
這樣就可以了 3
.……
四.小鍵盤輸入法
這個小鍵盤輸入法是拼音輸入法,實現了整句輸入、自動聯想、詞頻自動調整、自造詞、魔法1鍵等功能,具體的特性可以參看中文之星的職能狂拼,因為我在開發的時候基本上就是比照它來寫的。
1. 演算法上不多說,其實就是乙個樹搜尋。
2. 在候選框裡如何把侯選字顯示出來?其實也就是重寫控制項:
private
void pnllettersqueue_paint(object sender, painteventargs e)
//繪製游標前的未選定的字串
if (this.displaystringbeforekeysptr.length > 0)
//繪製游標指向的文字
if (this.displaystringinkeysptr.length > 0)
//繪製游標線
e.graphics.drawline(new
pen(color.red), (int)drawedleft, e.cliprectangle.top + 2, (int)drawedleft, e.cliprectangle.bottom - 2);
drawedleft += 2;
if (this.displaystringinkeysptr.length > 0)
//繪製游標後的文字
if (this.displaystringafterkeysptr.length > 0)
}
private
void pnlphrases_paint(object sender, painteventargs e)
//繪製數字
rectanglef rectfnumber = new
rectanglef(drawedleft, e.cliprectangle.top, numberwidth, e.cliprectangle.height);
e.graphics.drawstring((i + 1).tostring(), numberfont, new
solidbrush(color.red), rectfnumber);
drawedleft += (numberwidth); //
繪製文字
rectanglef rectfstring = new
rectanglef(drawedleft, e.cliprectangle.top, stringwidth, e.cliprectangle.height);
color stringcolor = (i == this.currentcandidatephrasesptr) ? color.white : color.black;
e.graphics.drawstring(this.candidatephraseses[currentpagedisplayptr][i].string, this.font, new
solidbrush(stringcolor), rectfstring);
drawedleft += (stringwidth + 4); }
} }
最後得到的效果可以看最前面的圖。
好了,就說這麼多了。如果哪位達人有興趣,可以與我深入**,我可以把源**公開出來:)。