android txt小说阅读器的实现

来源:互联网 发布:ubuntu启动引导器设置 编辑:程序博客网 时间:2024/04/28 17:05


既然做出来,想整理一下实现的思路,有时间再封装一下,做成一个自己喜欢的风格的阅读器。


实现这个肯定是自定义view啦,将字符一个一个的画上去,自己定义行距、上下左右边距、字体大小、背景、字体样式等等。然后复写了ontouch事件,完成手势,使之实现点击切换,滑动切换。

整个阅读器的难点,我觉得在以下三个部分:

1.数据分页。

2.支持不同编码格式。

3.切换手势。


好啦,一个一个说。


1.数据分页。因为看的是一页一页的看的,所以必须拿出一页一页的数据画到bitmap上去。那么上一页的结束位置必须要与下一页的开始位置衔接起来,除外发现了一个问题,每一页除了衔接之外还要分行,行数必须要根据屏幕的大小、字体大小、行间距来计算出来。好像不好做,如何分行啊。通过找资料,发现paint有个方法可以返回可以显示的字符数,就是可以返回指定字符串可以显示的字符数。所以可以通过这个进行分行了。

 mPaint.breakText(str, true, with, null);

在分行的时候又发现了一个问题。我们发现阅读器每一段的最后一行并不全是满行的,这样直接分行会导致一个问题,就是段落的最后一行或许会与下一段的开始一行的开头在同一行。解决的方法就是先分段在分行。

分段的方法:

/** * TODO将字符串分段 上午8:59:18 *  * @param datas * @return */public List<String> SeperateByParagph(String datas) {List<String> paragphdatas = new ArrayList<String>();if (datas != null) {String[] ps = datas.split("\r\n");for (int i = 0; i < ps.length; i++) {ps[i] = ps[i] + "  ";paragphdatas.add(ps[i]);}if (paragphdatas.size() > 0) {String lastp = paragphdatas.get(paragphdatas.size() - 1).substring(0,paragphdatas.get(paragphdatas.size() - 1).length() - 1);paragphdatas.remove(paragphdatas.size() - 1);paragphdatas.add(lastp);}} else {paragphdatas.add(datas);}return paragphdatas;}



分行的方法:

/** * 将段落字符串截取成句数据,存储在集合里 2016年1月7日上午10:46:44 *  * @param mpPaint * @param paragraphstr * @return */public List<String> SeparateParagraphtoLines(String paragraphstr) {Paint mPaint = getTextPaint();mPaint.setSubpixelText(true);List<String> linesdata = new ArrayList<String>();String str = paragraphstr;int with = getWindowWith() - getTxtReadConfig().getPaddingleft() - getTxtReadConfig().getPaddingright();for (; str.length() > 0;) {int nums = mPaint.breakText(str, true, with, null);if (nums <= str.length()) {String linnstr = str.substring(0, nums);linesdata.add(linnstr);str = str.substring(nums, str.length());} else {linesdata.add(str);str = "";}}return linesdata;}


所以分页的过程如下:





分页了之后,需要标志该页的开始位置与结束位置,为了下次分页的时知道在哪里开始。


public class PageEntity {private int firstbyetposition;private int lastbyteposition;private int pageindex;private List<String> LinesData;}

这里顺便说一下,为了实现页的进度跳转,必须对整个txt文件进行分页,分页的结果可以通过数据库保存起来,保存的数据就是保存每一页的开始位置与结束位置。这样跳转到指定页的时候只需要获取指定位置的数据就可以了。所以没有完成分页的时候可以通过上面的流程进行获取数据,分页完成后可以直接获取指定位置的数据就可以了。

分页的基本思路就是这样!


2.解决编码的问题。难点就是获取文件的编码,自己怎么弄都获取不正确,后来找到一个文件编码检测器的 东西,发现获取是还是蛮准确是。我的处理思路是获取文件的编码,如果是utf-8的话就在直接处理,不是的话就先将整个文件转为utf-8的编码后再处理。



3.切换手势。基本的思路就是如下,其实发现效果也不是特别完美,有时间再看看完善一下。








9 1