基于Android的本地电子书阅读器的设计与实现Ebook(2)

接着上回,我们继续分说下面步骤。
用户登录后,映入眼帘的就是我们实现阅读器的主要三个界面,分别是书架、感悟、分类。

首先这三个界面的切换是通过Fragment实现的底部导航:

activity_main_login.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainLogin"><androidx.viewpager.widget.ViewPagerandroid:id="@+id/viewPager"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"></androidx.viewpager.widget.ViewPager><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/bottomNavigationView"app:menu="@menu/menu_main"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/bookbg"app:itemIconTint="@drawable/fgbtn"app:labelVisibilityMode="auto"/>
</LinearLayout>

这里的menu是在res文件夹下创建的menu文件夹,具体存放图标和文字
menu_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:id="@+id/item1"android:title="书架"android:icon="@drawable/book"/><itemandroid:id="@+id/item2"android:title="感悟"android:icon="@drawable/note"/><itemandroid:id="@+id/item3"android:title="分类"android:icon="@drawable/sort"/>
</menu>

接下来是java文件MainLogin:

 protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_login);viewPager=findViewById(R.id.viewPager);bottomNavigationView=findViewById(R.id.bottomNavigationView);//初始化fragments数组list=new ArrayList<Fragment>();list.add(new LoginFragment1());list.add(new LoginFragment2());list.add(new LoginFragment3());//设置底部导航点击和不点击时颜色Resources resource = getResources();@SuppressLint("ResourceType")ColorStateList csl = resource.getColorStateList(R.drawable.fgbtn);bottomNavigationView.setItemTextColor(csl);viewPager.setAdapter(new MyAdapter(getSupportFragmentManager(),list));//点击底部导航项,显示对应的页面bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {@Overridepublic boolean onNavigationItemSelected(@NonNull MenuItem item) {switch (item.getItemId()){case R.id.item1:viewPager.setCurrentItem(0);break;case R.id.item2:viewPager.setCurrentItem(1);break;case R.id.item3:viewPager.setCurrentItem(2);break;}return true;}});//页面左右滑动时,让底部的导航项和显示的页面保持一致viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {if(menuItem==null){menuItem=bottomNavigationView.getMenu().getItem(0);}//将上次的选择设置为false,等待下次的选择menuItem.setChecked(false);menuItem=bottomNavigationView.getMenu().getItem(position);menuItem.setChecked(true);}@Overridepublic void onPageScrollStateChanged(int state) {}});}//作为fragment的适配器private class MyAdapter extends FragmentPagerAdapter{List list;public MyAdapter(@NonNull FragmentManager fm, List list) {super(fm);this.list=list;}@NonNull@Overridepublic Fragment getItem(int position){return (Fragment) list.get(position);}@Overridepublic int getCount(){return list.size();}}
}

现在我们的底部导航已经建好了,接下来需要我们新建三个fragment页面,分别实现书架、感悟、分类三个部分。

首先是书架部分,先上图看看效果:

fragment_login1.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"tools:context=".LoginFragment1"><LinearLayoutandroid:layout_weight="1"android:layout_width="0dp"android:layout_height="match_parent"android:orientation="vertical"><com.example.ebook.MarqueTextViewandroid:layout_width="wrap_content"android:layout_height="50dp"android:id="@+id/mtv"android:ellipsize="marquee"android:textSize="25dp"android:singleLine="true"android:marqueeRepeatLimit="marquee_forever"android:background="@drawable/bookbg"/><ListViewandroid:id="@+id/lg3_listView"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/bookbg2"/></LinearLayout></LinearLayout>

在这里说明一下,页面的顶部本质是一个TextView控件,但文字是可以横向滚动的,所以得自己写一个基于TextView的子类。
java文件MarqueTextView:

