QMUI Photo-向 Compose 出征的第一步

1,407 阅读4分钟

QMUI Photo 功能已经迁移到个人开启了仓库 emo 中,可以前往 github.com/cgspine/emo star 下。

缘起

Jetpack Compose 正式版已经出来一段时间了,在我强力的 push 下,读书团队已经在 app 里应用起来了,包括微信读书、微信听书、微信读书墨水屏,现网都已经跑起来了。

比起 View 体系,开发效率提升肯定是极大的,随着熟练度的提升,写起 UI 来行云流水。但目前在已有的工程添加 Compose 支持,对编译速度的影响还是蛮大的,而且 Layout Inspector 支持也不是很友好(View 体系其实也不用 Layout Inspector,而是用 Facebook 出品的 Flipper),所以现阶段也只是痛苦并快乐着。不过 kotlin 1.6.20 对编译速度提升很大,Compose 最新 alpha 也支持了,试了下,编译提升速度还是蛮不错的。

Compose 既然是未来,那么 QMUI 也要跟进跟进,所以 QMUI 也开了子 library,慢慢的进行着 compose 的组件开发,旧的 qmui 库就要惨遭抛弃了。 目前首个发布的就是 photo 库了,也是 QMUI 一直缺失的库。

QMUI Photo 目前包括图片查看器、图片选择器、以及一个简单的头像裁剪控件, 代码质量可能不是很好,毕竟 Compose 的最佳实践还没摸索得很好,组件也有个逐步完善的过程,有机会的话就慢慢迭代吧。 当然,最惨的是当前它还是一份”三无代码”(无注释、无日志、无文档),参照 qmui 库的经历,完善这些周边可能永远只是停留在口头,所以想要使用,还是主动阅读源码,顺便看看代码有没有 bug 吧。

基本使用

引入

// 如果使用 coil 作为图片加载框架
implementation("com.qmuiteam:photo-coil:1.1.1")

// 如果使用 glide 作为图片加载框架
implementation("com.qmuiteam:photo-glide:1.1.1")

// 其它图片加载, 参照上面两个库自定义实现 QMUIPhoto、QMUIPhotoProvider 等
implementation("com.qmuiteam:photo:1.1.1")

版本号为何是 1.1.1 呢?

这里规则是我自定义的,没文档就是找骂的点。因为 compose 依赖了 kotlin 的版本以及编译器扩展的版本,所以 photo 组件也存在这个问题,因为我决定,版本号的 major 与 mirror 跟随组件所依赖的 compose 的 major 与 mirror ,最后一位则是库的版本号, 一直叠加就行了,反正 qmui 也没怎么遵循过 major.mirror.patch 的规则。 所以 1.1.1 版本号标明这是使用于 compose 1.1.x 的库,是库的第一次 release。

九宫格缩略图使用

QMUIPhotoThumbnailWithViewer(
    activity = requireActivity(),
    images = listOf(
        QMUICoilPhotoProvider(uri,ratio),
        QMUICoilPhotoProvider(uri,ratio)
    )
)

基本上 follow 了微信朋友圈的适配规则,当然 config 参数的,使用者可以调整。

图片查看器

在 AndroidManifest 里引入

<!-- 如果需要自定义处理的话, 则覆写 QMUIPhotoViewerActivity -->
<activity
    android:name="com.qmuiteam.photo.activity.QMUIPhotoViewerActivity"
    android:screenOrientation="portrait"/>

如果使用 QMUIPhotoThumbnailWithViewer,则点击图片的转场动画是处理好了的,否则的话就要自己构造传参了

val intent = QMUIPhotoViewerActivity.intentOf(
    activity, 
    targetActivity, // 目标 activity 为 QMUIPhotoViewerActivity 或其子类,需要在 AndroidManifest 里注册
    list,  // 图片list
    index  // 打开的定位点
)
activity.startActivity(intent)
activity.overridePendingTransition(0, 0)

其 list 的 item 结构为 QMUIPhotoTransitionInfo, 其定义为

class QMUIPhotoTransitionInfo(
    val photoProvider: QMUIPhotoProvider, // 图片, 因图片加载框架而不同
    var offsetInWindow: Offset?, // 图片打开的转场的起始位置,相对于 window
    var size: IntSize?, // 图片打开的转场的起始大小
		var photo: Drawable?  // 缩略图,如果可以拿到就可以透传,避免再次读取,使得转场流畅
){...}

具体构造以参考 QMUIPhotoThumbnailWithViewer 的实现。

图片查看器是支持长图的,这就是 Compose 舒服的点,LazyColumn 加 BitmapRegion 轻松搞定,如果是 View 体系,要嵌套的 GesutureView 里面去,想想都麻烦。

图片选择器

在 AndroidManifest 里引入


<!-- 如果需要自定义处理的话, 则覆写 QMUIPhotoPickerActivity -->
<activity
    android:name="com.qmuiteam.photo.activity.QMUIPhotoPickerActivity"
    android:screenOrientation="portrait"/>

使用

private val pickLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
    if (it.resultCode == RESULT_OK) {
        val pickerResult = it.data?.getQMUIPhotoPickResult() ?: return@registerForActivityResult
        // TODO with result
    }
}

pickLauncher.launch(
    QMUIPhotoPickerActivity.intentOf(
        activity,
        QMUIPhotoPickerActivity::class.java, // 目标 activity 为 QMUIPhotoPickerActivity 或其子类,需要在 AndroidManifest 里注册
        QMUIMediaCoilPhotoProviderFactory::class.java // 这里用 coil 作为图片加载器
    )
)

图片选择器的交互基本上都是抄微信的,也不要另立新意去搞个新的设计了,反正搞来搞去,最终都是要对齐微信的。。。。

图片选择器的编辑功能还没完成,目前涂鸦、文字输入基本上渲染端完成了,裁剪这些还没搞完。为了快点接入到产品中看点效果,所以就先终端了,用配置项,先关了。

那么什么时候可以完成编辑功能呢?

等鸡吃完了米,狗舔完了面,火烧断了锁,大概就做完了。

就先聊这么多了,有兴趣的就读读源码,找找bug。反正除了学习 Compose, 你也不会接入 到项目中,所以也用不上这个库了。

最后,推荐下我的公众号,快来关注下:

picture.png