android自定義控件創(chuàng)建翻頁(yè)接口詳細(xì)代碼
本文分享的這個(gè)類(lèi)的目的是為在看書(shū)翻頁(yè)時(shí),需要進(jìn)行的動(dòng)作提供接口,利用android自定義控件創(chuàng)建翻頁(yè)接口,具體內(nèi)容如下
BookPage.java
package com.horse.util;
import java.text.DecimalFormat;
import java.util.Vector;
import com.horse.bean.Chapter;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.text.format.Time;
/**
* 這個(gè)類(lèi)的目的是為在看書(shū)翻頁(yè)時(shí),需要進(jìn)行的動(dòng)作提供接口。
* 包括翻向下一頁(yè),翻向上一頁(yè)。在翻到每章最后一頁(yè)時(shí),如果后面還有章節(jié)就繼續(xù)翻向下一章節(jié),沒(méi)有就向用戶(hù)顯示已讀完。
* 在翻向上一章節(jié)時(shí),如果前面還有章節(jié),就翻到上一章節(jié),沒(méi)有就向用戶(hù)顯示,這已經(jīng)是第一章節(jié)。
*
* 在直覺(jué)上認(rèn)為這個(gè)應(yīng)該只設(shè)置成一個(gè)接口,因?yàn)橹恍柘蛞晥D層提供動(dòng)作接口,也就是本類(lèi)應(yīng)屬于模型層。則其設(shè)置為一個(gè)借口可能也合適。
* 但是如果設(shè)置成一個(gè)接口,那么接口的實(shí)現(xiàn)類(lèi),有多個(gè)都要保存的數(shù)據(jù)。那么為了代碼重用,抽象類(lèi)可能比接口更加合適。 上面是個(gè)人分析,可能不是很合適。
*
* @author MJZ
*
*/
public class BookPage {
// configuration information
private int screenWidth; // 屏幕寬度
private int screenHeight; // 屏幕高度
private int fontSize; // 字體大小
private int lineHgight; //每行的高度
private int marginWidth = 15; // 左右與邊緣的距離
private int marginHeight = 15; // 上下與邊緣的距離
private int textColor; // 字體顏色
private Bitmap bgBitmap; // 背景圖片
private int bgColor; // 背景顏色
private Paint paint;
private Paint paintBottom;
private int visibleWidth; // 屏幕中可顯示文本的寬度
private int visibleHeight;
private Chapter chapter; // 需要處理的章節(jié)對(duì)象
private Vector<String> linesVe; // 將章節(jié)內(nèi)容分成行,并將每頁(yè)按行存儲(chǔ)到vector對(duì)象中
private int lineCount; // 一個(gè)章節(jié)在當(dāng)前配置下一共有多少行
private String content;
private int chapterLen; // 章節(jié)的長(zhǎng)度
// private int curCharPos; // 當(dāng)前字符在章節(jié)中所在位置
private int charBegin; // 每一頁(yè)第一個(gè)字符在章節(jié)中的位置
private int charEnd; // 每一頁(yè)最后一個(gè)字符在章節(jié)中的位置
private boolean isfirstPage;
private boolean islastPage;
private Vector<Vector<String>> pagesVe;
int pageNum;
/**
* 在新建一個(gè)BookPage對(duì)象時(shí),需要向其提供數(shù)據(jù),以支持屏幕翻頁(yè)功能。
*
* @param screenWidth
* 屏幕寬度,用來(lái)計(jì)算每行顯示多少字
* @param screenHeight
* 屏幕高度,用來(lái)計(jì)算每頁(yè)顯示多少行
* @param chapter
* 章節(jié)對(duì)象
*/
public BookPage(int screenWidth, int screenHeight, Chapter chapter) {
this.screenHeight = screenHeight;
this.screenWidth = screenWidth;
this.chapter = chapter;
init();
}
/**
* 初始最好按照定義變量的順序來(lái)初始化,統(tǒng)一。在將來(lái)需要修改某個(gè)變量的時(shí)候,容易找到。 對(duì)代碼維護(hù)應(yīng)該也很有用吧。
*/
protected void init() {
bgBitmap = null;
bgColor = 0xffff9e85;
textColor = Color.BLACK;
content = chapter.getContent();
chapterLen = content.length();
// curCharPos = 0;
charBegin = 0;
charEnd = 0;
fontSize = 30;
lineHgight = fontSize + 8;
linesVe = new Vector<String>();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextAlign(Align.LEFT);
paint.setTextSize(fontSize);
paint.setColor(textColor);
paintBottom = new Paint(Paint.ANTI_ALIAS_FLAG);
paintBottom.setTextAlign(Align.LEFT);
paintBottom.setTextSize(fontSize / 2);
paintBottom.setColor(textColor);
visibleWidth = screenWidth - marginWidth * 2;
visibleHeight = screenHeight - marginHeight * 2;
lineCount = visibleHeight / lineHgight - 2;
isfirstPage = true;
islastPage = false;
pagesVe = new Vector<Vector<String>>();
pageNum = -1;
slicePage();
}
public Vector<String> getCurPage() {
return linesVe;
}
protected void slicePage() {
pagesVe.clear();
int curPos = 0;
while (curPos < chapterLen) {
Vector<String> lines = new Vector<String>();
charBegin = curPos;
while (lines.size() < lineCount && curPos < chapterLen) {
int i = content.indexOf("\n", curPos);
String paragraphStr = content.substring(curPos, i);
// curCharPos += i;
if (curPos == i)
lines.add("");
while (paragraphStr.length() > 0) {
int horSize = paint.breakText(paragraphStr, true,
visibleWidth, null);
lines.add(paragraphStr.substring(0, horSize));
paragraphStr = paragraphStr.substring(horSize);
curPos += horSize;
if (lines.size() > lineCount)
break;
}
// 如果是把一整段讀取完的話,需要給當(dāng)前位置加1
if (paragraphStr.length() == 0)
curPos += "\n".length();
}
pagesVe.add(lines);
}
}
/**
* 翻到下一頁(yè)
*/
public boolean nextPage() {
if (isLastPage()) {
if (!nextChapter()) // 如果已經(jīng)到本書(shū)末尾,那么不能繼續(xù)執(zhí)行翻頁(yè)代碼
return false;
}
/*
* Vector<String> lines = new Vector<String>(); charBegin = charEnd;
* while (lines.size() < lineCount && charEnd < chapterLen) { int i =
* content.indexOf("\n", charEnd); String paragraphStr =
* content.substring(charEnd, i); // curCharPos += i; if (charEnd == i)
* lines.add("");
*
* while (paragraphStr.length() > 0) { int horSize =
* paint.breakText(paragraphStr, true, visibleWidth, null);
* lines.add(paragraphStr.substring(0, horSize)); paragraphStr =
* paragraphStr.substring(horSize); charEnd += horSize; if (lines.size()
* > lineCount) break; } // 如果是把一整段讀取完的話,需要給當(dāng)前位置加1 if
* (paragraphStr.length() == 0) charEnd += "\n".length(); } linesVe =
* lines;
*/
linesVe = pagesVe.get(++pageNum);
return true;
}
/**
* 翻到上一頁(yè)
*/
public boolean prePage() {
if (isFirstPage()) {
if (!preChapter()) // 如果已經(jīng)到本書(shū)第一章,就不能繼續(xù)執(zhí)行翻頁(yè)代碼
return false;
}
/*
* Vector<String> lines = new Vector<String>(); String backStr =
* content.substring(0, charBegin); charEnd = charBegin;
*
* while (lines.size() < lineCount && charBegin > 0) { int i =
* backStr.lastIndexOf("\n"); if(i == -1) i = 0; String paragraphStr =
* backStr.substring(i, charBegin); Vector<String> vet = new
* Vector<String>(lines);
*
* // if(charBegin == i)lines.add("");
*
* while (paragraphStr.length() > 0) { int horSize =
* paint.breakText(paragraphStr, true, visibleWidth, null);
* lines.add(paragraphStr.substring(0, horSize)); paragraphStr =
* paragraphStr.substring(horSize); charBegin -= horSize; if
* (lines.size() > lineCount) break; }
*
* backStr = content.substring(0, charBegin); int j = -1; for (String
* line : vet) lines.insertElementAt(line, ++j); } linesVe = lines;
*/
linesVe = pagesVe.get(--pageNum);
return true;
}
/**
* 跳到下一章,若返回值為false,則當(dāng)前章節(jié)已經(jīng)為最后一章
*/
public boolean nextChapter() {
int order = chapter.getOrder();
Chapter tempChapter = IOHelper.getChapter(order + 1);
if (tempChapter == null)
return false;
chapter = tempChapter;
content = chapter.getContent();
chapterLen = content.length();
// curCharPos = 0;
charBegin = 0;
charEnd = 0;
slicePage();
pageNum = -1;
return true;
}
/**
* 跳到上一章,若返回值為false,則當(dāng)前章節(jié)已經(jīng)為第一章
*/
public boolean preChapter() {
int order = chapter.getOrder();
Chapter tempChapter = IOHelper.getChapter(order - 1);
if (tempChapter == null)
return false;
chapter = tempChapter;
content = chapter.getContent();
chapterLen = content.length();
// curCharPos = chapterLen;
charBegin = chapterLen;
charEnd = chapterLen;
slicePage();
pageNum = pagesVe.size();
return true;
}
public boolean isFirstPage() {
if (pageNum <= 0)
return true;
return false;
}
public boolean isLastPage() {
if (pageNum >= pagesVe.size() - 1)
return true;
return false;
}
public void draw(Canvas c) {
if (linesVe.size() == 0)
nextPage();
if (linesVe.size() > 0) {
if (bgBitmap == null)
c.drawColor(bgColor);
else
c.drawBitmap(bgBitmap, 0, 0, null);
int y = marginHeight;
for (String line : linesVe) {
y += lineHgight;
c.drawText(line, marginWidth, y, paint);
}
}
// float percent = (float) (charBegin * 1.0 / chapterLen);
float percent = (float) ((pageNum + 1) * 1.0 / pagesVe.size());
DecimalFormat df = new DecimalFormat("#0.0");
String percetStr = df.format(percent * 100) + "%";
Time time = new Time();
time.setToNow();
String timeStr;
if (time.minute < 10)
timeStr = "" + time.hour + " : 0" + time.minute;
else
timeStr = "" + time.hour + " : " + time.minute;
int pSWidth = (int) paintBottom.measureText("99.9%") + 2;
int titWidth = (int) paintBottom.measureText(chapter.getTitle());
c.drawText(timeStr, marginWidth / 2, screenHeight - 5, paintBottom);
c.drawText(chapter.getTitle(), screenWidth / 2 - titWidth / 2,
screenHeight - 5, paintBottom);
c.drawText(percetStr, screenWidth - pSWidth, screenHeight - 5, paintBottom);
}
public void setBgBitmap(Bitmap bMap) {
bgBitmap = Bitmap.createScaledBitmap(bMap, screenWidth, screenHeight,
true);
}
}
com.horse.bean.Chapter
package com.horse.bean;
/**
* 章節(jié)信息,包括標(biāo)題和內(nèi)容,及順序
* @author MJZ
*
*/
public class Chapter {
private String title;
private String content;
private int order;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android中圖片翻頁(yè)效果簡(jiǎn)單的實(shí)現(xiàn)方法
- 解析Android中實(shí)現(xiàn)滑動(dòng)翻頁(yè)之ViewFlipper的使用詳解
- Android實(shí)現(xiàn)閱讀APP平移翻頁(yè)效果
- Android利用懸浮按鈕實(shí)現(xiàn)翻頁(yè)效果
- Android通過(guò)手勢(shì)實(shí)現(xiàn)答題器翻頁(yè)效果
- 基于Android實(shí)現(xiàn)3D翻頁(yè)效果
- Android程序開(kāi)發(fā)ListView+Json+異步網(wǎng)絡(luò)圖片加載+滾動(dòng)翻頁(yè)的例子(圖片能緩存,圖片不錯(cuò)亂)
- android ViewPager實(shí)現(xiàn)滑動(dòng)翻頁(yè)效果實(shí)例代碼
- Android基于ListView實(shí)現(xiàn)類(lèi)似QQ空間的滾動(dòng)翻頁(yè)與滾動(dòng)加載效果
- Android使用手勢(shì)實(shí)現(xiàn)翻頁(yè)效果
相關(guān)文章
Android開(kāi)發(fā)自學(xué)筆記(二):工程文件剖析
這篇文章主要介紹了Android開(kāi)發(fā)自學(xué)筆記(二):工程文件剖析,本文講解了AndroidManifest.xml、src文件夾、res文件夾等文件的作用,需要的朋友可以參考下2015-04-04
Android中如何實(shí)現(xiàn)清空搜索框的文字
本文主要介紹Android中實(shí)現(xiàn)清空搜索框的文字的方法。項(xiàng)目中的有關(guān)搜索的地方,加上清空文字的功能,目的是為了增加用戶(hù)體驗(yàn),使用戶(hù)刪除文本更加快捷。需要的朋友一起來(lái)看下吧2016-12-12
Android使用多線程實(shí)現(xiàn)斷點(diǎn)下載
這篇文章主要介紹了Android使用多線程實(shí)現(xiàn)斷點(diǎn)下載,多線程下載是加快下載速度的一種方式,感興趣的小伙伴們可以參考一下2016-03-03
Flutter中g(shù)o_router路由管理的使用指南
go_router?是一個(gè)?Flutter?的第三方路由插件,相比?Flutter?自帶的路由,go_router?更加靈活,而且簡(jiǎn)單易用,下面小編就來(lái)和大家聊聊go_router的使用吧2023-08-08
Android ListView數(shù)據(jù)的分批顯示功能
本文通過(guò)實(shí)例代碼給大家分享了Android ListView數(shù)據(jù)的分批顯示功能,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友參考下吧2017-04-04
android: targetSdkVersion升級(jí)中Only fullscreen activities can r
這篇文章主要給大家介紹了關(guān)于Android target SDK和build tool版本升級(jí)中遇到Only fullscreen activities can request orientation問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-09-09
android 為應(yīng)用程序創(chuàng)建桌面快捷方式技巧分享
手機(jī)裝的軟件過(guò)多,找起來(lái)很不方便,所以在主頁(yè)面有一個(gè)快捷方式的話會(huì)很不錯(cuò)的,本文將介紹如何實(shí)現(xiàn),需要了解跟多的朋友可以參考下2012-12-12
kotlin實(shí)戰(zhàn)教程之lambda編程
這篇文章主要給大家介紹了關(guān)于kotlin實(shí)戰(zhàn)教程之lambda編程的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用kotlin具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09

