android自定义控件创建翻页接口详细代码

本文分享的这个类的目的是为在看书翻页时,需要进行的动作提供接口,利用android自定义控件创建翻页接口,具体内容如下

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;

/**
 * 这个类的目的是为在看书翻页时,需要进行的动作提供接口。
 * 包括翻向下一页,翻向上一页。在翻到每章最后一页时,如果后面还有章节就继续翻向下一章节,没有就向用户显示已读完。
 * 在翻向上一章节时,如果前面还有章节,就翻到上一章节,没有就向用户显示,这已经是第一章节。
 *
 * 在直觉上认为这个应该只设置成一个接口,因为只需向视图层提供动作接口,也就是本类应属于模型层。则其设置为一个借口可能也合适。
 * 但是如果设置成一个接口,那么接口的实现类,有多个都要保存的数据。那么为了代码重用,抽象类可能比接口更加合适。 上面是个人分析,可能不是很合适。
 *
 * @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; // 需要处理的章节对象
 private Vector<String> linesVe; // 将章节內容分成行,并将每页按行存储到vector对象中
 private int lineCount; // 一个章节在当前配置下一共有多少行

 private String content;
 private int chapterLen; // 章节的长度
 // private int curCharPos; // 当前字符在章节中所在位置
 private int charBegin; // 每一页第一个字符在章节中的位置
 private int charEnd; // 每一页最后一个字符在章节中的位置
 private boolean isfirstPage;
 private boolean islastPage;

 private Vector<Vector<String>> pagesVe;
 int pageNum;

 /**
 * 在新建一个BookPage对象时,需要向其提供数据,以支持屏幕翻页功能。
 *
 * @param screenWidth
 *      屏幕宽度,用来计算每行显示多少字
 * @param screenHeight
 *      屏幕高度,用来计算每页显示多少行
 * @param chapter
 *      章节对象
 */
 public BookPage(int screenWidth, int screenHeight, Chapter chapter) {
 this.screenHeight = screenHeight;
 this.screenWidth = screenWidth;
 this.chapter = chapter;
 init();
 }

 /**
 * 初始最好按照定义变量的顺序来初始化,统一。在将来需要修改某个变量的时候,容易找到。 对代码维护应该也很有用吧。
 */
 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;
  }
  // 如果是把一整段读取完的话,需要给当前位置加1
  if (paragraphStr.length() == 0)
   curPos += "\n".length();
  }
  pagesVe.add(lines);
 }

 }

 /**
 * 翻到下一页
 */
 public boolean nextPage() {
 if (isLastPage()) {
  if (!nextChapter()) // 如果已经到本书末尾,那么不能继续执行翻页代码
  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; } // 如果是把一整段读取完的话,需要给当前位置加1 if
  * (paragraphStr.length() == 0) charEnd += "\n".length(); } linesVe =
  * lines;
  */
 linesVe = pagesVe.get(++pageNum);
 return true;
 }

 /**
 * 翻到上一页
 */
 public boolean prePage() {
 if (isFirstPage()) {
  if (!preChapter()) // 如果已经到本书第一章,就不能继续执行翻页代码
  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,则当前章节已经为最后一章
 */
 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,则当前章节已经为第一章
 */
 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;
/**
 * 章节信息,包括标题和内容,及顺序
 * @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;
 }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 基于Android实现3D翻页效果

    最近做了一个简单的3D效果翻页特效,先说说我的思路吧,首先我这个翻页效果并不是两个Activity之间的跳转,而是在同一个activity类切换不同的view而已.我现在的做法是单击一个button然后Gone当前的布局,然后把需要呈现的布局visible,在隐藏当前布局的时候启动动画,然后给动画添加监听,在动画结束时开始另外一个view的入场动画就行了. 下面来看下我的主页面的布局文件: <FrameLayout xmlns:android="http://schemas.android

  • Android利用悬浮按钮实现翻页效果

    今天给大家分享下自己用悬浮按钮点击实现翻页效果的例子. 首先,一个按钮要实现悬浮,就要用到系统顶级窗口相关的WindowManager,WindowManager.LayoutParams.那么在AndroidManifest.xml中添加权限: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 然后,我们要对WindowManager,WindowManager.Layout

  • Android程序开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)

    例子中用于解析Json的Gson请自己Google下载 主Activity: package COM.Example.Main; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import COM.Example.Main.R; import COM.Example.Main.stringG

  • 解析Android中实现滑动翻页之ViewFlipper的使用详解

    1)View切换的控件-ViewFlipper介绍 ViewFilpper类继承于ViewAnimator类.而ViewAnimator类继承于FrameLayout. 查看ViewAnimator类的源码可以看出此类的作用主要是为其中的View切换提供动画效果.该类有如下几个和动画相关的方法. setInAnimation:设置View进入屏幕时候使用的动画.该方法有两个重载方法,即可以直接传入Animation对象,也可以传入定义的Animation文件的resourceID. setOut

  • Android通过手势实现答题器翻页效果

    本文实例为大家分享了Android答题器翻页功能,主要使用ViewFilpper和GestureDetector来实现,供大家参考,具体内容如下 1.效果图 2.实现思路 把Activity的TouchEvent事件交个GestureDetector来处理,然后使用ViewFilpper使用动画控制多个组件的之间的切换效果.手势的一个Api就不详细说了,大家如果不了解可以查一下. 3.实现的步骤 1).构建手势检测器 2).准备数据 3).为ViewFilpper添加子控件. 4).初始化Ani

  • Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果

    本文实例讲述了Android基于ListView实现类似QQ空间的滚动翻页与滚动加载效果.分享给大家供大家参考,具体如下: 1. 滚动加载 listView.setOnScrollListener(new OnScrollListener() { //添加滚动条滚到最底部,加载余下的元素 @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState == OnScro

  • Android使用手势实现翻页效果

    本程序的手势检测思路就是把Activity的TouchEvent交给GestureDetector处理,本程序使用了一个ViewFlipper组件,ViewFlipper可使用动画控制多个组件之间的切换效果. 本实例程序通过GestureDetector来检测用户的手势动作,并根据手势动作来控制ViewFlipper包含的View组件的切换,从而实现翻页效果. activity_main.xml布局界面代码: <?xml version="1.0" encoding="

  • android ViewPager实现滑动翻页效果实例代码

    实现ViewPager的滑动翻页效果可以使用ViewPager的setPageTransformer方法,如下: import android.content.Context; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.View; public class ReadViewPager extends ViewPager { public ReadV

  • Android实现阅读APP平移翻页效果

    自己做的一个APP需要用到翻页阅读,网上看过立体翻页效果,不过bug太多了还不兼容.看了一下多看阅读翻页是采用平移翻页的,于是就仿写了一个平移翻页的控件.效果如下: 在翻页时页面右边缘绘制了阴影,效果还不错.要实现这种平移翻页控件并不难,只需要定义一个布局管理页面就可以了.具体实现上有以下难点: 1.循环翻页,页面的重复利用. 2.在翻页时过滤掉多点触碰. 3.采用setAdapter的方式设置页面布局和数据. 下面就来一一解决这几个难点.首先看循环翻页问题,怎么样能采用较少的页面实现这种翻页呢

  • android中图片翻页效果简单的实现方法

    复制代码 代码如下: public class PageWidget extends View {    private Bitmap foreImage;    private Bitmap bgImage;    private PointF touchPt;    private int screenWidth;    private int screenHeight;    private GradientDrawable shadowDrawableRL;    private Gra

随机推荐