基于Andriod的閱讀軟件的設(shè)計(jì)與實(shí)現(xiàn)_第1頁(yè)
已閱讀5頁(yè),還剩46頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

基于Andriod的閱讀軟件的設(shè)計(jì)與實(shí)現(xiàn)摘要:隨著智能化電子化水平的提高,電子閱讀方式已經(jīng)漸漸成為現(xiàn)代人主要的閱讀方式。電子閱讀器相比于傳統(tǒng)書籍具有方便快捷、存儲(chǔ)容量大,易于操作等優(yōu)點(diǎn)。本系統(tǒng)利用Google的Andriod集成開發(fā)環(huán)境ADT進(jìn)行開發(fā)。文章首先介紹了課題的研究背景以及Andriod開發(fā)的相關(guān)技術(shù)理論。闡述在開發(fā)過(guò)程中對(duì)系統(tǒng)進(jìn)行的詳細(xì)的需求分析,根據(jù)需求分析結(jié)果對(duì)系統(tǒng)做出總體設(shè)計(jì)。然后著重介紹了該電子閱讀器在本地書柜、在線書庫(kù)、白天模式和黑夜模式、屏幕方向、字體加大縮小以及翻頁(yè)功能的模塊的設(shè)計(jì)與實(shí)現(xiàn)。最后對(duì)本次設(shè)計(jì)做出總結(jié)與展望。關(guān)鍵詞:Andriod開發(fā);電子閱讀軟件;Java Abstract:Withtheimprovementofintelligentelectroniclevel,EBookreadinghasgraduallybecomethemainreadingwayinourlife.ElectronicReadersaremoreconvenientandlargerstoredcomparedwiththetraditionalbooks.Besidesitiseasytooperate.ThissystemisbasedonGoogle'sandroidADT.ItisanintegrationdevelopmentenvironmentforAndrioddevelopment.Thisarticleisconsistsofthefollowingparts.Thefirstparagraphintroducestheresearchbackgroundandthedevelopmentoftheandroidalongwiththerelatedtechnicaltheory.Thesecondparagraphexpoundsthedevelopmentprocessaboutthedemandanalysis.Thethirdexpoundstheoveralldesignaboutthesystembasedonthedemandanalysis.Then,theforthparagraphintroducedthefunctionsoftheelectronicreaderonlocalbookcase,onlinelibrary,dayandnightscreendirection,fontincreaseanddecreaseandturnpagerightandleft.Finallymakeasummaryandoutlookofthedesign.Keywords:AndriodDevelopment;Electronicreaders;Java第1章緒論電子閱讀的方式已經(jīng)成為現(xiàn)代人生活中的主要閱讀方式,隨著智能手機(jī)的普及,市場(chǎng)上出現(xiàn)了各種各樣的電子閱讀器。Andriod系統(tǒng)作為智能手機(jī)操作系統(tǒng)中的佼佼者,其本身具有的平臺(tái)的開放性,以及各開發(fā)組件的成熟性等優(yōu)點(diǎn),給熱衷于Andriod應(yīng)用開發(fā)的愛(ài)好者們提供了一個(gè)很好的平臺(tái)。1.1課題研究背景及意義自1993年世界上第一款智能觸屏手機(jī)“Simon”出現(xiàn)后,智能手機(jī)市場(chǎng)便呈指數(shù)趨勢(shì)迅速發(fā)展。2013年至2015年期間,智能手機(jī)已基本完成與傳統(tǒng)按鍵機(jī)的更新?lián)Q代。智能手機(jī)人性化、智能化的特點(diǎn)改變了人們以往的生活方式。開放的操作系統(tǒng)使得人們可以隨心所欲安裝自己所需的應(yīng)用程序??v觀我們的周邊,電子閱讀軟件已經(jīng)在我們的生活中相當(dāng)?shù)钠占?。其方便快捷電子化的特征逐漸改變?nèi)藗兊膫鹘y(tǒng)閱讀方式。紙質(zhì)書受限于物理空間的大小不方便攜帶也不方便閱讀,但是電子閱讀器只需帶手機(jī)或擁有智能設(shè)備便可觀看閱讀。紙質(zhì)書受限于空間環(huán)境的變化,沒(méi)有光線的地方便無(wú)法閱讀,電子書只需智能設(shè)備有電,便可自主調(diào)節(jié)亮度背景顏色。在現(xiàn)代化電子化的環(huán)境下,電子閱讀器越來(lái)越受群眾的歡迎。而安卓手機(jī)市場(chǎng)又占手機(jī)市場(chǎng)極高的份額,所以基于Android的閱讀軟件的設(shè)計(jì)是極具市場(chǎng)意義的。1.2國(guó)內(nèi)外研究現(xiàn)狀電子閱讀器這一概念早在二十世紀(jì)七十年代便由美國(guó)布朗大學(xué)的軟件工程師提出[1]。隨后,美國(guó)SoftBook公司便推出了市場(chǎng)上第一款電子閱讀軟件“RocketBook”,該款電子書采用與計(jì)算機(jī)串口相連的方式實(shí)現(xiàn)電子書的購(gòu)買與下載。2008年8月,微軟推出了一款名為“MicrosoftReader”的電子于都軟件,該款閱讀器使用微軟的字符顯示ClearType技術(shù)[2],使得顯示屏的清晰度和分辨率大大提高,電子閱讀器具有了更好的觀看體驗(yàn)。目前,市場(chǎng)上比較流行的安卓手機(jī)閱讀器主要有以下幾款:1、iReader:該款手機(jī)閱讀器支持TXT,UMD,HTML,PDF等多種書籍格式,支持書簽、全屏、白天黑夜模式、備份觀看歷史等多種功能,并且具有多種翻頁(yè)特效;2、QQ閱讀:該款閱讀器由盛大公司出品,簡(jiǎn)單實(shí)用,可個(gè)性化更改皮膚,同樣支持書簽、全屏、文本設(shè)置等功能[3]。3、百閱:該款閱讀器的特點(diǎn)在于能及時(shí)撰寫書評(píng)并且同步微博,給讀者帶來(lái)社交互動(dòng)的良好體驗(yàn)。4、盛大云中書城:該款閱讀器UI界面清爽,同步紅袖添香、瀟湘書院等多閱讀網(wǎng)站,適合多層次年齡段的讀者。其他比較主流的閱讀器還有“起點(diǎn)讀書”、“靜讀天下”、“91熊貓看書”等。雖然市場(chǎng)上的電子閱讀軟件種類多種樣,功能比較完善,但是依然無(wú)法完全滿足讀者需求,長(zhǎng)時(shí)間閱讀后較為疲勞,所以電子閱讀軟件領(lǐng)域還有較大的研究空間。1.3論文主要內(nèi)容及組織結(jié)構(gòu)本文共分為六個(gè)章節(jié),各章節(jié)內(nèi)容安排如下:緒論,介紹了課題的研究背景及意義,國(guó)內(nèi)外研究現(xiàn)狀以及本文的組織結(jié)構(gòu)安排。Andriod應(yīng)用開發(fā)環(huán)境介紹,介紹了Android系統(tǒng)及架構(gòu),Andriod的基本組件,以及本系統(tǒng)的開發(fā)工具和平臺(tái)。電子閱讀軟件需求分析,主要對(duì)電子閱讀軟件在書籍管理需求方面、書籍編輯需求方面、書籍閱讀需求方面以及界面交互需求方面進(jìn)行分析。電子閱讀軟件總體設(shè)計(jì),包括系統(tǒng)的功能設(shè)計(jì)、系統(tǒng)的流程設(shè)計(jì)以及數(shù)據(jù)庫(kù)設(shè)計(jì)。電子閱讀軟件詳細(xì)設(shè)計(jì),包括系統(tǒng)流程詳細(xì)設(shè)計(jì)以及系統(tǒng)功能的詳細(xì)設(shè)計(jì)。總結(jié)與展望。對(duì)系統(tǒng)設(shè)計(jì)的總結(jié)以及功能拓展的設(shè)想。第2章Andriod應(yīng)用開發(fā)環(huán)境介紹2.1Android系統(tǒng)及架構(gòu)介紹Android系統(tǒng),由Google公司開發(fā),是一款基于Linux且開源的手機(jī)操作系統(tǒng),其版本經(jīng)歷了從Andriod1.1到Andriod4.4的演變,本系統(tǒng)的設(shè)計(jì)版本要求為Andriod4.0及以上版本[4]。Andriod的系統(tǒng)組織架構(gòu)類似于操作系統(tǒng),采用分層的架構(gòu)[5],從高層到底層分為為:應(yīng)用程序?qū)印?yīng)用程序框架層、系統(tǒng)運(yùn)行層和Linux內(nèi)核層。應(yīng)用程序?qū)影幌盗袘?yīng)用程序包(客戶端,SMS短消息程序,瀏覽器、管理程序等);應(yīng)用程序框架中包含了每個(gè)應(yīng)用后面隱藏的一系列服務(wù)機(jī)制,包括視圖(View)、內(nèi)容提供器(ContentProviders)、資源管理器(ResourceManager)、通知管理器(NotificationManager)、活動(dòng)管理器(ActivityManager),開發(fā)人員可以通過(guò)訪問(wèn)應(yīng)用程序的API框架實(shí)現(xiàn)應(yīng)用程序的各功能模塊;系統(tǒng)運(yùn)行層包含一些C/C++庫(kù),這些庫(kù)能被Andriod系統(tǒng)中不同的組件使用,這些函數(shù)庫(kù)包括系統(tǒng)C庫(kù),一個(gè)從BSD繼承來(lái)的標(biāo)準(zhǔn)C函數(shù)庫(kù)Libc;媒體功能庫(kù),支持多種常用格式的音頻錄制播放等;2D和3D圖形庫(kù);用于點(diǎn)陣和矢量字體渲染的FreeType以及SQLite引擎等;Linux內(nèi)核層則提供內(nèi)存管理、進(jìn)程管理、軟硬件連接等服務(wù)。2.2Andriod基本組件介紹一個(gè)Andriod應(yīng)用程序是以java編程語(yǔ)言為基礎(chǔ)[6],通過(guò)Andriod組件Activity之間的相互跳轉(zhuǎn),并且利用Intent實(shí)現(xiàn)多程序運(yùn)行的。在一個(gè)應(yīng)用程序中,主要用到以下幾種Andriod組件:Activity、Service、BroadcastReceiver、ContentProvider、Intent。2.2.1Activity(活動(dòng))Activity是一個(gè)用戶界面的基類[7],它為用戶提供了與應(yīng)用程序交互的窗口,相當(dāng)于C/S程序中的窗體(Form)或Web程序的頁(yè)面。Activity窗口中的可視化組件由View及其子類組成,這些組件按著XML布局文件中指定的位置排放。一個(gè)Activity狀態(tài)回調(diào)分別通過(guò)“onCreate”進(jìn)行創(chuàng)建、“onStart”進(jìn)行激活、“onResume”進(jìn)行恢復(fù)、“onPause”進(jìn)行暫停、“onStop”進(jìn)行停止、“onDestroy”進(jìn)行銷毀、“onRestart”進(jìn)行重啟。2.2.2Service(服務(wù))Service沒(méi)有可見的用戶界面,但是能夠在后臺(tái)長(zhǎng)時(shí)間運(yùn)行。例如,當(dāng)用戶在進(jìn)行其他操作時(shí),便可利用Service在后臺(tái)進(jìn)行播放音樂(lè)等操作。Service是不能自己?jiǎn)?dòng)的,必須通過(guò)Context對(duì)象(如一個(gè)Activity)調(diào)用startService或bindService方法來(lái)啟動(dòng)。2.2.3BroadcastReceiver(廣播接受器)BroadcastReceiver是一個(gè)用于接受廣播通知的組件,如手機(jī)時(shí)區(qū)變化、電池電量低等系統(tǒng)或其他應(yīng)用程序的廣播通知。當(dāng)BroadcastReceiver接受到廣播后自身并不實(shí)現(xiàn)用戶界面的變化,而是通過(guò)啟動(dòng)相應(yīng)的Activity作出響應(yīng),或者通過(guò)NotificationMananger提醒用戶。2.2.4ContentProvider(內(nèi)容提供者)ContentProvider用于將存儲(chǔ)在文件系統(tǒng)、SQLite數(shù)據(jù)庫(kù)或其他合理內(nèi)存中的數(shù)據(jù)提供給應(yīng)用程序。ContentProvider繼承自基類ContentProvider,并實(shí)現(xiàn)了一個(gè)標(biāo)準(zhǔn)方法集,使得其他應(yīng)用程序可以檢索和存儲(chǔ)數(shù)據(jù)。2.2.5IntentIntent是連接上述各組件之間的重要紐帶。Andriod通過(guò)Intent類來(lái)實(shí)現(xiàn)各活動(dòng)之間的切換以及組件的調(diào)用。不同類型的Intent消息不會(huì)出現(xiàn)重疊,Android會(huì)準(zhǔn)確找到與之相匹配的一個(gè)或多個(gè)Activity、Service或BroadcastReceive作出響應(yīng)。2.3系統(tǒng)開發(fā)工具介紹本系統(tǒng)開發(fā)用到的開發(fā)工具為:JDK8.0ADT-Bundle:ADT-Bundle是由GoogleAndriod官方提供集成開發(fā)環(huán)境(IDE),其中包含了Eclipse,AndriodSDK以及Android開發(fā)所需的平臺(tái)工具。第3章電子閱讀軟件需求分析電子閱讀軟件需求分析主要分為以下幾個(gè)部分:書籍管理需求分析、書籍編輯需求分析、書籍閱讀需求分析、界面交互需求分析。3.1書籍管理需求分析書籍管理需求主要有用戶在該電子閱讀軟件上對(duì)書籍的添加、刪除、查找等操作。用戶可以根據(jù)自己的喜好在電子閱讀器中加載所需的圖書或閱讀文本。其實(shí)現(xiàn)可通過(guò)本地SD卡查找導(dǎo)入渲染,在線書城鏈接等方式。用戶也可進(jìn)行一定的管理操作[8]。同時(shí),可通過(guò)查找對(duì)指定書籍進(jìn)行快速查找導(dǎo)入。書籍管理需求分析如表3-1所示。表3-1書籍管理需求分析參與者用戶概述用戶點(diǎn)擊添加、刪除、查詢,書籍被添加、刪除、查詢前置條件點(diǎn)擊相應(yīng)按鈕,動(dòng)作被記錄詳細(xì)描述用戶點(diǎn)擊相應(yīng)的操作按鈕活動(dòng)跳轉(zhuǎn)相應(yīng)的操作選項(xiàng)點(diǎn)擊實(shí)現(xiàn)預(yù)期操作后置條件書籍添加成功、刪除成功、查詢成功3.2書籍編輯需求分析書籍編輯需求主要有對(duì)書籍文字字體和大小的調(diào)整、書簽的刪除添加操作[9]等。書簽的添加刪除操作需求分析如表3-2所示。表3-2書簽操作需求分析參與者用戶概述用戶點(diǎn)擊添加、刪除書簽,書簽被添加、刪除前置條件點(diǎn)擊相應(yīng)按鈕,動(dòng)作被記錄詳細(xì)描述1、用戶點(diǎn)擊書簽操作按鈕2、界面跳轉(zhuǎn)書簽操作選項(xiàng)3、點(diǎn)擊實(shí)現(xiàn)預(yù)期操作后置條件書簽添加成功、刪除成功3.3書籍閱讀需求分析書籍閱讀需求主要包括用戶在進(jìn)行書籍閱讀時(shí)對(duì)書籍的背景顏色,屏幕亮度,文本顯示方向等的要求。用戶可以根據(jù)白天和黑夜不同的閱讀時(shí)間段選擇“白底黑字”“黑底白字”不同的閱讀模式對(duì)眼睛起保護(hù)作用,也可根據(jù)外部光線調(diào)節(jié)屏幕亮度[10]。同時(shí)可根據(jù)手機(jī)放置方向選擇合適的文本顯示方向。其中背景設(shè)置需求分析如下表3-3所示。表3-3背景設(shè)置需求分析參與者用戶概述用戶點(diǎn)擊“白底黑字”,界面變?yōu)椤鞍椎缀谧帧鼻爸脳l件點(diǎn)擊相應(yīng)按鈕,動(dòng)作被記錄詳細(xì)描述1、用戶點(diǎn)擊“白底黑字”操作按鈕2、界面變?yōu)榘椎缀谧趾笾脳l件屏幕變?yōu)椤鞍椎缀谧帧?.4界面交互需求分析界面交互需求主要包括用戶在閱讀過(guò)程中對(duì)翻頁(yè)動(dòng)畫、頁(yè)面切換效果、閱讀進(jìn)度顯示等的要求[11]。電子閱讀軟件需要有良好的UI界面和操作動(dòng)畫[12],使電子閱讀軟件模擬能真實(shí)的翻頁(yè)效果,同時(shí)記錄用戶的閱讀進(jìn)度。其中電子閱讀器的動(dòng)畫翻頁(yè)需求分析如表3-4所示。表3-4動(dòng)畫翻頁(yè)需求分析參與者用戶概述用戶向左/右滑動(dòng)屏幕,書頁(yè)向左、右翻動(dòng)前置條件點(diǎn)擊相應(yīng)按鈕,動(dòng)作被記錄詳細(xì)描述1、用戶向左/右滑動(dòng)屏幕2、書頁(yè)向左/右翻動(dòng)后置條件翻頁(yè)成功第4章電子閱讀軟件總體設(shè)計(jì)對(duì)于電子閱讀軟件的模塊設(shè)計(jì)建立在對(duì)其進(jìn)行需求分析的基礎(chǔ)上[13],概括出各大主要功能模塊。同時(shí),結(jié)合用戶閱讀習(xí)慣及潛在需求,對(duì)各大功能模塊進(jìn)行細(xì)化,從而實(shí)現(xiàn)該電子閱讀軟件的總體設(shè)計(jì)。4.1功能模塊設(shè)計(jì)4.1.1軟件主要功能模塊設(shè)計(jì)本系統(tǒng)設(shè)計(jì)的電子閱讀軟件包含四大主要功能模塊,分別是:書籍管理模塊、書籍編輯模塊、書籍閱讀模塊和閱讀交互模塊[14]。其中,書籍管理模塊中包含書籍的添加、下載、排序等功能設(shè)計(jì)。書籍編輯模塊主要實(shí)現(xiàn)書簽、閱讀時(shí)頁(yè)面字體排版等功能。書籍閱讀模塊包含書籍的呈現(xiàn)方式(屏幕方向設(shè)置)、字體的加大縮小操作[15]、以及背景色的設(shè)置等。閱讀交互模塊主要包含閱讀的進(jìn)度條設(shè)置、翻閱動(dòng)畫效果、翻閱速度以及快速翻看等功能設(shè)置。功能模塊結(jié)構(gòu)如圖4.1所示。圖4.1軟件主要功能模塊設(shè)計(jì)4.1.2書籍管理模塊設(shè)計(jì)在書籍管理模塊中要實(shí)現(xiàn)對(duì)電子書籍的增加、刪除、整理等功能,在該功能模塊中,本系統(tǒng)設(shè)置了“本地書庫(kù)”、“在線書庫(kù)”兩大書籍添加模塊,在“本地書庫(kù)”的子功能中設(shè)計(jì)了書籍管理模塊,可將書籍按“最愛(ài)的書”、“最近閱讀”、“按作者”、“按書名”、“按系列”、“按標(biāo)簽”進(jìn)行整理排序。在“在線書庫(kù)”的子功能模塊中同時(shí)設(shè)置了“管理書庫(kù)”“添加在線書籍”的功能模塊。書籍管理模塊的功能設(shè)計(jì)如圖4.2所示。圖4.2書籍管理模塊功能設(shè)計(jì)4.1.3書籍編輯模塊設(shè)計(jì)書籍編輯模塊中主要實(shí)現(xiàn)書簽的相關(guān)操作,包括添加、刪除、打開書簽以及頁(yè)面排版的相關(guān)操作,包括文本的字體、行間距、對(duì)齊方式的操作。書籍編輯模塊的功能設(shè)計(jì)如圖4.3所示。圖4.3書籍編輯模塊設(shè)計(jì)4.1.4書籍閱讀模塊設(shè)計(jì)書籍閱讀模塊中主要包括屏幕方向設(shè)置和字體的放大縮小設(shè)置。其中屏幕方向設(shè)置包括獲取默認(rèn)系統(tǒng)方向設(shè)置、感知設(shè)備方向設(shè)置、以及豎直(豎直反置)和水平(水平反置)的設(shè)置。書籍閱讀模塊功能設(shè)計(jì)如圖4.4所示。圖4.4書籍閱讀模塊設(shè)計(jì)4.1.5閱讀交互模塊設(shè)計(jì)閱讀交互模塊設(shè)計(jì)包括閱讀過(guò)程中的翻閱操作,包括翻閱動(dòng)畫,自動(dòng)翻頁(yè)等選擇;快速翻看操作,用于用戶對(duì)書籍的快速瀏覽;進(jìn)度條功能,用于顯示用戶的閱讀進(jìn)度。閱讀交互模塊的具體設(shè)計(jì)如圖4.5所示。圖4.5閱讀交互模塊設(shè)計(jì)4.1.6系統(tǒng)功能模塊本系統(tǒng)設(shè)計(jì)的電子閱讀軟件由上述主要功能模塊以及子功能模塊組成。在設(shè)計(jì)過(guò)程中通過(guò)自頂向下的設(shè)計(jì)方法對(duì)閱讀軟件的功能進(jìn)行細(xì)化。最終將該系統(tǒng)的功能模塊分為以下幾大部分。如圖4.6所示。圖4.6系統(tǒng)功能模塊圖4.2系統(tǒng)流程設(shè)計(jì)電子閱讀軟件從打開到可以觀看要經(jīng)過(guò)以下幾個(gè)流程[16]:程序進(jìn)入主Activity之前完成對(duì)數(shù)據(jù)庫(kù)配置、載入系統(tǒng)默認(rèn)加載文檔[17]、初始化界面打開時(shí)屏幕亮度,字體高亮等等。這些事件都是在聲明Application中實(shí)現(xiàn)的。要實(shí)現(xiàn)本系統(tǒng)的初識(shí)化具體操作如下(默認(rèn)加載小說(shuō)盜墓筆記):首先在配置文件AndriodMainfest.xml中聲明本系統(tǒng)的application:<applicationandroid:name="org.geometerplus.android.hxwreader.hxwReaderApplication"然后在FBReaderApplication文件中聲明初始化程序的入口:importorg.geometerplus.zhulibrary.dao_mu.ui.android.library.hxwAndroidApplication;最后在ZLAndriodApplication中進(jìn)行聲明,創(chuàng)建一個(gè)config.db,其目的是用來(lái)初始化一個(gè)圖片管理類,并且獲取信息。實(shí)現(xiàn)如下:publicabstractclassZLAndroidApplicationextendsApplication{ @Override publicvoidonCreate(){ super.onCreate(); newZhuLSQLiteConfig(this); newZhuLAndroidImageManager(); newZhuLAndroidLibrary(this); }}進(jìn)入主程序,尋找一個(gè)主Activity[18],本系統(tǒng)中將程序的入口設(shè)為一個(gè)WelcomeActivity,其代碼實(shí)現(xiàn)如下:<activityandroid:name="org.geometerplus.android.hxwreader.custom.activity.Welcome_Activity"> <intent-filter> <actionandroid:name="ent.action.MAIN"/> <categoryandroid:name="ent.category.LAUNCHER"/> </intent-filter> </activity>進(jìn)入系統(tǒng)主界面后,便需要生成一個(gè)Book對(duì)象。在openBook函數(shù)中引用mybook類。記錄用戶已經(jīng)添加到書架的書籍,若myBook不為空,按照相應(yīng)的書籍存放路徑BOOK_KEY或者BOOKMARK_KE對(duì)應(yīng)的入口查找并打開書籍。privatesynchronizedvoidopen_Book(Intentintent,Runableaction,booleanforce){ if(!force&&myBook!=null){ return; } myBook=SerializerUtil.deserializeBook(intent.getStringExtra(BOOKMARK_KEY)); finalBookmarkbookmark= SerializerUtil.deserializeBookmark(intent.getStringExtra(BOOKMARK_KEY)); StringfromIntentBookKey=intent.getStringExtra(BOOK_KEY); if(!TextUtils.isEmpty(fromIntentBookKey)){ myBook=createBookForFile(ZLFile.createFileByPath(fromIntentBookKey)); }else{ if(myBook==null){ finalUridata=intent.getData(); if(data!=null){ myBook=createBookForFile(ZLFile.createFileByPath(data.getPath())); } } }獲取并打開文件后需要將數(shù)據(jù)保存到一個(gè)MODELZH中[19],所以接下來(lái)系統(tǒng)將要生成一個(gè)Model對(duì)象,本系統(tǒng)在生成數(shù)據(jù)Model對(duì)象時(shí),利用open_BookInternal(book,null)函數(shù)將book向下傳遞的。具體代碼實(shí)現(xiàn)如下:publicabstractclassBookModel{ publicstaticBookModelcreateModel(Bookbook)throwsBookReadingException{ finalFormatPluginplugin=book.getPlugin(); System.err.println("usingplugin:"+plugin.supportedFileType()+"/"+plugin.type()); finalBookModelmodel; switch(plugin.type()){ caseNATIVE: model=newNativeBookModel(book); break; caseJAVA: model=newJavaBookModel(book); break; default: thrownewBookReadingException("unknownPluginType",plugin.type().toString(),null); } Plugin.read_Model(model); returnmodel; }5、第四步中將數(shù)據(jù)保存到一個(gè)MODEL中之后,系統(tǒng)接下來(lái)就需要將MODEL中保存的數(shù)據(jù)取出來(lái),渲染到畫布中。本系統(tǒng)的畫布是通過(guò)一個(gè)自定義的VIEW,來(lái)顯示文字、圖像、超鏈接等信息,在VIEW中定義兩個(gè)paint函數(shù),其中一個(gè)函數(shù)用來(lái)實(shí)現(xiàn)與FooterArea的接口,另一個(gè)函數(shù)用來(lái)繪制閱讀界面。這樣,一個(gè)閱讀界面的渲染便可以實(shí)現(xiàn)了[20]。渲染部分代碼如下: ZhuLAndroidPaintContext(Canvascanvas,intwidth,intheight,intscrollbarWidth){...} privatestaticZhuLFileWallpaper_File; privatestaticBitmapWallpaper; @Override publicvoidclear(ZLFilewallpaperFile,WallpaperModemode){...} @Override publicvoidclear(ZLColorcolor){...} @Override publicZLColorgetBackgroundColor(){...} publicvoiddrawPolygonalLine(int[]xs,intys[]){...} @Override protectedvoidset_Font_Internal(Stringfamily,intsize,booleanbold,booleanitalic,booleanunderline,booleanstrikeThrought){...} @Override publicvoidsetTextColor(ZLColorcolor){...} @Override publicvoidsetLineColor(ZLColorcolor){...} @Override publicvoidsetLineWidth(intwidth){...} @Override publicvoidsetFillColor(ZLColorcolor,intalpha){...} @Override publicintgetStringWidth(char[]string,intoffset,intlength){...} @Override protectedintgetSpaceWidthInternal(){...} @Override protectedintgetStringHeightInternal(){...} @Override protectedintgetDescentInternal(){...} @Override publicvoiddrawString(intx,inty,char[]string,intoffset,intlength){...} @Override publicSizeimageSize(ZLImageDataimageData,SizemaxSize,ScalingTypescaling){...} @Override publicvoiddrawImage(intx,inty,ZLImageDataimageData,SizemaxSize,ScalingTypescaling,ColorAdjustingModeadjustingMode){...} @Override publicvoiddrawLine(intx0,inty0,intx1,inty1){...}綜上所述,本系統(tǒng)的流程設(shè)計(jì)如圖4.7所示。圖4.7系統(tǒng)流程圖設(shè)計(jì)4.3系統(tǒng)數(shù)據(jù)庫(kù)設(shè)計(jì)4.3.1Andriod內(nèi)置數(shù)據(jù)庫(kù)SQLite概述本文2.1章中提過(guò),Android系統(tǒng)中內(nèi)嵌了小型數(shù)據(jù)庫(kù)SQLite。SQLite是一款遵守ACID的關(guān)聯(lián)式數(shù)據(jù)庫(kù)管理系統(tǒng),支持NULL、INTEGER、REAL、TEXT和BLOB五種數(shù)據(jù)類型,當(dāng)SQLite在解析CREATETABLE語(yǔ)句時(shí),會(huì)忽略CREATETABLE語(yǔ)句中在字段名后面的數(shù)據(jù)類型。大多數(shù)情況下,Andriod中的數(shù)據(jù)庫(kù)默認(rèn)是私有的,只供當(dāng)前應(yīng)用程序訪問(wèn)。SQLite內(nèi)部結(jié)構(gòu)圖如圖4.8所示。圖4.8SQLite內(nèi)部結(jié)構(gòu)圖在Andriod開發(fā)過(guò)程中,Activity通過(guò)ContentProvider或Service訪問(wèn)數(shù)據(jù)庫(kù)。但是Android不自動(dòng)提供數(shù)據(jù)庫(kù),需要在SQLite中自己創(chuàng)建數(shù)據(jù)庫(kù)。在Andriod中創(chuàng)建數(shù)據(jù)庫(kù)需要繼承SQLiteOpenHelper類,具體代碼如下:publicclassDatabaseHelperextendsSQLiteOpen_Helper{

