GithubHelp home page GithubHelp logo

fantasticporntaiqiang / ptqflipper Goto Github PK

View Code? Open in Web Editor NEW
50.0 2.0 15.0 58.33 MB

Jetpack Compose 仿真书籍翻页组件 3D Page Flip for Android Jetpack Compose - Page Curl

License: MIT License

Kotlin 96.17% CMake 0.20% C++ 3.63%
android compose kotlin

ptqflipper's Introduction

PTQBookPageView

Android JetPack Compose 仿真书籍翻页组件,支持自定义任何非动态内容。

[效果演示] DemoApk v1.1.0 提取码:ptq6

[项目仓库] Github

[组件使用] 传送门

[设计思路] 传送门

[源码解析]

(DemoApk 中的图片均使用 AI 生成的图片)


1 使用组件

1.1 引入

1、在项目的 root 的 build.gradle 中引入仓库。(高版本gradle是在settings.gradle里配)

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

2、在项目的 app 的 build.gradle 中添加依赖。

    dependencies {
        implementation 'com.github.FantasticPornTaiQiang:PTQFlipper:$latest_version'
    }

最新版本

1.2 基本使用

在@Composable 中使用组件。

    val state by rememberPTQBookPageViewState(pageCount = 100)

    PTQBookPageView(state = state) {
        contents { currentPage, refresh ->
            Box(modifier = Modifier.fillMaxSize().background(Color.White)) {
                //任何非动态的自定义内容
            }

            refresh()
        }
    }
  • 在 rememberPTQBookPageViewState 中设置总页数
  • 请务必在 contents 的最末尾调用 refresh 方法以保证 View 显示的内容正常
    • 例如需要网络请求图片,那么请在请求成功后手动refresh,把新内容同步到组件内
  • 在 contents 中利用回调参数 currentPage 设置当前页显示的内容
  • 在 contents 中,最外层是一个 fillMaxSize 的 Box,并需要使用 background 设置当前纸页正面的颜色
  • 在 contents 的 Box 中(即示例代码的注释处),可以自定义任何非动态的内容

注:不支持:

  • 不支持纸张(即背景色)带透明度
  • 不支持纸张设置圆角(即必须是矩形的)
  • 暂时不支持像LazyColumn这种内部状态会快速变化的View(除非你能监听到状态停止变化的时刻,然后手动调用refresh,总之就是要保证refresh能调用到)

2 定制

2.1 页数控制

组件提供了rememberPTQBookPageViewState方法进行页数相关的控制。

rememberPTQBookPageViewState(pageCount: Int = 1, currentPage: Int? = null)

  • pageCount 总页数,如果页面总数小于当前页数,则会引发异常

  • currentPage 当前页数,如果为 null 则页数由翻页器内部控制

控制页数方式有两种:

  • 不传入 currentPage,则页数作为组件内部状态,由翻页器内部自动控制

  • 传入 currentPage,则页数作为外部状态,需要在onTurnPageRequest方法中维护(详细介绍)。

示例如下

    var state by rememberPTQBookPageViewState(pageCount = 100, currentPage = 0)

    PTQBookPageView(state = state) {
        onTurnPageRequest { currentPage, isNextOrPrevious, success ->
            if (!success) {
                Toast.makeText(ctx, if (isNextOrPrevious) "已经是最后一页啦" else "已经是第一页啦", Toast.LENGTH_SHORT).show()
            } else {
                state = state.copy(currentPage = if (isNextOrPrevious) currentPage + 1 else currentPage - 1)
            }
        }

        contents { currentPage, refresh ->
            Box(modifier = Modifier.fillMaxSize().background(Color.White)) {
                //任何非动态的自定义内容
                Text(currentPage.toString(), modifier = Modifier.align(Alignment.Center))
            }

            refresh()
        }
    }

2.2 配置参数

组件提供了rememberPTQBookPageViewConfig方法进行相关的控制。

