资源下载地址:https://download.csdn.net/download/sheziqiong/85604746
阅读 APP
一、应用基本信息
应用名:FTEReader
应用 Logo:
二、程序运行界面
功能说明
1. 主界面
- 点击下方图标或左右滑动来切换书架、排行榜、分类,点击右上角搜索图标进入搜索界面
- 从书架点击某本书籍进入阅读界面
- 在排行榜处点击左上角 ♂/♀ 图标切换男生/女生,点击某个排行榜进入排行榜界面
- 在分类处点击上方按钮切换男生/女生,点击某个分类进入分类界面
2. 排行榜界面
- 点击上方按钮切换周榜/月榜/总榜
- 点击某本书籍进入书籍详情界面
3. 分类界面
- 点击上方按钮切换热门/新书/好评/完结
- 点击某本书籍进入书籍详情界面
4. 搜索界面
- 在上方搜索框中输入书名,点击搜索按钮进行搜索
- 点击搜索结果中的书名跳转到书籍详情界面
- 点击“大家都在搜”/“搜索历史”中的书名直接跳转到书籍详情界面
5. 书籍详情界面
- 点击左下角“加入书架”按钮可将当前书籍加入书架
- 点击右下角“免费阅读”按钮跳转到阅读界面
- 点击“同类推荐”中的书籍可跳转到该书籍的详情界面
- 点击“更多”按钮跳转到相关书籍界面
6. 阅读界面
- 上下滑动进行阅读,左右滑动切换章节
- 点击屏幕中部,屏幕底部出现菜单:夜间/日间、横屏/竖屏、设置、目录
- 点击“夜间/日间”切换到夜间/日间模式
- 点击“横屏/竖屏”切换到横屏/竖屏模式
- 点击“设置”出现字体大小调整界面,点击“A-”减小字体大小,点击“A+”增大字体大小,点击屏幕其他部分返回
- 点击“目录”出现书籍目录,点击某个章节可跳转到该章节,点击屏幕其他部分返回
7. 相关书籍界面
- 点击相关书籍列表中的书籍,跳转到该书籍的详情界面
主界面
分为书架、排行榜、分类,可从它进入排行榜界面、分类界面、阅读界面。
排行榜界面
显示某个排行榜的书籍。
分类界面
显示某个分类的书籍。
搜索界面
搜索书籍。
书籍详情界面
显示书籍的详情。
阅读界面
阅读书籍。
相关书籍界面
显示与某本书籍相关的一些书籍。
三、应用类图/时序图/架构图等
项目结构图:
我们将整个代码分为了 6 部分:
-
control:包含了创建、操作数据库的函数。
-
fragment:
-
recylerView:包含和 recylerview 相关的对象、适配器和基础的 viewholder
-
object:包含各种 API 返回对象类、数据库对象类等等
- service:包含 API 服务相关函数
- activity:该 app 所有的 activity
四、所采用的技术和采用该技术的原因
1.ViewPager+Fragment 的使用
原因
每一个 Fragment 对应一个界面,使用此技术来显示界面,能够更流畅地在各个界面之间完成切换,
比如主界面的书架、排行榜、分类就是利用 3 个 Fragment 来显示的
再增加 RadioGroup 作为导航栏,就能够实现类似于微信主界面一样的效果了,各个界面之间切换流畅,具有美感
方法
使用的方法就是在布局中添加 ViewPager:
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never"
android:scrollbars="none"/>
再在 Activity 中设置 Adapter、FragmentList:
private ViewPager viewPager;
private List<Fragment> fragmentList = new ArrayList<>();
private TabFragmentStatePagerAdapter fragmentPagerAdapter;
//初始化Fragment
//...
fragmentList.add(bookShelfFragment);
fragmentList.add(rankingFragment);
fragmentList.add(categoryFragment);
设置 ViewPager:
viewPager.setOnPageChangeListener(new MyPagerChangeListener());
fragmentPagerAdapter = new TabFragmentStatePagerAdapter(getSupportFragmentManager(), fragmentList);
viewPager.setAdapter(fragmentPagerAdapter);
viewPager.setCurrentItem(0);
viewPager.setOffscreenPageLimit(2);
2.RadioGroup 实现导航栏
原因
只有单纯的滑动切换 Fragment 给用户的提示信息还不够,界面也不够美观,Fragment 的分离也不够明显。实现一个导航栏能够让用户明确每一个 Fragment 的作用。这也是当前许多主流 App 的做法。
方法
利用 RadioButton 的 android:button="@null"
这个属性来把圆形按钮去掉,再利用 android:drawableTop="@mipmap/bookshelf"
属性来给 RadioButton 显示不同的图片:
<RadioButton
style="@style/BottomRB"
android:drawableTop="@mipmap/bookshelf"
/>
<style name="BottomRB">
<item name="android:button">@null</item>
<item name="android:textColor">@drawable/selector_tab_text_color</item>
</style>
在 RadioButton 被选中时,还需要设置字体的颜色以及改变图片颜色,以达到被选中的效果。这可以在 RadioGroup 的监听事件中来实现,注意需要设置图片的大小,否则会不适配,设置的方法为:
RadioButton 的选中与 ViewPager 切换帧需要结合起来,才能达到导航栏的效果。
在切换选中的 RadioButton 时,要修改 ViewPager 当前显示的帧;在切换 ViewPager 显示的帧时,要修改被选中的 RadioButton。
3.网络访问部分使用了名为 Retrofit 的网络加载框架,其底层使用 OKHttp 封装,支持 rxjava。
原因
- 解耦,减少 API 接口定义和 API 接口使用的耦合
- 包含许多注解,简化代码,方便使用
- 支持同步、异步、RxJava
- 可以使用不同工具解析数据,如 JSON、XML
- 请求速度快
方法
接口类:
@GET("/ranking/gender")
Call<AllRankingObj> getAllRanking();
OkHttpClient build = new OkHttpClient.Builder()
.connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS)
.writeTimeout(2, TimeUnit.SECONDS)
.build();
// 用于API访问
Retrofit retrofitForApi = new Retrofit.Builder()
.baseUrl(ApiUrl)
// 设置json数据解析器
.addConverterFactory(GsonConverterFactory.create())
// RxJava封装OkHttp的Call函数,本质还是利用OkHttp请求数据
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(build)
.build();
4.设置同步变量控制线程顺序
原因
当输入速度特别快时,有的线程清空了 list,而有的线程正在调用 list 里的元素,这样会发生访问异常,需要设置同步变量使得同一时刻只有一个线程在运行。
方法
flag = true; //用于同步问题的布尔变量
if (!s.equals("")&&flag) {
new Thread(new Runnable() {
@Override
public void run() {
flag = false;
...
}
}
}
5.将多个列表放在一个 activity 下
原因
将不同列表放入多个 activity 里可以使得界面布局简单,但是带来的问题是需要增加许多 activity 之间的通信,增加了跳转的复杂度,而将列表放入同一个 activity 里方便跳转时的信息传递。
方法
//设置可见
if (!isSubmit) {
if (s.equals("")) {
initialLayout.setVisibility(View.VISIBLE);
searchLayout.setVisibility(View.GONE);
}
else {
initialLayout.setVisibility(View.GONE);
searchLayout.setVisibility(View.VISIBLE);
fuzzyList.setVisibility(View.VISIBLE);
resultList.setVisibility(View.GONE);
}
}
6.系统广播获取系统电量和时间
原因
用户进入阅读界面时是全屏阅读,顶部状态栏会消失,那么需要有个信息栏来简要显示系统电量和时间
方法
onCreate
中注册广播,接受电量和时钟变化,并创建自定义的广播接收者MyReceiver
类来处理订阅
//注册广播接受者java代码
intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); // 电量变化广播
intentFilter.addAction(ACTION_TIME_TICK);
//创建广播接受者对象
myReceiver = new MyReceiver();
//注册receiver
registerReceiver(myReceiver, intentFilter);
- 自定义广播接收者类,处理电量和时钟变化广播
class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())){
//获取当前电量
int level = intent.getIntExtra("level", 0);
//电量的总刻度
int scale = intent.getIntExtra("scale", 100);
//把它转成百分比
int percent = level*100/scale;
// TODO: Do Something when battery_changed
}
else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
// TODO:Do Something when time_tick
}
}
}
onDestroy
中注销广播订阅
unregisterReceiver(myReceiver);
7.非注销生命周期的横竖屏切换
原因
- 小说阅读需要适应用户阅读习惯,有时候用户需要横屏阅读,因此需要实现阅读界面横竖屏模式切换
- 如果不设置上面第 1 步的代码,那么横竖屏切换会重新注销 Activity,即结束当前活动的生命周期并重新开启一个新的声明周期。这样不仅需要时间重新进行网络访问获取小说章节内容而且会影响到用户使用体验。
方法
- 在
AndroidManifest.xml
中对 Activity 设置属性(关键)
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"
-
横竖屏切换后台 Java 代码
切换到横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
切换到竖屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
五、应用部署方法
下载好源码之后通过 Android studio 部署到手机或虚拟机即可,或直接安装 report 目录下的 apk 文件。
注:应用开发测试环境的 sdk 版本最低为 22,最高为 28。
资源下载地址:https://download.csdn.net/download/sheziqiong/85604746