DatabaseHelper(Contextcontext,Stringname,CursorFactorycursorFactory,intversion)

{

super(context,name,cursorFactory,version);

}

@Override

publicvoidonCreate(SQLite_Databasedb){

}

@Override

publicvoidonUpgrade(SQLite_Databasedb,intoldVersion,intnewVersion){

}

@Override

publicvoidonOpen(SQLiteDatabasedb){

super.onOpen(db);

}

}4.3.2系統(tǒng)涉及的數(shù)據(jù)結(jié)構(gòu)分析本系統(tǒng)中設(shè)計(jì)的數(shù)據(jù)主要包括書籍信息、書簽信息、最近閱讀信息。其中,書籍信息包括書名、語(yǔ)言、書文信息(存儲(chǔ)路徑)。書簽信息包括書簽內(nèi)容、書簽章節(jié)、書簽保存時(shí)間。最近閱讀信息包括最近閱讀書名。本系統(tǒng)的具體數(shù)據(jù)結(jié)構(gòu)描述如下表4-1所示。表4-1系統(tǒng)數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)名描述組成書籍書籍信息書名、語(yǔ)言、文本信息書簽書簽信息書簽內(nèi)容、書簽章節(jié)、書簽保存時(shí)間最近閱讀最近閱讀信息最近閱讀書名第5章電子閱讀軟件詳細(xì)設(shè)計(jì)5.1系統(tǒng)流程詳細(xì)設(shè)計(jì)5.1.1初始化子線程的建立在用戶點(diǎn)擊閱讀軟件圖標(biāo),軟件作出響應(yīng)時(shí)起,系統(tǒng)便會(huì)在主線程中建立一個(gè)子線程,該子線程負(fù)責(zé)在后臺(tái)讀取epub文件,并進(jìn)行一系列的初始化工作。子線程的創(chuàng)建通過(guò)下述步驟實(shí)現(xiàn)的。首先在AndriodManifes.xml配置文件中聲明系統(tǒng)首先進(jìn)入FBReader類,該類繼承自父類ZLAndriodActivity。代碼如下圖5.1所示:圖5.1聲明主類接著在hxwReader類中創(chuàng)建一個(gè)on_Create的方法,利用該方法可以來(lái)觸發(fā)父類ZLAndriodActivity類中的onCreate方法,在父類中的onCreate方法中設(shè)置了對(duì)系統(tǒng)的一系列初始化工作以及利用ZLApplication類的子類FBReaderApp類中的initWindow方法建立子線程。其他的初始化工作包括設(shè)置程序?yàn)槿聊J?,用ViewZLAndriodWidget類設(shè)置程序的界面,調(diào)用ZLAndriodLibrary類的setActivity方法,為ZLAndriodLibrary類里面的myActivity變量賦值等。具體代碼實(shí)現(xiàn)如下圖5.2所示圖5.2父類ZLAndriodActivity中的onCreate方法5.1.2系統(tǒng)資源文件的解析系統(tǒng)在讀取XML文件的過(guò)程中需要涉及三個(gè)核心類:ZMLZMLProcessor、ZLXMLParser、ZLXMLReader以及ZLTreeReaource。在解析資源的過(guò)程中這三個(gè)核心類的調(diào)用流程設(shè)計(jì)如下:1、首先,子類Resource_Tree_Reader類里面的read方法調(diào)用ZLXMLProcessor類的read方法該類繼承自Adapter抽象類;2、接著,通過(guò)ZLXMLProcessor類的read方法通過(guò)AndroidAssetsFile類ZLResourceFile類的子類的getInputStream方法獲取一個(gè)針對(duì)資源文件的字節(jié)流類AssetInputStream類,并以這個(gè)字節(jié)流類為參數(shù)初始化了一個(gè)針對(duì)資源文件的字符流類。接著,再調(diào)用了ZLXMLParser類的doIt方法。3、然后,ZLXMLParser類的doIt方法就會(huì)利用字符流類將文件轉(zhuǎn)換成一個(gè)char數(shù)組。再利用for循環(huán)迭代byte數(shù)組的過(guò)程中,doIt方法又反過(guò)來(lái)調(diào)用ZLXMLReaderAdapter抽象類的子類(ResourceTreeReader類)的startElementHandler與endElementHandler方法對(duì)byte數(shù)組中元素所代表的不同節(jié)點(diǎn)進(jìn)行操作。5.2系統(tǒng)功能詳細(xì)設(shè)計(jì)在第四章的總體設(shè)計(jì)中對(duì)閱讀軟件的系統(tǒng)功能做出了闡述,本系統(tǒng)的功能設(shè)計(jì)主要有“本地書柜”、“在線書庫(kù)”、“日間模式/夜間模式”、“屏幕方向”、“書簽”、“字體加大/縮小”和“翻頁(yè)”這些功能。系統(tǒng)功能界面菜單如下圖5.3所示。圖5.3系統(tǒng)功能菜單5.2.1本地書柜在本地書柜中提供了在本地文件夾中查找并導(dǎo)入書籍,以及對(duì)書籍按照“最愛(ài)”、“作者”、“系列”等分類的書籍管理功能,該功能主要涉及LibraryActivity文件。本地書柜的界面布局如下圖5.4所示。圖5.4本地書柜操作界面本地書柜的功能操作代碼實(shí)現(xiàn)如下:首先聲明各類操作的ID號(hào): privatestaticfinalintOPEN_BOOK_ITEM_ID=0; privatestaticfinalintSHOW_BOOK_INFO_ITEM_ID=1; privatestaticfinalintSHARE_BOOK_ITEM_ID=2; privatestaticfinalintADD_TO_FAVORITES_ITEM_ID=3; privatestaticfinalintREMOVE_FROM_FAVORITES_ITEM_ID=4; privatestaticfinalintMARK_AS_READ_ITEM_ID=5; privatestaticfinalintMARK_AS_UNREAD_ITEM_ID=6; privatestaticfinalintDELETE_BOOK_ITEM_ID=7;然后用case的分支判定不同的操作情況,跳轉(zhuǎn)相應(yīng)的Activity:privatebooleanonContextItemSelected(intitemId,Bookbook){ switch(itemId){ caseOPEN_BOOK_ITEM_ID://打開書籍列表 FBReader.openBookActivity(this,book,null); returntrue; caseSHOW_BOOK_INFO_ITEM_ID://顯示書籍信息 showBookInfo(book); returntrue; caseSHARE_BOOK_ITEM_ID://分享書籍 FBUtil.shareBook(this,book); returntrue; caseADD_TO_FAVORITES_ITEM_ID://添加到最愛(ài)的圖書 book.addLabel(Book.FAVORITE_LABEL); myRootTree.Collection.saveBook(book); returntrue; caseREMOVE_FROM_FAVORITES_ITEM_ID://從最愛(ài)的圖書中移除 book.removeLabel(Book.FAVORITE_LABEL); myRootTree.Collection.saveBook(book); if(getCurrentTree().onBookEvent(BookEvent.Updated,book)){ getListAdapter().replaceAll(getCurrentTree().subtrees(),true); } returntrue; caseMARK_AS_READ_ITEM_ID://標(biāo)記為已讀 book.addLabel(Book.READ_LABEL); myRootTree.Collection.saveBook(book); getListView().invalidateViews(); returntrue; caseMARK_AS_UNREAD_ITEM_ID://標(biāo)記為未讀 book.removeLabel(Book.READ_LABEL); myRootTree.Collection.saveBook(book); getListView().invalidateViews(); returntrue; caseDELETE_BOOK_ITEM_ID://刪除圖書 tryToDeleteBook(book); returntrue; } returnfalse; }5.2.2在線書庫(kù)在線書庫(kù)最主要的是實(shí)現(xiàn)與網(wǎng)絡(luò)數(shù)據(jù)庫(kù)連接的相關(guān)設(shè)置。在進(jìn)行事件跳轉(zhuǎn)之前首先要在Manifestest.xml文件中包含網(wǎng)絡(luò)連接的許可:<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>用戶點(diǎn)擊在線書庫(kù)之后,系統(tǒng)將要實(shí)行與SQLiteNetworkDatabase的連接、連接保持以及刪除連接三個(gè)流程。在與SQLiteNetworkDatabase建立連接時(shí),首先用Application申請(qǐng)打開數(shù)據(jù)庫(kù),代碼如下:classSQLiteNetworkDatabaseextendsNetworkDatabase{ privatefinalSQLiteDatabasemyDatabase; SQLiteNetworkDatabase(Applicationapplication){ myDatabase=application.openOrCreateDatabase("network.db",Context.MODE_PRIVATE,null); migrate(); }連接建立之后調(diào)用SaveLink函數(shù),關(guān)鍵代碼如下: protectedsynchronizedvoidsaveLink(finalINetworkLinklink){ executeAsTransaction(newRunnable(){ publicvoidrun(){ finalSQLiteStatementstatement; if(link.getId()==INetworkLink.INVALID_ID){ if(...); } statement=myInsertCustomLinkStatement; }else{...} statement=myUpdateCustomLinkStatement; }最后,調(diào)用deleteLink函數(shù)刪除與數(shù)據(jù)庫(kù)的連接,關(guān)鍵代碼如下:protectedsynchronizedvoiddeleteLink(finalINetworkLinklink){ if(link.getId()==INetworkLink.INVALID_ID){ return; } executeAsTransaction(newRunnable(){ publicvoidrun(){ finalStringstringLinkId=String.valueOf(link.getId()); myDatabase.delete("Links","link_id=?",newString[]{stringLinkId}); myDatabase.delete("LinkUrls","link_id=?",newString[]{stringLinkId}); link.setId(INetworkLink.INVALID_ID); } }); }在線書庫(kù)列表界面如圖5.5所示。圖5.5在線書庫(kù)功能界面 5.2.3黑底白字/白底黑字黑底白字和白底黑字的切換就是我們?cè)谶M(jìn)行閱讀時(shí)的白天模式和夜間模式,這種功能有助于保護(hù)讀者的視力。其黑底白字功能效果圖如圖5.6所示,白底黑字功能效果圖如圖5.7所示。圖5.6白底黑字模式圖5.7黑底白字模式關(guān)鍵代碼實(shí)現(xiàn)如下:publicclassMainActivityextendsActivityimplementsOnClickListener{privateWindowManagermWindowManager;privateViewmyView;privateButtonbtn_dayAndnight;privateSharedPreferencesskinSp;privatefinalstaticStringDAY="day";privatefinalstaticStringNIGHT="night";privateintflage=0;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);mWindowManager=(WindowManager)getSystemService(Context.WINDOW_SERVICE);setContentView(R.layout.activity_main);init();}privatevoidinit(){skinSp=this.getSharedPreferences("skinchange",Context.MODE_PRIVATE);btn_dayAndnight=(Button)findViewById(R.id.btn_dayAndnight);btn_dayAndnight.setOnClickListener(this);Stringmode=skinSp.getString("skin","");if(mode!=null||!mode.equals("")){if(mode.equals(NIGHT)){night();}else{day();}}}@OverridepublicvoidonClick(Viewv){if(flage%2==0){night();btn_dayAndnight.setText("白底黑字");btn_dayAndnight.setText_Colour(Colour.WHITE);flage++;}else{day();btn_dayAndnight.setText("黑底白字");btn_dayAndnight.setTextColour(Colour.BLACK);flage++;}}publicvoidnight(){WindowManager.LayoutParamsparams=newWindowManager.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT,LayoutParams.TYPE_APPLICATION,WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);params.gravity=Gravity.BOTTOM;params.y=10;if(myView==null){myView=newTextView(this);myView.setBackgroundColor(0x80000000);}mWindowManager.add_View(myView,params);Editoredit=skinSp.edit();edit.putString("skin",NIGHT);mit();}publicvoidday(){if(myView!=null){mWindowManager.removeView(myView);Editoredit=skinSp.edit();edit.putString("skin",DAY);mit();}}publicvoidremoveSkin(){if(myView!=null){mWindowManager.removeView(myView);}}@OverrideprotectedvoidonDestroy(){super.onDestroy();Stringmode=skinSp.getString("skin","");if(mode.equals(NIGHT)){removeSkin();}}}布局文件代碼如下:<RelativeLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn_dayAndnight"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="@string/btn_changeskin"/></RelativeLayout>5.2.4屏幕旋轉(zhuǎn)在設(shè)計(jì)系統(tǒng)屏幕旋轉(zhuǎn)時(shí),如果不做特殊處理,會(huì)導(dǎo)致系統(tǒng)當(dāng)前的Activity被銷毀重建,調(diào)用方法onDestroy再重建onCreate,這種情況下就有可能導(dǎo)致用戶的當(dāng)前數(shù)據(jù)丟失,為了防止在屏幕旋轉(zhuǎn)中Activity的重建,需要在AndriodManifest.xml中對(duì)應(yīng)的activity屬性中配置configChanges的值:android:configChanges="keyboard|keyboardHidden|orientation"然后在Activity活動(dòng)中,再次載入函數(shù)onConfgurationChanged:@OverridepublicvoidonConfigurationChanged(ConfigurationnewConfig){super.onConfigurationChanged(newConfig);}通過(guò)newConfig的返回的值Configuration.ORIENTATION_LANDSCAPE或者Configuration.ORIENTATION_PORTRAIT可以判斷是水平方向還是豎直方向。在屏幕實(shí)現(xiàn)感知設(shè)備方向旋轉(zhuǎn)時(shí)用到的類了一個(gè)方向監(jiān)聽器:OrientationListener,在OrientationListener的構(gòu)造函數(shù)中,會(huì)獲取一個(gè)SensorManager類的實(shí)例對(duì)象,通過(guò)SensorManager獲取一個(gè)加速度傳感器對(duì)象,然后new一個(gè)傳感器監(jiān)聽事件SensorEventListener來(lái)感知設(shè)備的屏幕方向,具體代碼如下:mSensorManager=(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);mRate=rate;mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if(mSensor!=null){//創(chuàng)建一個(gè)listenermSensorEventListener=newSensorEventListenerImpl();}publicvoidenable(){if(mSensor==null){Log.win(tag,"Cannotfindsensors.Notenabled");return;}if(mEnabled==false){if(local)Log.d(tag,"WindowOrientationListenerenabled");mSensorManager.register_Listener(Sensor_EventListener,Sensor,Rate);mEnabled=true;}}在傳感器數(shù)據(jù)發(fā)生變化是,OrientationListener類中的SensorEventListenerImpl,會(huì)調(diào)用onSensorChanged方法,該方法的功能為將傳感器上顯示的數(shù)字轉(zhuǎn)換為手機(jī)旋轉(zhuǎn)的角度,然后再調(diào)用一個(gè)角度計(jì)算方法calculateNewRotation方法將角度轉(zhuǎn)換為相應(yīng)的屏幕的旋轉(zhuǎn)方向,關(guān)鍵代碼如下:privateint[][][]THRESHOLDS=newint[][][]{{{79,180},{180,282}},{{0,45},{45,165},{300,360}},{{0,53},{195,315},{315,360}}};privatefinalint[][]ROTATE_TO=newint[][]{{ROTATION_270,ROTATION_90},{ROTATION_0,ROTATION_270,ROTATION_0},{ROTATION_0,ROTATION_90,ROTATION_0}};上述兩個(gè)數(shù)組是一一對(duì)應(yīng)的,THRESHOLDS數(shù)組是一個(gè)三維數(shù)組,THRESHOLDS數(shù)組第一行代表當(dāng)手機(jī)屏幕處于ROTATION_0時(shí),第二行代表當(dāng)手機(jī)屏幕處于ROTATION_90,第三行對(duì)應(yīng)ROTATION_270當(dāng)手機(jī)旋轉(zhuǎn)到79~180度,calculateNewRotation會(huì)將根ROTATE_TO數(shù)組中計(jì)算得出屏幕該旋轉(zhuǎn)的方向如果屏幕旋轉(zhuǎn)的角度在所定義的角度范圍內(nèi),屏幕將會(huì)旋轉(zhuǎn)。屏幕旋轉(zhuǎn)效果圖水平方向如圖5.8所示,垂直方向如圖5.9所示。圖5.8水平方向圖5.9垂直方向5.2.5書簽在書簽功能設(shè)計(jì)中,包括對(duì)書簽的添加、刪除和打開。涉及的文件主要有BookMarksActivity.java、bookmarks.xml、BookmarkEditActivity.java。書簽的界面布局如下圖5.10所示。圖5.10書簽界面布局布局代碼為:<?xmlversion="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"><ListViewandroid:id="@+id/this_book"android:layout_width="fill_parent"android:layout_height="fill_parent"/><ListViewandroid:id="@+id/all_books"android:layout_width="fill_parent"android:layout_height="fill_parent"/><ListViewandroid:id="@+id/search_results"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"></ListView></RelativeLayout>書簽的創(chuàng)建、刪除、打開,在書簽的Activity中實(shí)現(xiàn):書簽的創(chuàng)建關(guān)鍵代碼實(shí)現(xiàn)如下:privatevoidaddBookmark(){ finalBookmarkbookmark= SerializerUtil.deserializeBookmark(getIntent().getStringExtra(FBReader.BOOKMARK_KEY)); if(bookmark!=null){ myCollection.saveBookmark(bookmark); myThisBookAdapter.add(bookmark); myAllBooksAdapter.add(bookmark); } }書簽的打開關(guān)鍵代碼實(shí)現(xiàn)如下:privatevoidgotoBookmark(Bookmarkbookmark){ bookmark.markAsAccessed(); myCollection.saveBookmark(bookmark); finalBookbook=myCollection.getBookById(bookmark.getBookId()); if(book!=null){ FBReader.openBookActivity(this,book,bookmark); }else{ UIUtil.showErrorMessage(this,"cannotOpenBook"); } }書簽的刪除關(guān)鍵代碼實(shí)現(xiàn)如下:publicvoidremove(finalBookmarkb){ runOnUiThread(newRunnable(){ publicvoidrun(){ myBookmarks.remove(b); notifyDataSetChanged(); } }); }書簽的列表界面如圖5.11所示,書簽的操作界面如圖5.12所示。圖5.11書簽列表界面圖5.12書簽操作界面5.2.6字體加大/縮小字體的放大和縮小是通過(guò)定義一個(gè)字體選擇的函數(shù)FontOption,在這個(gè)函數(shù)中確定字體的最大和最小的值,即上界和下屆,然后利用函數(shù)的IncreateFont方法和DecreaseFont方法,成比例的放大和縮小函數(shù),然后調(diào)用getViewWidget().repaint函數(shù)對(duì)畫布進(jìn)行重新渲染,字體放大后和縮小后的界面效果對(duì)比如下圖5.13和5.14所示。圖5.13字體放大后效果圖圖5.14字體縮小后效果圖代碼實(shí)現(xiàn)如下:Action文件代碼:classChangeFontSizeActionextendsFBAction{ privatefinalintmyDelta; ChangeFontSizeAction(FBReaderAppfbreader,intdelta){ super(fbreader); myDelta=delta; } @Override protectedvoidrun(Object...params){ finalZLIntegerRangeOptionoption= Reader.TextStyleCollection.getBaseStyle().FontSizeOption; option.setValue(option.getValue()+myDelta); Reader.clearTextCaches(); Reader.getViewWidget().repaint(); }}FontSizeOption的代碼設(shè)計(jì)如下:publicTextBaseStyle(Stringprefix,Stringfont_Family,intfont_Size){ super(null,ZLTextHyperlink.NO_LINK); FontFamilyOption=newZLStringOption(GROUP,prefix+":fontFamily",fontFamily); fontSize=fontSize*ZLibrary.Instance().getDisplayDPI()/160; FontSizeOption=newZLIntegerRangeOption(GROUP,prefix+":fontSize",5,Math.max(144,fontSize*2),fontSize); BoldOption=newZLBooleanOption(GROUP,prefix+":bold",false); ItalicOption=newZLBooleanOption(GROUP,prefix+":italic",false); UnderlineOption=newZLBooleanOption(GROUP,prefix+":underline",false); StrikeThroughOption=newZLBooleanOption(GROUP,prefix+":strikeThrough",false); AlignmentOption=newZLIntegerRangeOption(GROUP,prefix+":alignment",1,4,ZLTextAlignmentType.ALIGN_JUSTIFY); LineSpaceOption=newZLIntegerRangeOption(GROUP,prefix+":lineSpacing",5,20,12); }5.2.7翻頁(yè)翻頁(yè)功能是一個(gè)閱讀器最基本的功能,實(shí)現(xiàn)翻頁(yè)需要用到控件ViewFlipper,翻頁(yè)動(dòng)畫的實(shí)現(xiàn)通過(guò)ViewAnimator實(shí)現(xiàn)。翻頁(yè)原理圖如下圖5.15所示:圖5.15翻頁(yè)效果原理圖圖5.15中的A區(qū)域表示把翻頁(yè)后后看到的背面區(qū)域,B區(qū)域表示把書頁(yè)翻起來(lái)后下一頁(yè)的部分顯示,C區(qū)域?yàn)楫?dāng)前顯示的可見部分,a表示手指滑動(dòng)頁(yè)角到達(dá)的位置,b表示當(dāng)前頁(yè)翻起來(lái)后與書本垂直邊的交點(diǎn),c表示當(dāng)前頁(yè)翻起來(lái)后與書本水平邊的交點(diǎn),m表示翻頁(yè)的起始點(diǎn),n為書本右上角,t為書本左上角,o是直角坐標(biāo)系原點(diǎn)。為了實(shí)現(xiàn)上述翻頁(yè)效果,就必須在翻頁(yè)之前準(zhǔn)備三張紙,一張是當(dāng)前頁(yè),一張前頁(yè),一張后頁(yè),翻頁(yè)的過(guò)程就是當(dāng)前頁(yè)也前頁(yè)或后頁(yè)的頁(yè)面剪切。由于用戶在翻頁(yè)過(guò)程中并不會(huì)遵循直線的路徑,為了使用戶翻頁(yè)路徑更加真實(shí),所以采用Andriod中Path類里的quadTo(x1,y1,x2,y2)繪制貝塞爾曲線路徑。關(guān)鍵代碼實(shí)現(xiàn)如下:classTurnPageActionextendsFBAction{ privatefinalbooleanmyForward; TurnPageAction(FBReaderAppfbreader,booleanforward){ super(fbreader); myForward=forward; } @Override publicbooleanisEnabled(){ finalPageTurningOptions.FingerScrollingTypefingerScrolling= Reader.PageTurningOptions.FingerScrolling.getValue(); return fingerScrolling==PageTurningOptions.FingerScrollingType.byTap|| fingerScrolling==PageTurningOptions.FingerScrollingType.byTapAndFlick; } @Override protectedvoidrun(Object...params){ finalPageTurningOptionspreferences=Reader.PageTurningOptions; if(params.length==2&¶ms[0]instanceofInteger&¶ms[1]instanceofInteger){ finalintx=(Integer)params[0]; finalinty=(Integer)params[1]; Reader.getViewWidget().startAnimatedScrolling( myForward?FBView.PageIndex.next:FBView.PageIndex.previous, x,y, preferences.Horizontal.getValue() ?FBView.Direction.rightToLeft:FBView.Direction.up, preferences.AnimationSpeed.getValue() ); }else{ Reader.getViewWidget().startAnimatedScrolling( myForward?FBView.PageIndex.next:FBView.PageIndex.previous, preferences.Horizontal.getValue() ?FBView.Direction.rightToLeft:FBView.Direction.up, preferences.AnimationSpeed.getValue() ); } }}其中,right-to-left設(shè)置如下:<tapZonesv="3"h="3"> <zonex="0"y="0"

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論