FBReaderJ學習筆記(二):PopWindow實現自訂閱讀頁菜單,fbreaderjpopwindow
很少寫技術部落格,最常用的部落格還是Lofter這個:chacePM。非技術部落格。
另外基於FBReaderJ本人開發了一個閱讀器:悅讀。有興趣的朋友可以去安裝看看,支援一下。
以下是實現的菜單。
MainMenuPopup
注意:本文不涉及具體介面設計,只談思路。
1.結構
在正式動手改代碼前,我們最好先搞清楚幾個PopWindow的結構和繼承關係,因為FBReaderJ的封裝嚴密,容易走入死胡同。
整個跟popup相關的類結構大概就是這樣,其中紅色的為抽象類別。命名很清楚,我就不解釋每一個是幹嘛的了。
我們要實現自訂popwindow菜單,可以模仿NavigationPopup的做法,寫一個MainMenuPopup繼承自PopupPanel。
2.原理
我們開啟assets目錄,發現在下面的目錄裡定義了tapzones。
開啟down.xml,發現內容是這樣的。這下明白閱讀頁面的點擊事件是怎麼回事了吧,其實就是把整個地區劃分為九宮格,每個格子響應不同的事件。為了讓我們的菜單顯示,只要把這裡的menu全改成navigate,再在代碼裡實現navigate響應事件為顯示我們的自訂菜單。其實我們看到這裡是少了(1,1)地區的,不知道是原作者為什麼弄成這樣,為了更好的體驗,我們需要加上(1,1)也響應navigate。
3.兩個PopWindow同時顯示的解決方案
在我們的菜單裡,是同時包含頂部菜單和底部菜單,如何解決這個問題呢?
一種直觀的方式當然是弄兩個菜單,BottomMenuPopup和TopMenuPopup都繼承自PopupPanel,我最開始也是這麼想的,但是問題就來了,PopupPanel的顯示是用的Application.showPopup(ID)。代碼如下,發現在show之前會先調用hideActivePopup(),這樣我們show第二個Popup的時候會先把第一個Popup隱藏掉。
public final void showPopup(String id) { hideActivePopup(); myActivePopup = myPopups.get(id); if (myActivePopup != null) { myActivePopup.show_(); } }
我們當然可以把這行去掉,但這會導致我們每次顯示其他Popup的時候都得先調用hideActivePopup,出於少改動代碼的目的,我放棄了這種方法。
第二種方法是單獨弄一個TopMenuPopup而不繼承PopupPanel,但是我嘗試了一下後發現會更麻煩,什麼時候顯示什麼消失一團糟。
最後我想到的方法是,在PopupPanel裡面增加一個myWindowTop。這樣我們就有兩個PopupWindow,但是都顯示在一個PopupPanel子類裡,我們命名為MainMenuPopup。
protected volatile PopupWindow myWindow; protected volatile PopupWindow myWindowTop;
4.切換PopupPanel
上面解決了MainMenuPopup的顯示,但是其實我們是包含多個PopupPanel的,這就涉及到切換問題。我們以MainMenuPopup和NavigationPopup的切換為例。
下面的代碼是用來顯示NavigationPopup的,上面說過,在showPopup(ID)方法裡會先調用hideActivePopup(),所以這裡的切換不成問題。
((NavigationPopup)Application.getPopupById(NavigationPopup.ID)).runNavigation();
另一個問題是顯示和隱藏Popup,因為點擊書本,對應的都是navigate()方法,所以我們需要判斷點擊時到底該顯示還是隱藏。好在FBReaderJ已經有一個方法Application.getActivePopup()來獲得當前顯示的Popup,只要判斷是否為空白即可。所以在MainMenuPopup裡面的showBottomMenu()方法是這樣的。
public void showBottomMenu(){ if (myWindow == null || myWindow.getVisibility() == View.GONE){ if(Application.getActivePopup()==null){ Application.showPopup(ID); }else{ Application.hideActivePopup(); } }else{ Application.hideActivePopup(); } }
5.結語
現在的結構就是這樣了,增加了一個MainMenuPopup。
大致的流程就是更改tapzones->建立MainMenuPopup->新增myPopWindowTop->判斷顯示/隱藏popup。
到此思路基本已經理清了,開頭就說過,本文不涉及具體介面開發,開頭的僅作示範,千萬不要有上當受騙的感覺。
實現自訂菜單的方式有很多種。比如頂部的菜單可以用Actionbar來實現,FBReaderJ的ics版本就是這樣做的;或者在XML裡面直接在ZLViewWidget外放上底部和頂部菜單。本文的方法只是一種。我說的不明白的地方,以及不足之處,歡迎與我探討交流。
另外,基於FBReaderJ本人開發了一個閱讀器:悅讀。有興趣的朋友可以去安裝看看,支援一下。
下一篇講底部狀態列的自訂。