public class MarqueTextView extends androidx.appcompat.widget.AppCompatTextView {public MarqueTextView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public MarqueTextView(Context context, AttributeSet attrs) {super(context, attrs);}public MarqueTextView(Context context) {super(context);}@Overridepublic boolean isFocused() {//就是把这里返回true即可return true;}
}

然后是实现书架这一部分的java文件LoginFragment1:

public class LoginFragment1 extends Fragment implements AdapterView.OnItemClickListener{//变量名注册ListView listView;SimpleAdapter simpleAdapter;public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_login1, container, false);//id注册listView = view.findViewById(R.id.lg3_listView);MarqueTextView as = view.findViewById(R.id.mtv);simpleAdapter = new SimpleAdapter(getActivity(),getData(),R.layout.item,new String[]{"title","image"},new int[]{R.id.item_tv,R.id.item_image});//设置适配器监听器listView.setAdapter(simpleAdapter);listView.setOnItemClickListener(this);//将文件由assets转移到手机空间copyFilesFromAssets(getActivity(),"ml","/data/data/com.example.ebook/files");as.setText(load());return view;}//设置listview图文private List<Map<String,Object>> getData() {String [] titles={"射雕英雄传\n简介:南宋末年,金兵入侵,朝廷奸臣当道。全真派丘处机因杀死汉奸王道乾,被官兵追杀,逃到江南一个小村牛家庄,与隐居在此处的爱国义士郭啸天和杨铁心一见如故,以“靖、康”为他俩即将出生的孩子命名,并留下一对短剑作为信物……","神雕侠侣\n简介:南宋末年,江南少年杨过被郭靖送去全真教学武。全真教教规森严,天性叛逆的杨过在教中吃尽苦头,忍无可忍,终于逃出全真教。被活死人墓中的小龙女收留为徒。师徒二人在墓中一起练武、一起长大,渐生情愫……","倚天屠龙记\n简介:少林寺觉远禅师看护《楞伽经》不力,导致经书被尹克西和潇湘子盗走。潇湘子和尹克西互相猜忌残杀,临终之前幡然醒悟,委托何足道向觉远转达经书的下落。何足道接受委托,并向少林寺发出挑战。适逢郭靖、黄蓉的女儿郭襄前往少林寺寻找杨过……","绝对娇宠\n简介:作者:陈三年\n斯文霸道总裁装逼乘骄纵美人,爱让人勇敢,双向奔赴,梦会成真。","斗罗大陆\n简介:外门弟子唐三,因偷学内门绝学为唐门所不容,跳崖明志时却发专现没有死,反而以另属外一个身份来到了另一个世界,名叫斗罗大陆。这里没有魔法,没有斗气,没有武术,却有神奇的武魂……","末日游戏场\n简介:系统:“你们的任务是活下去,倾尽所有,不择手段地活下去,完成一场挑战,即可获得一张通行证。\n星际333年,地球环境无法生存 开启全民末日游戏场,提过游戏得到通行证,获取生存资格。","完美世界\n简介:一粒尘可填海,一根草斩尽日月星辰,弹指间天翻地覆。\n群雄并起,万族林立,诸圣争霸,乱天动地。问苍茫大地,谁主沉浮?!\n一个少年从大荒中走出,一切从这里开始\n"};int [] images={R.drawable.im1,R.drawable.im2,R.drawable.im3,R.drawable.im4,R.drawable.im5,R.drawable.im6,R.drawable.im7};List<Map<String,Object>> list= new ArrayList<>();for(int i=0;i<7;i++){Map  map = new HashMap();map.put("title",titles[i]);map.put("image",images[i]);list.add(map);}return list;}public void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);}//设置listview点击触发事件@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {switch (position){case 0:Intent intent0 = new Intent(getActivity(),ReadBook.class);intent0.putExtra("extra","0.txt");startActivity(intent0);break;case 1:Intent intent1 = new Intent(getActivity(),ReadBook.class);intent1.putExtra("extra","1.txt");startActivity(intent1);break;case 2:Intent intent2 = new Intent(getActivity(),ReadBook.class);intent2.putExtra("extra","2.txt");startActivity(intent2);break;case 3:Intent intent3 = new Intent(getActivity(),ReadBook.class);intent3.putExtra("extra","3.txt");startActivity(intent3);break;case 4:Intent intent4 = new Intent(getActivity(),ReadBook.class);intent4.putExtra("extra","4.txt");startActivity(intent4);break;case 5:Intent intent5 = new Intent(getActivity(),ReadBook.class);intent5.putExtra("extra","5.txt");startActivity(intent5);break;case 6:Intent intent6 = new Intent(getActivity(),ReadBook.class);intent6.putExtra("extra","6.txt");startActivity(intent6);break;default:throw new IllegalStateException("Unexpected value: " + position);}}//       从assets目录中复制整个文件夹内容到新的路径下
//       @param  context  Context 使用CopyFiles类的Activity
//      @param  oldPath  String  原文件路径  如:Data(assets文件夹下文件夹名称)
//      @param  newPath  String  复制后路径  如:data/data/(手机内部存储路径名称)public void copyFilesFromAssets(Context context, String oldPath, String newPath) {try {String fileNames[] = context.getAssets().list(oldPath);//获取assets目录下的所有文件及目录名if (fileNames.length > 0) {//如果是目录File file = new File(newPath);file.mkdirs();//如果文件夹不存在,则递归for (String fileName : fileNames) {copyFilesFromAssets(context,oldPath + "/" + fileName,newPath+"/"+fileName);}} else {//如果是文件InputStream is = context.getAssets().open(oldPath);FileOutputStream fos = new FileOutputStream(new File(newPath));byte[] buffer = new byte[1024];int byteCount=0;while((byteCount=is.read(buffer))!=-1) {//循环从输入流读取 buffer字节fos.write(buffer, 0, byteCount);//将读取的输入流写入到输出流}fos.flush();//刷新缓冲区is.close();fos.close();}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();//如果捕捉到错误则通知UI线程//MainActivity.handler.sendEmptyMessage(COPY_FALSE);}}//设置顶部文字并循环播放String  load(){String tit="  欢迎来到Ebook阅读器,这是您打开知识宝库的钥匙!\n" +"  欢迎来到Ebook阅读器,这是您打开知识宝库的钥匙!\n" ;return tit;}
}

其实现在看来当时写的还是非常简单的,在书架展示这一块是靠代码后台输入文字介绍,以及用简单地Switch现实跳转,换成现在有更好的解决方式。不过这是后话,我想能力的提升也是循序渐进的。我还是来解释一些核心的代码。
书的内容是以txt格式存放在之前提到的asset文件夹里面,copyFilesFromAssets函数便是实现对asset文件内容的读取。这样就实现了文件可以随着代码一起保存并放到手机上,不用创建数据库(现在觉得创建了数据库实现的功能可能可以更加完善)是一种投机取巧的方式
这里的适配器simpleAdapter里的item:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/item_image"android:layout_margin="10dp"android:layout_width="280px"android:layout_height="580px" /><TextViewandroid:textSize="15dp"android:layout_margin="10dp"android:padding="10px"android:textColor="@color/black"android:layout_width="match_parent"android:layout_height="580px"android:id="@+id/item_tv"/></LinearLayout>

当用户点进一本书后会看到类似界面:

activity_read_book.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="@drawable/rbookbg3"tools:context=".ReadBook"><TextViewandroid:layout_width="wrap_content"android:layout_height="650dp"android:textSize="20dp"android:id="@+id/sd"android:layout_margin="30dp"android:textColor="@color/black"android:scrollbars="vertical"/></LinearLayout>

java文件ReadBook:

public class ReadBook extends AppCompatActivity {String txt;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_read_book);Intent intent=getIntent();txt=intent.getStringExtra("extra");Log.d("ReadBook",txt);TextView sb =  findViewById(R.id.sd);sb.setMovementMethod(ScrollingMovementMethod.getInstance());sb.setSelected(true);sb.setText(load());}//获取手机空间中的txt文件public String load() {FileInputStream in = null;BufferedReader reader = null;StringBuilder content = new StringBuilder();try {in = openFileInput(txt);reader = new BufferedReader(new InputStreamReader(in));String line = "";while ((line = reader.readLine()) != null) {content.append("\n");content.append(line);}} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e) {e.printStackTrace();}}}return content.toString();}
}