rememberPTQBookPageViewConfig(pageColor: Color = Color.White, disabled: Boolean = false)

  • pageColor 当前页背面的颜色(页面正面的颜色在 contents 的 Box 的 background modifier 中设置)(暂不支持页面透明度的设置,即alpha通道必须为ff)

  • disabled 整个组件是否禁用(若想单独禁用单击或拖动手势,请看高级定制

v1.1.0新增属性:

  • distortionInterval 图像扭曲的采样间隔,可以根据屏幕大小去作适配,此值越小,曲线越精密,但同样地,计算开销会越大,性能会下降

  • bezierEdgeDownSampling 边缘扭曲的采样间隔,可以根据屏幕大小去作适配,此值越大,曲线越精密,但同样地,计算开销会越大,性能会下降(变化不是线性的)

config 以参数的形式传入组件以生效,示例如下

    val config by rememberPTQBookPageViewConfig()

    PTQBookPageView(state = state, config = config) {
        ...
    }

2.3 大小和位置

组件支持以 modifier 的形式设置大小和位置,具体地

  • 支持以 padding modifier 方式设置组件位置和大小

  • 支持以 height modifier 和 width modifier 方式设置大小

  • 不支持offset 和 size modifier

示例如下

    PTQBookPageView(
        modifier = Modifier.padding(start = padding[0].dp, top = padding[1].dp, end = padding[2].dp, bottom = padding[3].dp),
        config = config,) {
        ...
    }
    PTQBookPageView(
        modifier = Modifier.width(100.dp).height(100.dp),
        config = config,) {
        ...
    }

2.4 翻页请求

PTQBookPageViewScope中注册onTurnPageRequest回调以响应手指的翻页请求。

onTurnPageRequest(block: (currentPage: Int, isNextOrPrevious: Boolean, success: Boolean) -> Unit)

当用户有想翻页的操作时,会触发这个回调。如果当前处于最后一页,仍想向右翻,则会翻页失败,但此回调仍然会调用,可以利用这个回调弹 Toast 显示没有下一页了。

  • currentPage 用户操作之后的页面索引,范围是 [0, pageCount)

  • isNextOrPrevious 用户想向前翻页还是向后翻页,true 表示 next

  • success 用户翻页是否成功,若处于最后一页还想向右翻则翻页失败,处于第一页向前翻同理

示例代码


3 高级定制

3.1 控制点击时的翻页行为

PTQBookPageViewScope中注册tapBehavior回调以自定义控制点击时的行为。

tapBehavior(block: (leftUp: Point, rightDown: Point, touchPoint: Point) -> Boolean?)

  • leftUP 组件左上角坐标

  • rightDown 组件右下角坐标

  • touchPoint 用户手指触摸坐标

  • 返回值 翻页行为,true=下一页,false=上一页,null=不响应

此回调中的 Point 均为相对于组件左上角的坐标点,且此回调会影响 UI 的呈现和onTurnPageRequest回调。

如果不注册此回调,则默认情况下:

  • 点击 x>1/2 处时翻下一页

  • 点击 x<1/2 处时翻上一页

示例代码

3.2 控制拖动时的起手响应

PTQBookPageViewScope中注册responseDragWhen回调以自定义控制拖动时的起手响应。

responseDragWhen(block: (rightDown: Point, startTouchPoint: Point, currentTouchPoint: Point) -> Boolean?)

  • rightDown 组件右下角坐标(左上角为 0)

  • startTouchPoint 用户起手坐标(开始动画前)

  • currentTouchPoint 当前触摸点坐标

  • 返回值 翻页行为,true=下一页(从右侧翻开),false=上一页(从左侧翻开),null=不响应

此回调决定了从起手开始到能够自由拖动之间的翻页行为,如果不注册此回调,默认情况下:

  • 从右往左滑则右起手(翻下一页)

  • 从左往右划则左起手(翻上一页)

示例代码

3.3 控制拖动松手时的翻页行为

PTQBookPageViewScope中注册dragBehavior回调以自定义控制拖动松手时的翻页行为。

dragBehavior(block: (
    rightDown: Point,
    initialTouchPoint: Point,
    lastTouchPoint: Point,
    isRightToLeftWhenStart: Boolean
    ) -> Pair<Boolean, Boolean?>
)
  • rightDown 组件右下角坐标(左上角为 0)

  • initialTouchPoint 用户初始触摸坐标(开始动画前)

  • lastTouchPoint 用户松手坐标(结束动画前)

  • isRightToLeftWhenStart 用户起手是从右向左还是从左向右(即 responseDragWhen 的结果)

  • 返回值 翻页行为

    • 第一个参数控制 UI 动画,true=从左侧退出,false=从右侧退出

    • 第二个参数控制翻页响应,true=下一页,false=上一页,null=不翻页

此回调中的 Point 均为相对于组件左上角的坐标点,且此回调会影响 UI 的呈现和onTurnPageRequest回调。

如果不注册此回调,则默认情况下:

  • 起手从右向左

    • 松手在 x>1/2 处则不翻页

    • 松手在 x<1/2 处则翻下一页

  • 起手从左向右

    • 松手在 x>1/2 处则翻上一页

    • 松手在 x<1/2 处则不翻页

示例代码


4 更新日志

v1.0.0

  • 初始版本,readme内的基本功能

v1.0.1

  • 修复跟随算法bug

v1.1.0

  • 配置项新增distortionInterval和bezierEdgeDownSampling
  • 性能优化
  • 移除了minSdk26的限制

ptqflipper's People

Contributors

fantasticporntaiqiang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ptqflipper's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.