基于Andriod的阅读软件的设计与实现_第1页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于Andriod的阅读软件的设计与实现摘要:随着智能化电子化水平的提高,电子阅读方式已经渐渐成为现代人主要的阅读方式。电子阅读器相比于传统书籍具有方便快捷、存储容量大,易于操作等优点。本系统利用Google的Andriod集成开发环境ADT进行开发。文章首先介绍了课题的研究背景以及Andriod开发的相关技术理论。阐述在开发过程中对系统进行的详细的需求分析,根据需求分析结果对系统做出总体设计。然后着重介绍了该电子阅读器在本地书柜、在线书库、白天模式和黑夜模式、屏幕方向、字体加大缩小以及翻页功能的模块的设计与实现。最后对本次设计做出总结与展望。关键词:Andriod开发;电子阅读软件;Java Abstract:Withtheimprovementofintelligentelectroniclevel,EBookreadinghasgraduallybecomethemainreadingwayinourlife.ElectronicReadersaremoreconvenientandlargerstoredcomparedwiththetraditionalbooks.Besidesitiseasytooperate.ThissystemisbasedonGoogle'sandroidADT.ItisanintegrationdevelopmentenvironmentforAndrioddevelopment.Thisarticleisconsistsofthefollowingparts.Thefirstparagraphintroducestheresearchbackgroundandthedevelopmentoftheandroidalongwiththerelatedtechnicaltheory.Thesecondparagraphexpoundsthedevelopmentprocessaboutthedemandanalysis.Thethirdexpoundstheoveralldesignaboutthesystembasedonthedemandanalysis.Then,theforthparagraphintroducedthefunctionsoftheelectronicreaderonlocalbookcase,onlinelibrary,dayandnightscreendirection,fontincreaseanddecreaseandturnpagerightandleft.Finallymakeasummaryandoutlookofthedesign.Keywords:AndriodDevelopment;Electronicreaders;Java第1章绪论电子阅读的方式已经成为现代人生活中的主要阅读方式,随着智能手机的普及,市场上出现了各种各样的电子阅读器。Andriod系统作为智能手机操作系统中的佼佼者,其本身具有的平台的开放性,以及各开发组件的成熟性等优点,给热衷于Andriod应用开发的爱好者们提供了一个很好的平台。1.1课题研究背景及意义自1993年世界上第一款智能触屏手机“Simon”出现后,智能手机市场便呈指数趋势迅速发展。2013年至2015年期间,智能手机已基本完成与传统按键机的更新换代。智能手机人性化、智能化的特点改变了人们以往的生活方式。开放的操作系统使得人们可以随心所欲安装自己所需的应用程序。纵观我们的周边,电子阅读软件已经在我们的生活中相当的普及。其方便快捷电子化的特征逐渐改变人们的传统阅读方式。纸质书受限于物理空间的大小不方便携带也不方便阅读,但是电子阅读器只需带手机或拥有智能设备便可观看阅读。纸质书受限于空间环境的变化,没有光线的地方便无法阅读,电子书只需智能设备有电,便可自主调节亮度背景颜色。在现代化电子化的环境下,电子阅读器越来越受群众的欢迎。而安卓手机市场又占手机市场极高的份额,所以基于Android的阅读软件的设计是极具市场意义的。1.2国内外研究现状电子阅读器这一概念早在二十世纪七十年代便由美国布朗大学的软件工程师提出[1]。随后,美国SoftBook公司便推出了市场上第一款电子阅读软件“RocketBook”,该款电子书采用与计算机串口相连的方式实现电子书的购买与下载。2008年8月,微软推出了一款名为“MicrosoftReader”的电子于都软件,该款阅读器使用微软的字符显示ClearType技术[2],使得显示屏的清晰度和分辨率大大提高,电子阅读器具有了更好的观看体验。目前,市场上比较流行的安卓手机阅读器主要有以下几款:1、iReader:该款手机阅读器支持TXT,UMD,HTML,PDF等多种书籍格式,支持书签、全屏、白天黑夜模式、备份观看历史等多种功能,并且具有多种翻页特效;2、QQ阅读:该款阅读器由盛大公司出品,简单实用,可个性化更改皮肤,同样支持书签、全屏、文本设置等功能[3]。3、百阅:该款阅读器的特点在于能及时撰写书评并且同步微博,给读者带来社交互动的良好体验。4、盛大云中书城:该款阅读器UI界面清爽,同步红袖添香、潇湘书院等多阅读网站,适合多层次年龄段的读者。其他比较主流的阅读器还有“起点读书”、“静读天下”、“91熊猫看书”等。虽然市场上的电子阅读软件种类多种样,功能比较完善,但是依然无法完全满足读者需求,长时间阅读后较为疲劳,所以电子阅读软件领域还有较大的研究空间。1.3论文主要内容及组织结构本文共分为六个章节,各章节内容安排如下:绪论,介绍了课题的研究背景及意义,国内外研究现状以及本文的组织结构安排。Andriod应用开发环境介绍,介绍了Android系统及架构,Andriod的基本组件,以及本系统的开发工具和平台。电子阅读软件需求分析,主要对电子阅读软件在书籍管理需求方面、书籍编辑需求方面、书籍阅读需求方面以及界面交互需求方面进行分析。电子阅读软件总体设计,包括系统的功能设计、系统的流程设计以及数据库设计。电子阅读软件详细设计,包括系统流程详细设计以及系统功能的详细设计。总结与展望。对系统设计的总结以及功能拓展的设想。第2章Andriod应用开发环境介绍2.1Android系统及架构介绍Android系统,由Google公司开发,是一款基于Linux且开源的手机操作系统,其版本经历了从Andriod1.1到Andriod4.4的演变,本系统的设计版本要求为Andriod4.0及以上版本[4]。Andriod的系统组织架构类似于操作系统,采用分层的架构[5],从高层到底层分为为:应用程序层、应用程序框架层、系统运行层和Linux内核层。应用程序层包含一系列应用程序包(客户端,SMS短消息程序,浏览器、管理程序等);应用程序框架中包含了每个应用后面隐藏的一系列服务机制,包括视图(View)、内容提供器(ContentProviders)、资源管理器(ResourceManager)、通知管理器(NotificationManager)、活动管理器(ActivityManager),开发人员可以通过访问应用程序的API框架实现应用程序的各功能模块;系统运行层包含一些C/C++库,这些库能被Andriod系统中不同的组件使用,这些函数库包括系统C库,一个从BSD继承来的标准C函数库Libc;媒体功能库,支持多种常用格式的音频录制播放等;2D和3D图形库;用于点阵和矢量字体渲染的FreeType以及SQLite引擎等;Linux内核层则提供内存管理、进程管理、软硬件连接等服务。2.2Andriod基本组件介绍一个Andriod应用程序是以java编程语言为基础[6],通过Andriod组件Activity之间的相互跳转,并且利用Intent实现多程序运行的。在一个应用程序中,主要用到以下几种Andriod组件:Activity、Service、BroadcastReceiver、ContentProvider、Intent。2.2.1Activity(活动)Activity是一个用户界面的基类[7],它为用户提供了与应用程序交互的窗口,相当于C/S程序中的窗体(Form)或Web程序的页面。Activity窗口中的可视化组件由View及其子类组成,这些组件按着XML布局文件中指定的位置排放。一个Activity状态回调分别通过“onCreate”进行创建、“onStart”进行激活、“onResume”进行恢复、“onPause”进行暂停、“onStop”进行停止、“onDestroy”进行销毁、“onRestart”进行重启。2.2.2Service(服务)Service没有可见的用户界面,但是能够在后台长时间运行。例如,当用户在进行其他操作时,便可利用Service在后台进行播放音乐等操作。Service是不能自己启动的,必须通过Context对象(如一个Activity)调用startService或bindService方法来启动。2.2.3BroadcastReceiver(广播接受器)BroadcastReceiver是一个用于接受广播通知的组件,如手机时区变化、电池电量低等系统或其他应用程序的广播通知。当BroadcastReceiver接受到广播后自身并不实现用户界面的变化,而是通过启动相应的Activity作出响应,或者通过NotificationMananger提醒用户。2.2.4ContentProvider(内容提供者)ContentProvider用于将存储在文件系统、SQLite数据库或其他合理内存中的数据提供给应用程序。ContentProvider继承自基类ContentProvider,并实现了一个标准方法集,使得其他应用程序可以检索和存储数据。2.2.5IntentIntent是连接上述各组件之间的重要纽带。Andriod通过Intent类来实现各活动之间的切换以及组件的调用。不同类型的Intent消息不会出现重叠,Android会准确找到与之相匹配的一个或多个Activity、Service或BroadcastReceive作出响应。2.3系统开发工具介绍本系统开发用到的开发工具为:JDK8.0ADT-Bundle:ADT-Bundle是由GoogleAndriod官方提供集成开发环境(IDE),其中包含了Eclipse,AndriodSDK以及Android开发所需的平台工具。第3章电子阅读软件需求分析电子阅读软件需求分析主要分为以下几个部分:书籍管理需求分析、书籍编辑需求分析、书籍阅读需求分析、界面交互需求分析。3.1书籍管理需求分析书籍管理需求主要有用户在该电子阅读软件上对书籍的添加、删除、查找等操作。用户可以根据自己的喜好在电子阅读器中加载所需的图书或阅读文本。其实现可通过本地SD卡查找导入渲染,在线书城链接等方式。用户也可进行一定的管理操作[8]。同时,可通过查找对指定书籍进行快速查找导入。书籍管理需求分析如表3-1所示。表3-1书籍管理需求分析参与者用户概述用户点击添加、删除、查询,书籍被添加、删除、查询前置条件点击相应按钮,动作被记录详细描述用户点击相应的操作按钮活动跳转相应的操作选项点击实现预期操作后置条件书籍添加成功、删除成功、查询成功3.2书籍编辑需求分析书籍编辑需求主要有对书籍文字字体和大小的调整、书签的删除添加操作[9]等。书签的添加删除操作需求分析如表3-2所示。表3-2书签操作需求分析参与者用户概述用户点击添加、删除书签,书签被添加、删除前置条件点击相应按钮,动作被记录详细描述1、用户点击书签操作按钮2、界面跳转书签操作选项3、点击实现预期操作后置条件书签添加成功、删除成功3.3书籍阅读需求分析书籍阅读需求主要包括用户在进行书籍阅读时对书籍的背景颜色,屏幕亮度,文本显示方向等的要求。用户可以根据白天和黑夜不同的阅读时间段选择“白底黑字”“黑底白字”不同的阅读模式对眼睛起保护作用,也可根据外部光线调节屏幕亮度[10]。同时可根据手机放置方向选择合适的文本显示方向。其中背景设置需求分析如下表3-3所示。表3-3背景设置需求分析参与者用户概述用户点击“白底黑字”,界面变为“白底黑字”前置条件点击相应按钮,动作被记录详细描述1、用户点击“白底黑字”操作按钮2、界面变为白底黑字后置条件屏幕变为“白底黑字”3.4界面交互需求分析界面交互需求主要包括用户在阅读过程中对翻页动画、页面切换效果、阅读进度显示等的要求[11]。电子阅读软件需要有良好的UI界面和操作动画[12],使电子阅读软件模拟能真实的翻页效果,同时记录用户的阅读进度。其中电子阅读器的动画翻页需求分析如表3-4所示。表3-4动画翻页需求分析参与者用户概述用户向左/右滑动屏幕,书页向左、右翻动前置条件点击相应按钮,动作被记录详细描述1、用户向左/右滑动屏幕2、书页向左/右翻动后置条件翻页成功第4章电子阅读软件总体设计对于电子阅读软件的模块设计建立在对其进行需求分析的基础上[13],概括出各大主要功能模块。同时,结合用户阅读习惯及潜在需求,对各大功能模块进行细化,从而实现该电子阅读软件的总体设计。4.1功能模块设计4.1.1软件主要功能模块设计本系统设计的电子阅读软件包含四大主要功能模块,分别是:书籍管理模块、书籍编辑模块、书籍阅读模块和阅读交互模块[14]。其中,书籍管理模块中包含书籍的添加、下载、排序等功能设计。书籍编辑模块主要实现书签、阅读时页面字体排版等功能。书籍阅读模块包含书籍的呈现方式(屏幕方向设置)、字体的加大缩小操作[15]、以及背景色的设置等。阅读交互模块主要包含阅读的进度条设置、翻阅动画效果、翻阅速度以及快速翻看等功能设置。功能模块结构如图4.1所示。图4.1软件主要功能模块设计4.1.2书籍管理模块设计在书籍管理模块中要实现对电子书籍的增加、删除、整理等功能,在该功能模块中,本系统设置了“本地书库”、“在线书库”两大书籍添加模块,在“本地书库”的子功能中设计了书籍管理模块,可将书籍按“最爱的书”、“最近阅读”、“按作者”、“按书名”、“按系列”、“按标签”进行整理排序。在“在线书库”的子功能模块中同时设置了“管理书库”“添加在线书籍”的功能模块。书籍管理模块的功能设计如图4.2所示。图4.2书籍管理模块功能设计4.1.3书籍编辑模块设计书籍编辑模块中主要实现书签的相关操作,包括添加、删除、打开书签以及页面排版的相关操作,包括文本的字体、行间距、对齐方式的操作。书籍编辑模块的功能设计如图4.3所示。图4.3书籍编辑模块设计4.1.4书籍阅读模块设计书籍阅读模块中主要包括屏幕方向设置和字体的放大缩小设置。其中屏幕方向设置包括获取默认系统方向设置、感知设备方向设置、以及竖直(竖直反置)和水平(水平反置)的设置。书籍阅读模块功能设计如图4.4所示。图4.4书籍阅读模块设计4.1.5阅读交互模块设计阅读交互模块设计包括阅读过程中的翻阅操作,包括翻阅动画,自动翻页等选择;快速翻看操作,用于用户对书籍的快速浏览;进度条功能,用于显示用户的阅读进度。阅读交互模块的具体设计如图4.5所示。图4.5阅读交互模块设计4.1.6系统功能模块本系统设计的电子阅读软件由上述主要功能模块以及子功能模块组成。在设计过程中通过自顶向下的设计方法对阅读软件的功能进行细化。最终将该系统的功能模块分为以下几大部分。如图4.6所示。图4.6系统功能模块图4.2系统流程设计电子阅读软件从打开到可以观看要经过以下几个流程[16]:程序进入主Activity之前完成对数据库配置、载入系统默认加载文档[17]、初始化界面打开时屏幕亮度,字体高亮等等。这些事件都是在声明Application中实现的。要实现本系统的初识化具体操作如下(默认加载小说盗墓笔记):首先在配置文件AndriodMainfest.xml中声明本系统的application:<applicationandroid:name="org.geometerplus.android.hxwreader.hxwReaderApplication"然后在FBReaderApplication文件中声明初始化程序的入口:importorg.geometerplus.zhulibrary.dao_mu.ui.android.library.hxwAndroidApplication;最后在ZLAndriodApplication中进行声明,创建一个config.db,其目的是用来初始化一个图片管理类,并且获取信息。实现如下:publicabstractclassZLAndroidApplicationextendsApplication{ @Override publicvoidonCreate(){ super.onCreate(); newZhuLSQLiteConfig(this); newZhuLAndroidImageManager(); newZhuLAndroidLibrary(this); }}进入主程序,寻找一个主Activity[18],本系统中将程序的入口设为一个WelcomeActivity,其代码实现如下:<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>进入系统主界面后,便需要生成一个Book对象。在openBook函数中引用mybook类。记录用户已经添加到书架的书籍,若myBook不为空,按照相应的书籍存放路径BOOK_KEY或者BOOKMARK_KE对应的入口查找并打开书籍。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())); } } }获取并打开文件后需要将数据保存到一个MODELZH中[19],所以接下来系统将要生成一个Model对象,本系统在生成数据Model对象时,利用open_BookInternal(book,null)函数将book向下传递的。具体代码实现如下: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、第四步中将数据保存到一个MODEL中之后,系统接下来就需要将MODEL中保存的数据取出来,渲染到画布中。本系统的画布是通过一个自定义的VIEW,来显示文字、图像、超链接等信息,在VIEW中定义两个paint函数,其中一个函数用来实现与FooterArea的接口,另一个函数用来绘制阅读界面。这样,一个阅读界面的渲染便可以实现了[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){...}综上所述,本系统的流程设计如图4.7所示。图4.7系统流程图设计4.3系统数据库设计4.3.1Andriod内置数据库SQLite概述本文2.1章中提过,Android系统中内嵌了小型数据库SQLite。SQLite是一款遵守ACID的关联式数据库管理系统,支持NULL、INTEGER、REAL、TEXT和BLOB五种数据类型,当SQLite在解析CREATETABLE语句时,会忽略CREATETABLE语句中在字段名后面的数据类型。大多数情况下,Andriod中的数据库默认是私有的,只供当前应用程序访问。SQLite内部结构图如图4.8所示。图4.8SQLite内部结构图在Andriod开发过程中,Activity通过ContentProvider或Service访问数据库。但是Android不自动提供数据库,需要在SQLite中自己创建数据库。在Andriod中创建数据库需要继承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系统涉及的数据结构分析本系统中设计的数据主要包括书籍信息、书签信息、最近阅读信息。其中,书籍信息包括书名、语言、书文信息(存储路径)。书签信息包括书签内容、书签章节、书签保存时间。最近阅读信息包括最近阅读书名。本系统的具体数据结构描述如下表4-1所示。表4-1系统数据结构数据结构名描述组成书籍书籍信息书名、语言、文本信息书签书签信息书签内容、书签章节、书签保存时间最近阅读最近阅读信息最近阅读书名第5章电子阅读软件详细设计5.1系统流程详细设计5.1.1初始化子线程的建立在用户点击阅读软件图标,软件作出响应时起,系统便会在主线程中建立一个子线程,该子线程负责在后台读取epub文件,并进行一系列的初始化工作。子线程的创建通过下述步骤实现的。首先在AndriodManifes.xml配置文件中声明系统首先进入FBReader类,该类继承自父类ZLAndriodActivity。代码如下图5.1所示:图5.1声明主类接着在hxwReader类中创建一个on_Create的方法,利用该方法可以来触发父类ZLAndriodActivity类中的onCreate方法,在父类中的onCreate方法中设置了对系统的一系列初始化工作以及利用ZLApplication类的子类FBReaderApp类中的initWindow方法建立子线程。其他的初始化工作包括设置程序为全屏模式,用ViewZLAndriodWidget类设置程序的界面,调用ZLAndriodLibrary类的setActivity方法,为ZLAndriodLibrary类里面的myActivity变量赋值等。具体代码实现如下图5.2所示图5.2父类ZLAndriodActivity中的onCreate方法5.1.2系统资源文件的解析系统在读取XML文件的过程中需要涉及三个核心类:ZMLZMLProcessor、ZLXMLParser、ZLXMLReader以及ZLTreeReaource。在解析资源的过程中这三个核心类的调用流程设计如下:1、首先,子类Resource_Tree_Reader类里面的read方法调用ZLXMLProcessor类的read方法该类继承自Adapter抽象类;2、接着,通过ZLXMLProcessor类的read方法通过AndroidAssetsFile类ZLResourceFile类的子类的getInputStream方法获取一个针对资源文件的字节流类AssetInputStream类,并以这个字节流类为参数初始化了一个针对资源文件的字符流类。接着,再调用了ZLXMLParser类的doIt方法。3、然后,ZLXMLParser类的doIt方法就会利用字符流类将文件转换成一个char数组。再利用for循环迭代byte数组的过程中,doIt方法又反过来调用ZLXMLReaderAdapter抽象类的子类(ResourceTreeReader类)的startElementHandler与endElementHandler方法对byte数组中元素所代表的不同节点进行操作。5.2系统功能详细设计在第四章的总体设计中对阅读软件的系统功能做出了阐述,本系统的功能设计主要有“本地书柜”、“在线书库”、“日间模式/夜间模式”、“屏幕方向”、“书签”、“字体加大/缩小”和“翻页”这些功能。系统功能界面菜单如下图5.3所示。图5.3系统功能菜单5.2.1本地书柜在本地书柜中提供了在本地文件夹中查找并导入书籍,以及对书籍按照“最爱”、“作者”、“系列”等分类的书籍管理功能,该功能主要涉及LibraryActivity文件。本地书柜的界面布局如下图5.4所示。图5.4本地书柜操作界面本地书柜的功能操作代码实现如下:首先声明各类操作的ID号: 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的分支判定不同的操作情况,跳转相应的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://添加到最爱的图书 book.addLabel(Book.FAVORITE_LABEL); myRootTree.Collection.saveBook(book); returntrue; caseREMOVE_FROM_FAVORITES_ITEM_ID://从最爱的图书中移除 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://标记为已读 book.addLabel(Book.READ_LABEL); myRootTree.Collection.saveBook(book); getListView().invalidateViews(); returntrue; caseMARK_AS_UNREAD_ITEM_ID://标记为未读 book.removeLabel(Book.READ_LABEL); myRootTree.Collection.saveBook(book); getListView().invalidateViews(); returntrue; caseDELETE_BOOK_ITEM_ID://删除图书 tryToDeleteBook(book); returntrue; } returnfalse; }5.2.2在线书库在线书库最主要的是实现与网络数据库连接的相关设置。在进行事件跳转之前首先要在Manifestest.xml文件中包含网络连接的许可:<uses-permissionandroid:name="android.permission.INTERNET"/><uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>用户点击在线书库之后,系统将要实行与SQLiteNetworkDatabase的连接、连接保持以及删除连接三个流程。在与SQLiteNetworkDatabase建立连接时,首先用Application申请打开数据库,代码如下:classSQLiteNetworkDatabaseextendsNetworkDatabase{ privatefinalSQLiteDatabasemyDatabase; SQLiteNetworkDatabase(Applicationapplication){ myDatabase=application.openOrCreateDatabase("network.db",Context.MODE_PRIVATE,null); migrate(); }连接建立之后调用SaveLink函数,关键代码如下: protectedsynchronizedvoidsaveLink(finalINetworkLinklink){ executeAsTransaction(newRunnable(){ publicvoidrun(){ finalSQLiteStatementstatement; if(link.getId()==INetworkLink.INVALID_ID){ if(...); } statement=myInsertCustomLinkStatement; }else{...} statement=myUpdateCustomLinkStatement; }最后,调用deleteLink函数删除与数据库的连接,关键代码如下: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); } }); }在线书库列表界面如图5.5所示。图5.5在线书库功能界面 5.2.3黑底白字/白底黑字黑底白字和白底黑字的切换就是我们在进行阅读时的白天模式和夜间模式,这种功能有助于保护读者的视力。其黑底白字功能效果图如图5.6所示,白底黑字功能效果图如图5.7所示。图5.6白底黑字模式图5.7黑底白字模式关键代码实现如下: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屏幕旋转在设计系统屏幕旋转时,如果不做特殊处理,会导致系统当前的Activity被销毁重建,调用方法onDestroy再重建onCreate,这种情况下就有可能导致用户的当前数据丢失,为了防止在屏幕旋转中Activity的重建,需要在AndriodManifest.xml中对应的activity属性中配置configChanges的值:android:configChanges="keyboard|keyboardHidden|orientation"然后在Activity活动中,再次载入函数onConfgurationChanged:@OverridepublicvoidonConfigurationChanged(ConfigurationnewConfig){super.onConfigurationChanged(newConfig);}通过newConfig的返回的值Configuration.ORIENTATION_LANDSCAPE或者Configuration.ORIENTATION_PORTRAIT可以判断是水平方向还是竖直方向。在屏幕实现感知设备方向旋转时用到的类了一个方向监听器:OrientationListener,在OrientationListener的构造函数中,会获取一个SensorManager类的实例对象,通过SensorManager获取一个加速度传感器对象,然后new一个传感器监听事件SensorEventListener来感知设备的屏幕方向,具体代码如下:mSensorManager=(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);mRate=rate;mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if(mSensor!=null){//创建一个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;}}在传感器数据发生变化是,OrientationListener类中的SensorEventListenerImpl,会调用onSensorChanged方法,该方法的功能为将传感器上显示的数字转换为手机旋转的角度,然后再调用一个角度计算方法calculateNewRotation方法将角度转换为相应的屏幕的旋转方向,关键代码如下: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}};上述两个数组是一一对应的,THRESHOLDS数组是一个三维数组,THRESHOLDS数组第一行代表当手机屏幕处于ROTATION_0时,第二行代表当手机屏幕处于ROTATION_90,第三行对应ROTATION_270当手机旋转到79~180度,calculateNewRotation会将根ROTATE_TO数组中计算得出屏幕该旋转的方向如果屏幕旋转的角度在所定义的角度范围内,屏幕将会旋转。屏幕旋转效果图水平方向如图5.8所示,垂直方向如图5.9所示。图5.8水平方向图5.9垂直方向5.2.5书签在书签功能设计中,包括对书签的添加、删除和打开。涉及的文件主要有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>书签的创建、删除、打开,在书签的Activity中实现:书签的创建关键代码实现如下:privatevoidaddBookmark(){ finalBookmarkbookmark= SerializerUtil.deserializeBookmark(getIntent().getStringExtra(FBReader.BOOKMARK_KEY)); if(bookmark!=null){ myCollection.saveBookmark(bookmark); myThisBookAdapter.add(bookmark); myAllBooksAdapter.add(bookmark); } }书签的打开关键代码实现如下: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"); } }书签的删除关键代码实现如下:publicvoidremove(finalBookmarkb){ runOnUiThread(newRunnable(){ publicvoidrun(){ myBookmarks.remove(b); notifyDataSetChanged(); } }); }书签的列表界面如图5.11所示,书签的操作界面如图5.12所示。图5.11书签列表界面图5.12书签操作界面5.2.6字体加大/缩小字体的放大和缩小是通过定义一个字体选择的函数FontOption,在这个函数中确定字体的最大和最小的值,即上界和下届,然后利用函数的IncreateFont方法和DecreaseFont方法,成比例的放大和缩小函数,然后调用getViewWidget().repaint函数对画布进行重新渲染,字体放大后和缩小后的界面效果对比如下图5.13和5.14所示。图5.13字体放大后效果图图5.14字体缩小后效果图代码实现如下: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的代码设计如下: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翻页翻页功能是一个阅读器最基本的功能,实现翻页需要用到控件ViewFlipper,翻页动画的实现通过ViewAnimator实现。翻页原理图如下图5.15所示:图5.15翻页效果原理图图5.15中的A区域表示把翻页后后看到的背面区域,B区域表示把书页翻起来后下一页的部分显示,C区域为当前显示的可见部分,a表示手指滑动页角到达的位置,b表示当前页翻起来后与书本垂直边的交点,c表示当前页翻起来后与书本水平边的交点,m表示翻页的起始点,n为书本右上角,t为书本左上角,o是直角坐标系原点。为了实现上述翻页效果,就必须在翻页之前准备三张纸,一张是当前页,一张前页,一张后页,翻页的过程就是当前页也前页或后页的页面剪切。由于用户在翻页过程中并不会遵循直线的路径,为了使用户翻页路径更加真实,所以采用Andriod中Path类里的quadTo(x1,y1,x2,y2)绘制贝塞尔曲线路径。关键代码实现如下: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设置如下:<tapZonesv="3"h="3"> <zonex="0"y="0"

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论