Android自定义View——从零开始实现书籍翻页效果(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。
系列教程:Android开发之从零开始系列
源码:github.com/AnliaLee/BookPage,欢迎star

大家要是看到有错误的地方或者有啥好的建议,欢迎留言评论

前言:本篇是系列博客的第三篇,这次我们要研究 书籍翻页效果 。不知道大家平时有没用过iReader、掌阅这些小说软件,里面的翻页效果感觉十分的酷炫。有心想研究研究如何实现,于是网上找了找,发现这方面的教学资料非常少,所幸能找到何明桂大大Android 实现书籍翻页效果—-原理篇这样的入门博客(感谢大大 Orz),我们就以这篇博客为切入点从零实现我们自己的翻页效果。由于这次坑比较深,预计会写好几期,感兴趣的小伙伴可以点下关注以便及时收到更新提醒,谢谢大家的支持 ~

本篇只着重于思路和实现步骤,里面用到的一些知识原理不会非常细地拿来讲,如果有不清楚的api或方法可以在网上搜下相应的资料,肯定有大神讲得非常清楚的,我这就不献丑了。本着认真负责的精神我会把相关知识的博文链接也贴出来(其实就是懒不想写那么多哈哈),大家可以自行传送。为了照顾第一次阅读系列博客的小伙伴,本篇会出现一些在之前系列博客就讲过的内容,看过的童鞋自行跳过该段即可

国际惯例,先上效果图,本次主要实现了基本的上下翻页效果右侧最大翻页距离的限制

目录
  • 计算与绘制各个标识点
  • 连接各标识点绘制A、B、C区域
  • 测量及自适应View的宽高
  • 通过触摸控制各标识点位置
  • 限制右侧翻页的最大距离

计算与绘制各个标识点
相关博文链接

Android 实现书籍翻页效果—-原理篇
Android 自定义View (一)

在看这篇博客之前,希望大家能先了解一下书籍翻页的实现原理,博客链接我已经贴出来了。通过原理讲解我们知道,整个书籍翻页效果界面分成了三个区域,A为当前页区域,B为下一页区域,C为当前页背面,如图所示

书籍翻页效果的实现就是要以我们触摸屏幕位置的坐标为基础绘制出这三个区域,形成模拟翻页的特效。要绘制这三个区域,我们需要通过一组特定的点来完成,这些点的坐标需要通过两个已知的点(触摸点相对边缘角)计算得到,下图我将各个特定点的位置和计算公式贴出来,大家对照着原理一起理解(渣画工望体谅 ╮(╯▽╰)╭ ),其中b点是由aecj的交点,k点是由ahcj的交点

简单总结一下,a是触摸点,f是触摸点相对的边缘角,gaf的中点,abakdj直线曲线cdb是起点为c,控制点为e,终点为b二阶贝塞尔曲线曲线kij是起点为k,控制点为h,终点为j二阶贝塞尔曲线,区域ABC就由这些点和线划分开来。我们将这些点称为标识点,下一步就是模拟设定af点的位置,将这组标识点绘制到屏幕上来验证我们的计算公式是否正确,创建BookPageView

public class BookPageView extends View {
   
    private Paint pointPaint;//绘制各标识点的画笔
    private Paint bgPaint;//背景画笔

    private MyPoint a,f,g,e,h,c,j,b,k,d,i;

    private int defaultWidth;//默认宽度
    private int defaultHeight;//默认高度
    private int viewWidth;
    private int viewHeight;

    public BookPageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs){
        defaultWidth = 600;
        defaultHeight = 1000;

        viewWidth = defaultWidth;
        viewHeight = defaultHeight;

        a = new MyPoint(400,800);
        f = new MyPoint(viewWidth,viewHeight);
        g = new MyPoint();
        e = new MyPoint();
        h = new MyPoint();
        c = new MyPoint();
        j = new MyPoint();
        b = new MyPoint();
        k = new MyPoint();
        d = new MyPoint();
        i = new MyPoint();
        calcPointsXY(a,f);

        pointPaint = new Paint();
        pointPaint.setColor(Color.RED);
        pointPaint.setTextSize(25);

        bgPaint = new Paint();
        bgPaint.setColor(Color.GREEN);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //为了看清楚点与View的位置关系绘制一个背景
        canvas.drawRect(0,0,viewWidth,viewHeight,bgPaint);
        //绘制各标识点
        canvas.drawText("a",a.x,a.y,pointPaint);
        canvas.drawText("f",f.x,f.y,pointPaint);
        canvas.drawText("g",g.x,g.y,pointPaint);

        canvas.drawText("e",e.x,e.y,pointPaint);
        canvas.drawText("h",h.x,h.y,pointPaint);

        canvas.drawText("c",c.x,c.y,pointPaint);
        canvas.drawText("j",j.x,j.y,pointPaint);

        canvas.drawText("b",b.x,b.y,pointPaint);
        canvas.drawText("k",k.x,k.y,pointPaint);

        canvas.drawText("d",d.x,d.y,pointPaint);
        canvas.drawText("i",i.x,i.y,pointPaint);
    }

    /**
     * 计算各点坐标
     * @param a
     * @param f
     */
    private void calcPointsXY(MyPoint a, 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值