这里的Log是用来实现两个活动直接的信息传递,load函数就是基本的读取txt文件操作了。

到此为止作为一个阅读器最重要的阅读功能就可以实现了,接下来的感悟和分类,均使用到了数据库,待下回分解。

基于Android的本地电子书阅读器的设计与实现Ebook(2)相关推荐

  1. 基于Android的本地电子书阅读器的设计与实现Ebook(1)

    基于Android的本地电子书阅读器的设计与实现Ebook(1) 学习Android时间不久,试着做了一个本地电子书阅读器APP,因为知识浅薄并不能像其他大佬一样实现各种繁杂的功能,但可以实现基本的阅 ...

  2. 基于Android的本地电子书阅读器的设计与实现Ebook(3)

    之前写这个只是抱着半玩的心态,没有想到有这么多网友愿意驻足浏览,十分的惊喜.这里浅浅说一下我并不是专门学软件开发的,所以如果有什么错误请多指教. 接上回分解.现在我们来到第二个界面"感悟&q ...

  3. 基于Android的本地电子书阅读器的设计与实现Ebook(终章)

    昨天写到最后实在是卡的受不了了,今天把这个写完. 最后就是补充几个xml,不知道前面有没有放,在这里补充下. 应该有五个是遗漏的: 我在这里按照顺序依次给出代码,就不标名字了 <?xml ver ...

  4. 基于Android的文本语音朗读器的设计与实现(有声小说APP)

    摘 要 随着时代的发展,越来越多的信息正在产生,人们对信息的获取也越来越重视,从传统的看书到现在的网络,看视频,听广播.多年来,人们获取信息的方式发生了变化.随着人们进入信息时代和网络文学的发展,人们 ...

  5. 张利国,龚海平,王植萌.android移动开发入门与进阶,开题报告-基于Android的手机音乐播放器的设计与实现.doc...

    盐城师范学院 毕业设计开题报告 题 目: 基于android的手机音乐播放器 的设计与实现 姓 名: 二级学院: 信息工程学院 专 业: 软件工程 班 级: 12(1) 学 号: 指导教师: 职称: ...

  6. Android电子书阅读器的设计与实现

    Android电子书阅读器 包括Android客服端和jsp服务端 主要有,在线图书,本地图书,用户设置,书签管理,JSP后台,可以管理用户帐号,图书信息管理 我的QQ 609085431

  7. 基于android的在线音乐播放器app设计

    Android是Google公司公布的基于Linux内核的手机操作系统,其代码属于完全开放,为开源软件开发人员提供使用方便的框架和平台.,本文以Android开发平台为基础,介绍了音乐播放器的开发.首 ...

  8. [内附完整源码和文档] 基于Android的手机音乐播放器的设计与实现

    摘 要 随着Android系统和移动互联网的快速崛起,手机已经成为人们生活不可缺的一部分,在现代人的生活中,人们生活节奏的加快,生活压力越来越大,碎片化的时间越来越多,那么一个可以在碎片化的时间内调节 ...

  9. 基于Android的手机音乐播放器的设计与实现

    源码及论文下载:http://www.byamd.xyz/tag/android/ 摘 要 随着Android系统和移动互联网的快速崛起,手机已经成为人们生活不可缺的一部分,在现代人的生活中,人们生活 ...

  10. 基于android系统的音乐播放器,基于Android系统的音乐播放器软件设计与实现.doc

    基于Android平台的音乐播放器 The Development of Mobile Music Player Based on Android platform system 学生学号: 学生姓名 ...

