android自定義控件創(chuàng)建翻頁(yè)接口詳細(xì)代碼
本文分享的這個(gè)類的目的是為在看書(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è)類的目的是為在看書(shū)翻頁(yè)時(shí),需要進(jìn)行的動(dòng)作提供接口。 * 包括翻向下一頁(yè),翻向上一頁(yè)。在翻到每章最后一頁(yè)時(shí),如果后面還有章節(jié)就繼續(xù)翻向下一章節(jié),沒(méi)有就向用戶顯示已讀完。 * 在翻向上一章節(jié)時(shí),如果前面還有章節(jié),就翻到上一章節(jié),沒(méi)有就向用戶顯示,這已經(jīng)是第一章節(jié)。 * * 在直覺(jué)上認(rèn)為這個(gè)應(yīng)該只設(shè)置成一個(gè)接口,因?yàn)橹恍柘蛞晥D層提供動(dòng)作接口,也就是本類應(yīng)屬于模型層。則其設(shè)置為一個(gè)借口可能也合適。 * 但是如果設(shè)置成一個(gè)接口,那么接口的實(shí)現(xiàn)類,有多個(gè)都要保存的數(shù)據(jù)。那么為了代碼重用,抽象類可能比接口更加合適。 上面是個(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)類似QQ空間的滾動(dòng)翻頁(yè)與滾動(dòng)加載效果
- Android使用手勢(shì)實(shí)現(xiàn)翻頁(yè)效果
相關(guān)文章
Android 系統(tǒng)相機(jī)拍照后相片無(wú)法在相冊(cè)中顯示解決辦法
這篇文章主要介紹了Android 系統(tǒng)相機(jī)拍照后相片無(wú)法在相冊(cè)中顯示解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12Android開(kāi)發(fā)Compose remember原理解析
這篇文章主要為大家介紹了Android開(kāi)發(fā)Compose remember原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07Android 保存Fragment 切換狀態(tài)實(shí)例代碼
本文主要介紹Android Fragment的應(yīng)用,這里給大家用實(shí)例代碼詳細(xì)介紹了Android Fragment 切換狀態(tài),有需要的小伙伴可以參考下2016-07-07Android實(shí)現(xiàn)帶簽到贏積分功能的日歷
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶簽到贏積分功能的日歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android組件間通信--深入理解Intent與IntentFilter
本篇文章是對(duì)Android組件間通信Intent與IntentFilter進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05詳解Android JetPack之LiveData的工作原理
這篇文章主要介紹了詳解Android JetPack之LiveData的工作原理,幫助大家更好的理解和學(xué)習(xí)使用Android開(kāi)發(fā),感興趣的朋友可以了解下2021-03-03Android給自定義按鍵添加廣播和通過(guò)廣播給當(dāng)前焦點(diǎn)輸入框賦值
這篇文章主要介紹了Android給自定義按鍵添加廣播和通過(guò)廣播給當(dāng)前焦點(diǎn)輸入框賦值的相關(guān)資料,需要的朋友可以參考下2016-10-10kotlin 官方學(xué)習(xí)教程之基礎(chǔ)語(yǔ)法詳解
這篇文章主要介紹了kotlin 官方學(xué)習(xí)教程之基礎(chǔ)語(yǔ)法詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05Android編程實(shí)現(xiàn)將壓縮數(shù)據(jù)庫(kù)文件拷貝到安裝目錄的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)將壓縮數(shù)據(jù)庫(kù)文件拷貝到安裝目錄的方法,涉及Android處理壓縮文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10android項(xiàng)目實(shí)現(xiàn)帶進(jìn)度條的系統(tǒng)通知欄消息
本篇文章主要介紹了android項(xiàng)目實(shí)現(xiàn)帶進(jìn)度條的系統(tǒng)通知欄消息,就是實(shí)現(xiàn)在通知欄看到下載進(jìn)度。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-10-10