最新文章

  1. Android Studio 单刷《第一行代码》系列 07 —— Broadcast 广播
  2. nvidia-smi:Failed to initialize NVML: Driver/library version mismatch
  3. JetBrains —— JetBrains系列IDE优化配置(提高启动和运行速度)
  4. Mysql常用命令(二)
  5. java 干支_Java實現干支紀年法
  6. dp、sp 转换为 px 的工具类
  7. 2018年php框架,2018年的7个热门网站开发框架
  8. C# where()筛选方法
  9. 通过名称识别和处理弹出窗口
  10. linux下无sudo权限安装MatlabR2016
  11. Windows上搭建SFTP服务器
  12. xp激活30天到期_我的XP系统还剩30天激活怎么办
  13. Android 读取U盘文件
  14. C#顺时针逆时针旋转图片
  15. 每个人都是雕刻自己的艺术家,生活是你的背景
  16. 给2011年的MacBook Pro和MacBook Air升级到最新系统和做双系统时遇到的问题
  17. 系统内存占用率高导致电脑卡顿的解决方案
  18. Ubuntu18解决:Not creating XLA devices, tf_xla_enable_xla_devices not set
  19. 常见工具识别集锦-Windows应急响应工具
  20. python学习笔记(三)之字符串的处理

热门文章

  1. 神奇的Perl-哈希与数组(4)
  2. Binet‘s Formula 算法
  3. 业务中台--企业流程优化
  4. jmeter学习指南之生成html性能结果报告(篇幅较长谨慎阅读)
  5. Redis简介和优势
  6. 【Android】关于WIFI局域网的手机摄像头当视频监控用实现方案详解
  7. 图文并茂讲VLAN,让你看一遍就理解VLAN
  8. 4418GPIO口调用过程
  9. FIRST集 FOLLOW集和SELECT集
  10. 吴军《态度》读后感(1):人生哲学