diff --git a/ohos/flutter-pag/.gitignore b/ohos/flutter-pag/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e6303d89fdb685adc2e42d9e0fa65545fe4ec549 --- /dev/null +++ b/ohos/flutter-pag/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ +.idea/ + +build/ diff --git a/ohos/flutter-pag/.metadata b/ohos/flutter-pag/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..3a59a794b364194264118ec4e3b8466dc81bfc8b --- /dev/null +++ b/ohos/flutter-pag/.metadata @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: + revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 + channel: stable + +project_type: plugin diff --git a/ohos/flutter-pag/CHANGELOG.md b/ohos/flutter-pag/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..4a051e9e7d44200604f921ba3fdad611407d1c50 --- /dev/null +++ b/ohos/flutter-pag/CHANGELOG.md @@ -0,0 +1,17 @@ +## 1.0.4 +* 增加展位图参数 + +## 1.0.3 +* 删除gradle无用引用 + +## 1.0.2 +* 修正Android repeatCount空异常 + +## 1.0.1 +* 修正命名规范的疏漏,podspec未修改 + +## 1.0.0 +* 封装PAG动画使用方式 +* 支持二进制、网络连接、资源文件等加载方式 +* 提供动画流程中的事件监听,与原生API一致 + diff --git a/ohos/flutter-pag/LICENSE b/ohos/flutter-pag/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..261eeb9e9f8b2b4b0d119366dda99c6fd7d35c64 --- /dev/null +++ b/ohos/flutter-pag/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/ohos/flutter-pag/README.md b/ohos/flutter-pag/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6d7394b5bfe7988a323b7d2eaca91cd04d9e0c0f --- /dev/null +++ b/ohos/flutter-pag/README.md @@ -0,0 +1,92 @@ +# 项目介绍 +为Flutter量身定制的PAG动画组件,采用外接纹理技术实现。 + +**注:如果遇到使用问题请在本仓库提 issue 与作者讨论,或直接提交 pr 参与共建。** + +[**PAG官方页面**](https://pag.art/) + +# 快速上手 +Flutter侧通过PAGView组件来播放动画 + +### 引用 +``` +dependencies: + pag: 1.0.0 +``` + +Android端混淆文件中配置,避免影响 +``` +-keep class org.libpag.**{*;} +``` + +### 使用本地资源 +``` +PAGView.asset( + "assets/example.pag", //flutter侧资源路径 + repeatCount: PagView.REPEAT_COUNT_LOOP, // 循环次数 + initProgress: 0.25, // 初始进度 + key: pagKey, // 利用key进行主动调用 + autoPlay: true, // 是否自动播放 + ) +``` +### 使用网络资源 +``` +PAGView.url( + "xxxx", //网络链接 + repeatCount: PagView.REPEAT_COUNT_LOOP, // 循环次数 + initProgress: 0.25, // 初始进度 + key: pagKey, // 利用key进行主动调用 + autoPlay: true, // 是否自动播放 + ) +``` +### 使用二进制数据 +``` +PAGView.bytes( + "xxxx", //网络链接 + repeatCount: PagView.REPEAT_COUNT_LOOP, // 循环次数 + initProgress: 0.25, // 初始进度 + key: pagKey, // 利用key进行主动调用 + autoPlay: true, // 是否自动播放 + ) +``` +### 可以在PAGView中加入回调参数 +以下回调与原生PAG监听对齐 +``` +PAGView.asset( + ... + onAnimationStart: (){ // 开始 + // do something + }, + onAnimationEnd: (){ // 结束 + // do something + }, + onAnimationRepeat: (){ // 重复 + // do something + }, + onAnimationCancel: (){ // 取消 + // do something + }, +``` + +### 通过key获取state进行主动调用 +``` + final GlobalKey pagKey = GlobalKey(); + + //传入key值 + PAGView.url(key:pagKey) + + //播放 + pagKey.currentState?.start(); + + //暂停 + pagKey.currentState?.pause(); + + //停止 + pagKey.currentState?.stop(); + + //设置进度 + pagKey.currentState?.setProgress(xxx); + + //获取坐标位置的图层名list + pagKey.currentState?.getLayersUnderPoint(x,y); +``` diff --git a/ohos/flutter-pag/analysis_options.yaml b/ohos/flutter-pag/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7814013c895a5ab88ab0bb58d8cfa716f9be5654 --- /dev/null +++ b/ohos/flutter-pag/analysis_options.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/flutter-pag/android/.gitignore b/ohos/flutter-pag/android/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c6cbe562a42726ab875d51cb513723b234787300 --- /dev/null +++ b/ohos/flutter-pag/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/ohos/flutter-pag/android/build.gradle b/ohos/flutter-pag/android/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..0962dcb3cd241d7bbafbb31b9d963bd65023c5d5 --- /dev/null +++ b/ohos/flutter-pag/android/build.gradle @@ -0,0 +1,39 @@ +group 'com.example.flutter_pag_plugin' +version '1.0' + +buildscript { + repositories { + google() + jcenter() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.20" + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 30 + + defaultConfig { + minSdkVersion 19 + } +} + + +dependencies { + implementation "com.tencent.tav:libpag:4.1.49" + implementation 'com.jakewharton:disklrucache:2.0.2' +} \ No newline at end of file diff --git a/ohos/flutter-pag/android/gradle.properties b/ohos/flutter-pag/android/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..94adc3a3f97aa8ae37ba567d080f94f95ee8f9b7 --- /dev/null +++ b/ohos/flutter-pag/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/ohos/flutter-pag/android/gradle/wrapper/gradle-wrapper.properties b/ohos/flutter-pag/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..3c9d0852bfa5299f103d97d8a1ab834afdaaa6bf --- /dev/null +++ b/ohos/flutter-pag/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/ohos/flutter-pag/android/settings.gradle b/ohos/flutter-pag/android/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..f1753f0bbceada1bc267e814ee12ee048fea689f --- /dev/null +++ b/ohos/flutter-pag/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'flutter_pag_plugin' diff --git a/ohos/flutter-pag/android/src/main/AndroidManifest.xml b/ohos/flutter-pag/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..f7432fb43cf83155143c5f25318bfb846c25c076 --- /dev/null +++ b/ohos/flutter-pag/android/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + diff --git a/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/DataLoadHelper.kt b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/DataLoadHelper.kt new file mode 100644 index 0000000000000000000000000000000000000000..78b13af19836c8f09a640bc0f425a84a59660d73 --- /dev/null +++ b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/DataLoadHelper.kt @@ -0,0 +1,225 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.flutter_pag_plugin + +import android.content.Context +import android.os.Environment +import android.util.Log +import android.util.LruCache +import com.example.flutter_pag_plugin.utils.EncodeUtil +import com.jakewharton.disklrucache.DiskLruCache +import java.io.* +import java.net.HttpURLConnection +import java.net.URL +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException + +//数据加载器 +object DataLoadHelper { + private var diskCache: DiskLruCache? = null + private val memoryCache by lazy { LruCache(Runtime.getRuntime().maxMemory().toInt() / 50) } + private const val TAG = "DataLoadHelper" + const val DEFAULT_DIS_SIZE = 30 * 1024 * 1024L; + + // 下载来源:flutter插件、其他 + const val FROM_PLUGIN = 0 + const val FROM_OTHER = 1 + + private val loadListeners = mutableListOf() + + //初始化pag动画 + fun loadPag(src: String, addPag: (ByteArray?) -> Unit, from: Int = FROM_OTHER) { + val time = System.currentTimeMillis(); + val bytes = memoryCache.get(hashKeyForDisk(src)) + + loadListeners.forEach { + it.loadStart(src, from) + } + + if (bytes != null) { + addPag(bytes) + loadListeners.forEach { + it.loadComplete(src, bytes, System.currentTimeMillis() - time, "", from) + } + } else { + Thread { + loadPagByDisk(src) { byteArray, errorMsg -> + addPag.invoke(byteArray) + loadListeners.forEach { + it.loadComplete(src, byteArray, System.currentTimeMillis() - time, errorMsg, from) + } + } + }.start() + } + } + + fun initDiskCache(context: Context, size: Long = DEFAULT_DIS_SIZE) { + if (diskCache != null) { + Log.w(TAG, "diskCache do not need init again!") + return + } + + val cacheDir = getDiskCacheDir(context, "pag") + if (!cacheDir.exists()) { + cacheDir.mkdirs() + } + try { + diskCache = diskCache ?: DiskLruCache.open( + cacheDir, + context.packageManager.getPackageInfo(context.packageName, 0).versionCode, + 1, size + ) + } catch (e: IOException) { + Log.e(TAG, "initDiskCache error: $e") + } + } + + + //获取硬盘缓存路径 + private fun getDiskCacheDir(context: Context, uniqueName: String): File { + val cachePath: String = if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState() + || !Environment.isExternalStorageRemovable() + ) { + context.externalCacheDir?.path + } else { + context.cacheDir.path + } ?: "" + return File(cachePath + File.separator.toString() + uniqueName) + } + + + //硬盘或者网络获取, + @Synchronized + private fun loadPagByDisk(src: String, addPag: (ByteArray?, String) -> Unit) { + //从硬盘缓存中获取 + + var errorMsg = "" + val key = hashKeyForDisk(src) + var snapShot: DiskLruCache.Snapshot? = null + try { + snapShot = diskCache?.get(key) + if (snapShot == null) { + Log.d(TAG, "loadPag load from network") + //没有,进行网络操作 + val editor = diskCache?.edit(key) + if (editor != null) { + val outputStream = editor.newOutputStream(0) + if (downloadUrlToStream(src, outputStream)) { + editor.commit() + } else { + editor.abort() + } + } + //存入硬盘后再次读取 + diskCache?.flush() + snapShot = diskCache?.get(key) + } + } catch (e: IOException) { + Log.e(TAG, "loadPag load from network erro: $e") + errorMsg = "loadPag load from network error: $e" + } + + //进行bytes读取 + var bytes: ByteArray? = null + if (snapShot != null) { + Log.d(TAG, "loadPag load from snapShot") + try { + val inputStream = snapShot.getInputStream(0) + val outputStrem = ByteArrayOutputStream() + inputStream.use { ins -> + outputStrem.use { bos -> + val buffer = ByteArray(1024) + var len: Int + + while (ins.read(buffer).also { len = it } != -1) { + bos.write(buffer, 0, len) + } + bytes = bos.toByteArray() + } + } + } catch (e: IOException) { + e.printStackTrace() + Log.e(TAG, "loadPag load from snapShot erro: $e") + errorMsg = "loadPag load from network error: $e" + } + } + + Log.d(TAG, "loadPag bytes size: ${bytes?.size}") + //存储进内存缓存 + if (bytes != null && bytes!!.isNotEmpty() && memoryCache.get(key) == null) { + memoryCache.put(key, bytes) + } + addPag(bytes, errorMsg) + } + + + //下载 + private fun downloadUrlToStream(urlString: String, outputStream: OutputStream): Boolean { + var urlConnection: HttpURLConnection? = null + var outStream: BufferedOutputStream? = null + var inStream: BufferedInputStream? = null + try { + val url = URL(urlString) + urlConnection = url.openConnection() as HttpURLConnection + inStream = BufferedInputStream(urlConnection.inputStream, 8 * 1024) + outStream = BufferedOutputStream(outputStream, 8 * 1024) + var b: Int + while (inStream.read().also { b = it } != -1) { + outStream.write(b) + } + return true + } catch (e: IOException) { + e.printStackTrace() + } finally { + urlConnection?.disconnect() + try { + outStream?.close() + inStream?.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + return false + } + + //使用MD5算法对传入的key进行加密并返回 + private fun hashKeyForDisk(key: String): String? { + return try { + val mDigest: MessageDigest = MessageDigest.getInstance("MD5") + mDigest.update(key.toByteArray()) + EncodeUtil.bytesToHexString(mDigest.digest()) + } catch (e: NoSuchAlgorithmException) { + key.hashCode().toString() + } + } + + fun addLoadListener(loadListener: ILoadListener) { + loadListeners.add(loadListener) + } + + + fun removeLoadListener(loadListener: ILoadListener) { + loadListeners.remove(loadListener) + } +} + +// 用于监听PAG加载情况 +interface ILoadListener { + + fun loadStart(url: String, from: Int) + + fun loadComplete(url: String, result: ByteArray?/*result为空则失败*/, useTime: Long, errorMsg: String, from: Int) +} \ No newline at end of file diff --git a/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/FlutterPagPlayer.java b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/FlutterPagPlayer.java new file mode 100644 index 0000000000000000000000000000000000000000..3e78bfaab640f99c6042f1f0f87a302a3d44365e --- /dev/null +++ b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/FlutterPagPlayer.java @@ -0,0 +1,164 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.flutter_pag_plugin; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.view.animation.LinearInterpolator; + +import org.libpag.PAGFile; +import org.libpag.PAGPlayer; +import org.libpag.PAGView; + +import java.util.ArrayList; +import java.util.HashMap; + +import io.flutter.plugin.common.MethodChannel; + + +public class FlutterPagPlayer extends PAGPlayer { + + private final ValueAnimator animator = ValueAnimator.ofFloat(0.0F, 1.0F); + private boolean isRelease; + private long currentPlayTime = 0L; + private double progress = 0; + private double initProgress = 0; + private ReleaseListener releaseListener; + + private MethodChannel channel; + private long textureId; + + public void init(PAGFile file, int repeatCount, double initProgress, MethodChannel channel, long textureId) { + setComposition(file); + this.channel = channel; + this.textureId = textureId; + progress = initProgress; + this.initProgress = initProgress; + initAnimator(repeatCount); + } + + private void initAnimator(int repeatCount) { + animator.setDuration(duration() / 1000L); + animator.setInterpolator(new LinearInterpolator()); + animator.addUpdateListener(animatorUpdateListener); + animator.addListener(animatorListenerAdapter); + if (repeatCount < 0) { + repeatCount = 0; + } + animator.setRepeatCount(repeatCount - 1); + setProgressValue(initProgress); + } + + public void setProgressValue(double value) { + this.progress = Math.max(0.0D, Math.min(value, 1.0D)); + this.currentPlayTime = (long) (progress * (double) this.animator.getDuration()); + this.animator.setCurrentPlayTime(currentPlayTime); + setProgress(progress); + flush(); + } + + public void start() { + animator.start(); + } + + public void stop() { + pause(); + setProgressValue(initProgress); + } + + public void pause() { + animator.pause(); + } + + @Override + public void release() { + super.release(); + animator.removeUpdateListener(animatorUpdateListener); + animator.removeListener(animatorListenerAdapter); + if (releaseListener != null) { + releaseListener.onRelease(); + } + isRelease = true; + } + + @Override + public boolean flush() { + if (isRelease) { + return false; + } + return super.flush(); + } + + // 更新PAG渲染 + private final ValueAnimator.AnimatorUpdateListener animatorUpdateListener = new ValueAnimator.AnimatorUpdateListener() { + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + progress = (double) (Float) animation.getAnimatedValue(); + currentPlayTime = (long) (progress * (double) animator.getDuration()); + setProgress(progress); + flush(); + } + }; + + public void setReleaseListener(ReleaseListener releaseListener) { + this.releaseListener = releaseListener; + } + + public interface ReleaseListener { + void onRelease(); + } + + // 动画状态监听 + private final AnimatorListenerAdapter animatorListenerAdapter = new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animator) { + super.onAnimationStart(animator); + notifyEvent(FlutterPagPlugin._eventStart); + } + + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + // Align with iOS platform, avoid triggering this method when stopping + int repeatCount = ((ValueAnimator) animation).getRepeatCount(); + if (repeatCount >= 0 && (animation.getDuration() > 0) && + (currentPlayTime / animation.getDuration() > repeatCount)) { + notifyEvent(FlutterPagPlugin._eventEnd); + } + } + + @Override + public void onAnimationCancel(Animator animator) { + super.onAnimationCancel(animator); + notifyEvent(FlutterPagPlugin._eventCancel); + } + + @Override + public void onAnimationRepeat(Animator animator) { + super.onAnimationRepeat(animator); + notifyEvent(FlutterPagPlugin._eventRepeat); + } + }; + + void notifyEvent(String event) { + final HashMap arguments = new HashMap<>(); + arguments.put(FlutterPagPlugin._argumentTextureId, textureId); + arguments.put(FlutterPagPlugin._argumentEvent, event); + channel.invokeMethod(FlutterPagPlugin._playCallback, arguments); + } +} diff --git a/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/FlutterPagPlugin.java b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/FlutterPagPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..35c70961bd676d7e3c4e7516adb523779fc89f44 --- /dev/null +++ b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/FlutterPagPlugin.java @@ -0,0 +1,360 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.example.flutter_pag_plugin; + +import android.content.Context; +import android.graphics.SurfaceTexture; +import android.os.Handler; +import android.os.Looper; +import android.view.Surface; + +import androidx.annotation.NonNull; + +import org.libpag.PAGFile; +import org.libpag.PAGLayer; +import org.libpag.PAGSurface; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry; +import io.flutter.view.FlutterNativeView; +import io.flutter.view.TextureRegistry; +import kotlin.Unit; +import kotlin.jvm.functions.Function1; + +/** + * FlutterPagPlugin + */ +public class FlutterPagPlugin implements FlutterPlugin, MethodCallHandler { + /// The MethodChannel that will the communication between Flutter and native Android + /// + /// This local reference serves to register the plugin with the Flutter Engine and unregister it + /// when the Flutter Engine is detached from the Activity + private MethodChannel channel; + TextureRegistry textureRegistry; + Context context; + io.flutter.plugin.common.PluginRegistry.Registrar registrar; + FlutterPlugin.FlutterAssets flutterAssets; + private Handler handler = new Handler(Looper.getMainLooper()); + + // 多引擎使用是plugin的集合,请留意该场景下需手动释放,否则存在内存泄漏的问题 + public static List pluginList = new ArrayList(); + + public HashMap layerMap = new HashMap(); + public HashMap entryMap = new HashMap(); + + // 原生接口 + final static String _nativeInit = "initPag"; + final static String _nativeRelease = "release"; + final static String _nativeStart = "start"; + final static String _nativeStop = "stop"; + final static String _nativePause = "pause"; + final static String _nativeSetProgress = "setProgress"; + final static String _nativeGetPointLayer = "getLayersUnderPoint"; + + // 参数 + final static String _argumentTextureId = "textureId"; + final static String _argumentAssetName = "assetName"; + final static String _argumentPackage = "package"; + final static String _argumentUrl = "url"; + final static String _argumentBytes = "bytesData"; + final static String _argumentRepeatCount = "repeatCount"; + final static String _argumentInitProgress = "initProgress"; + final static String _argumentAutoPlay = "autoPlay"; + final static String _argumentWidth = "width"; + final static String _argumentHeight = "height"; + final static String _argumentPointX = "x"; + final static String _argumentPointY = "y"; + final static String _argumentProgress = "progress"; + final static String _argumentEvent = "PAGEvent"; + + // 回调 + final static String _playCallback = "PAGCallback"; + final static String _eventStart = "onAnimationStart"; + final static String _eventEnd = "onAnimationEnd"; + final static String _eventCancel = "onAnimationCancel"; + final static String _eventRepeat = "onAnimationRepeat"; + final static String _eventUpdate = "onAnimationUpdate"; + + + public FlutterPagPlugin() { + } + + public FlutterPagPlugin(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { + pluginList.add(this); + this.registrar = registrar; + textureRegistry = registrar.textures(); + context = registrar.context(); + DataLoadHelper.INSTANCE.initDiskCache(context, DataLoadHelper.INSTANCE.DEFAULT_DIS_SIZE); + } + + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + if (!pluginList.contains(this)) { + pluginList.add(this); + } + flutterAssets = binding.getFlutterAssets(); + channel = new MethodChannel(binding.getBinaryMessenger(), "flutter_pag_plugin"); + channel.setMethodCallHandler(this); + context = binding.getApplicationContext(); + textureRegistry = binding.getTextureRegistry(); + DataLoadHelper.INSTANCE.initDiskCache(context, DataLoadHelper.INSTANCE.DEFAULT_DIS_SIZE); + } + + public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { + final FlutterPagPlugin plugin = new FlutterPagPlugin(registrar); + registrar.addViewDestroyListener(new PluginRegistry.ViewDestroyListener() { + @Override + public boolean onViewDestroy(FlutterNativeView flutterNativeView) { + plugin.onDestroy(); + pluginList.remove(this); + return false; // We are not interested in assuming ownership of the NativeView. + } + }); + } + + @Override + public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { + switch (call.method) { + case _nativeInit: + initPag(call, result); + break; + case _nativeStart: + start(call); + result.success(""); + break; + case _nativeStop: + stop(call); + result.success(""); + break; + case _nativePause: + pause(call); + result.success(""); + break; + case _nativeSetProgress: + setProgress(call); + result.success(""); + break; + case _nativeRelease: + release(call); + result.success(""); + break; + case _nativeGetPointLayer: + result.success(getLayersUnderPoint(call)); + break; + default: + result.notImplemented(); + break; + } + } + + private void initPag(final MethodCall call, final Result result) { + String assetName = call.argument(_argumentAssetName); + byte[] bytes = call.argument(_argumentBytes); + String url = call.argument(_argumentUrl); + String flutterPackage = call.argument(_argumentPackage); + + if (bytes != null) { + initPagPlayerAndCallback(PAGFile.Load(bytes), call, result); + } else if (assetName != null) { + String assetKey = ""; + + if (registrar != null) { + if (flutterPackage == null || flutterPackage.isEmpty()) { + assetKey = registrar.lookupKeyForAsset(assetName); + } else { + assetKey = registrar.lookupKeyForAsset(assetName, flutterPackage); + } + } else if (flutterAssets != null) { + if (flutterPackage == null || flutterPackage.isEmpty()) { + assetKey = flutterAssets.getAssetFilePathByName(assetName); + } else { + assetKey = flutterAssets.getAssetFilePathByName(assetName, flutterPackage); + } + } + + if (assetKey == null) { + result.error("-1100", "asset资源加载错误", null); + return; + } + + PAGFile composition = PAGFile.Load(context.getAssets(), assetKey); + initPagPlayerAndCallback(composition, call, result); + } else if (url != null) { + DataLoadHelper.INSTANCE.loadPag(url, new Function1() { + @Override + public Unit invoke(final byte[] bytes) { + handler.post(new Runnable() { + @Override + public void run() { + if (bytes == null) { + result.error("-1100", "url资源加载错误", null); + return; + } + + initPagPlayerAndCallback(PAGFile.Load(bytes), call, result); + } + }); + + return null; + } + }, DataLoadHelper.FROM_PLUGIN); + } else { + result.error("-1100", "未添加资源", null); + } + } + + private void initPagPlayerAndCallback(PAGFile composition, MethodCall call, final Result result) { + if (composition == null) { + result.error("-1100", "load composition is null! ", null); + return; + } + + final int repeatCount = call.argument(_argumentRepeatCount); + final double initProgress = call.argument(_argumentInitProgress); + final boolean autoPlay = call.argument(_argumentAutoPlay); + + final FlutterPagPlayer pagPlayer = new FlutterPagPlayer(); + final TextureRegistry.SurfaceTextureEntry entry = textureRegistry.createSurfaceTexture(); + entryMap.put(String.valueOf(entry.id()), entry); + + pagPlayer.init(composition, repeatCount, initProgress, channel, entry.id()); + SurfaceTexture surfaceTexture = entry.surfaceTexture(); + surfaceTexture.setDefaultBufferSize(composition.width(), composition.height()); + + final Surface surface = new Surface(surfaceTexture); + final PAGSurface pagSurface = PAGSurface.FromSurface(surface); + pagPlayer.setSurface(pagSurface); + pagPlayer.setReleaseListener(new FlutterPagPlayer.ReleaseListener() { + @Override + public void onRelease() { + entry.release(); + surface.release(); + pagSurface.release(); + } + }); + + layerMap.put(String.valueOf(entry.id()), pagPlayer); + final HashMap callback = new HashMap(); + callback.put(_argumentTextureId, entry.id()); + callback.put(_argumentWidth, (double) composition.width()); + callback.put(_argumentHeight, (double) composition.height()); + handler.post(new Runnable() { + @Override + public void run() { + pagPlayer.flush(); + if (autoPlay) { + pagPlayer.start(); + } + result.success(callback); + } + }); + } + + void start(MethodCall call) { + FlutterPagPlayer flutterPagPlayer = getFlutterPagPlayer(call); + if (flutterPagPlayer != null) { + flutterPagPlayer.start(); + } + } + + void stop(MethodCall call) { + FlutterPagPlayer flutterPagPlayer = getFlutterPagPlayer(call); + if (flutterPagPlayer != null) { + flutterPagPlayer.stop(); + } + } + + void pause(MethodCall call) { + FlutterPagPlayer flutterPagPlayer = getFlutterPagPlayer(call); + if (flutterPagPlayer != null) { + flutterPagPlayer.pause(); + } + } + + void setProgress(MethodCall call) { + double progress = call.argument(_argumentProgress); + FlutterPagPlayer flutterPagPlayer = getFlutterPagPlayer(call); + if (flutterPagPlayer != null) { + flutterPagPlayer.setProgressValue(progress); + } + } + + void release(MethodCall call) { + FlutterPagPlayer flutterPagPlayer = layerMap.remove(getTextureId(call)); + if (flutterPagPlayer != null) { + flutterPagPlayer.stop(); + flutterPagPlayer.release(); + } + + TextureRegistry.SurfaceTextureEntry entry = entryMap.remove(getTextureId(call)); + if (entry != null) { + entry.release(); + } + } + + List getLayersUnderPoint(MethodCall call) { + FlutterPagPlayer flutterPagPlayer = getFlutterPagPlayer(call); + + List layerNames = new ArrayList(); + PAGLayer[] layers = null; + if (flutterPagPlayer != null) { + layers = flutterPagPlayer.getLayersUnderPoint( + ((Double) call.argument(_argumentPointX)).floatValue(), ((Double) call.argument(_argumentPointY)).floatValue()); + } + + if (layers != null) { + for (PAGLayer layer : layers) { + layerNames.add(layer.layerName()); + } + } + + return layerNames; + } + + FlutterPagPlayer getFlutterPagPlayer(MethodCall call) { + return layerMap.get(getTextureId(call)); + } + + String getTextureId(MethodCall call) { + return "" + call.argument(_argumentTextureId); + } + + //插件销毁 + public void onDestroy() { + for (FlutterPagPlayer pagPlayer : layerMap.values()) { + pagPlayer.release(); + } + for (TextureRegistry.SurfaceTextureEntry entry : entryMap.values()) { + entry.release(); + } + layerMap.clear(); + entryMap.clear(); + channel.setMethodCallHandler(null); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + } +} diff --git a/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/utils/EncodeUtil.java b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/utils/EncodeUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..ded90186fd801eb49011aeb75c3fc328069162a7 --- /dev/null +++ b/ohos/flutter-pag/android/src/main/java/com/example/flutter_pag_plugin/utils/EncodeUtil.java @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.example.flutter_pag_plugin.utils; + + +/** + * String 相关操作工具类 + * Created by Victorluo on 2016/8/11. + */ +public class EncodeUtil { + + public static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(""); + if (src == null || src.length <= 0) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + +} diff --git a/ohos/flutter-pag/example/.gitignore b/ohos/flutter-pag/example/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0fa6b675c0a52be9242fc68269eefce46828ad43 --- /dev/null +++ b/ohos/flutter-pag/example/.gitignore @@ -0,0 +1,46 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/flutter-pag/example/.metadata b/ohos/flutter-pag/example/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..e893a8cba8da83501a6c49e27ddccea9a26d409d --- /dev/null +++ b/ohos/flutter-pag/example/.metadata @@ -0,0 +1,24 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: f4abaa0735eba4dfd8f33f73363911d63931fe03 + channel: stable + +project_type: app diff --git a/ohos/flutter-pag/example/README.md b/ohos/flutter-pag/example/README.md new file mode 100644 index 0000000000000000000000000000000000000000..fa019c4c9fabd15c0e6b3be2cc90fbcf871ab648 --- /dev/null +++ b/ohos/flutter-pag/example/README.md @@ -0,0 +1,14 @@ +# flutter_pag_plugin_example + +Demonstrates how to utilize the flutter_pag_plugin effectively. + +## Getting Started + +对于初学者,我们提供了一些Flutter项目启动资源: + +- [实验:编写你的第一个Flutter应用](https://flutter.dev/docs/get-started/codelab) +- [食谱:实用的Flutter示例](https://flutter.dev/docs/cookbook) + +要开始使用Flutter,可以查阅我们的 +[在线文档](https://flutter.dev/docs),其中提供了教程, +示例,移动开发指导,以及完整的API参考。 diff --git a/ohos/flutter-pag/example/analysis_options.yaml b/ohos/flutter-pag/example/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..61b6c4de17c96863d24279f06b85e01b6ebbdb34 --- /dev/null +++ b/ohos/flutter-pag/example/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/flutter-pag/example/android/.gitignore b/ohos/flutter-pag/example/android/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0a741cb43d66c6790a2a913fa24c8878fb1ab7b5 --- /dev/null +++ b/ohos/flutter-pag/example/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/ohos/flutter-pag/example/android/app/build.gradle b/ohos/flutter-pag/example/android/app/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..7bfc2f2cd543d97cc1bcf04a506685b72a605a85 --- /dev/null +++ b/ohos/flutter-pag/example/android/app/build.gradle @@ -0,0 +1,50 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 31 + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_pag_plugin_example" + minSdkVersion 19 + targetSdkVersion 31 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} diff --git a/ohos/flutter-pag/example/android/app/src/debug/AndroidManifest.xml b/ohos/flutter-pag/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..7b73aac1172789e3687b63ac9b3780461caeb6ca --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + diff --git a/ohos/flutter-pag/example/android/app/src/main/AndroidManifest.xml b/ohos/flutter-pag/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..6966119dd935caed8ac9c39b3c8d2fa0d21af690 --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + + + + + + + + + diff --git a/ohos/flutter-pag/example/android/app/src/main/java/com/example/flutter_pag_plugin_example/MainActivity.java b/ohos/flutter-pag/example/android/app/src/main/java/com/example/flutter_pag_plugin_example/MainActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..e91fec1a5980c21a2585ba673bd0e7f4aeb3b3ac --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/main/java/com/example/flutter_pag_plugin_example/MainActivity.java @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.example.flutter_pag_plugin_example; + +import io.flutter.embedding.android.FlutterActivity; + +public class MainActivity extends FlutterActivity { +} diff --git a/ohos/flutter-pag/example/android/app/src/main/res/drawable-v21/launch_background.xml b/ohos/flutter-pag/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000000000000000000000000000000000000..a4353423f588885080027877db1643422b19846a --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + diff --git a/ohos/flutter-pag/example/android/app/src/main/res/drawable/launch_background.xml b/ohos/flutter-pag/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000000000000000000000000000000000000..e37f926c92bab5117a41345f74e629d8cef00fd6 --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + diff --git a/ohos/flutter-pag/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 Binary files /dev/null and b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/ohos/flutter-pag/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be Binary files /dev/null and b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..09d4391482be68e9e4a07fab769b5de337d16eb1 Binary files /dev/null and b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c Binary files /dev/null and b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 Binary files /dev/null and b/ohos/flutter-pag/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/ohos/flutter-pag/example/android/app/src/main/res/values-night/styles.xml b/ohos/flutter-pag/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000000000000000000000000000000000000..434af3629c3665eaa0566780de8578f1fde06843 --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + diff --git a/ohos/flutter-pag/example/android/app/src/main/res/values/styles.xml b/ohos/flutter-pag/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000000000000000000000000000000000000..10268913d525df6288ea1d57881d677730cf4193 --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + diff --git a/ohos/flutter-pag/example/android/app/src/profile/AndroidManifest.xml b/ohos/flutter-pag/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..7b73aac1172789e3687b63ac9b3780461caeb6ca --- /dev/null +++ b/ohos/flutter-pag/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + diff --git a/ohos/flutter-pag/example/android/build.gradle b/ohos/flutter-pag/example/android/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..7fe1f1868e8f89f406c0707ec7d46393ea1fb850 --- /dev/null +++ b/ohos/flutter-pag/example/android/build.gradle @@ -0,0 +1,27 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.1.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/ohos/flutter-pag/example/android/gradle.properties b/ohos/flutter-pag/example/android/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..94adc3a3f97aa8ae37ba567d080f94f95ee8f9b7 --- /dev/null +++ b/ohos/flutter-pag/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/ohos/flutter-pag/example/android/gradle/wrapper/gradle-wrapper.properties b/ohos/flutter-pag/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..bc6a58afdda22a443c752eaae3d60c2480511a9f --- /dev/null +++ b/ohos/flutter-pag/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/ohos/flutter-pag/example/android/settings.gradle b/ohos/flutter-pag/example/android/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..44e62bcf06ae649ea809590f8a861059886502e8 --- /dev/null +++ b/ohos/flutter-pag/example/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/ohos/flutter-pag/example/ios/.gitignore b/ohos/flutter-pag/example/ios/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..151026b91bc928ad167b6168bf5aabdb4be8ce90 --- /dev/null +++ b/ohos/flutter-pag/example/ios/.gitignore @@ -0,0 +1,33 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ohos/flutter-pag/example/ios/Flutter/AppFrameworkInfo.plist b/ohos/flutter-pag/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000000000000000000000000000000000000..d93008f094c5beeb72a0d938474cfde94d206738 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 9.0 + + diff --git a/ohos/flutter-pag/example/ios/Flutter/Debug.xcconfig b/ohos/flutter-pag/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..d5eb912e62d790d1df0355683a674459face8ed7 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/ohos/flutter-pag/example/ios/Flutter/Release.xcconfig b/ohos/flutter-pag/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..931d28f36860b9346da727aa3313f98844e66db7 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/ohos/flutter-pag/example/ios/Podfile b/ohos/flutter-pag/example/ios/Podfile new file mode 100644 index 0000000000000000000000000000000000000000..eafa889f716134e2adc5529625ef6e83c572eec9 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Podfile @@ -0,0 +1,52 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + pod 'libpag', '4.2.11' + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.pbxproj b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..f04351e8e5a8dbe1a6961378bf4c55c63f0d7e41 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,568 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + F508DC21C3FF0565306F1BA4 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4669C38C14B0AB5FAC6611C9 /* libPods-Runner.a */; }; + FB2F7A2327DB72F100A90D02 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F7A2227DB72F100A90D02 /* libc++.tbd */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3DBDC017D50B82427AE7948E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 4669C38C14B0AB5FAC6611C9 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E8A1C220649E233F26806054 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + F16F7F92BD31D7A2AED62065 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + FB2F7A2227DB72F100A90D02 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FB2F7A2327DB72F100A90D02 /* libc++.tbd in Frameworks */, + F508DC21C3FF0565306F1BA4 /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 01346A5F62851C62F25D73AE /* Frameworks */ = { + isa = PBXGroup; + children = ( + FB2F7A2227DB72F100A90D02 /* libc++.tbd */, + 4669C38C14B0AB5FAC6611C9 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + 015AA143B0162E4AB723C99A /* Pods */ = { + isa = PBXGroup; + children = ( + F16F7F92BD31D7A2AED62065 /* Pods-Runner.debug.xcconfig */, + E8A1C220649E233F26806054 /* Pods-Runner.release.xcconfig */, + 3DBDC017D50B82427AE7948E /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 015AA143B0162E4AB723C99A /* Pods */, + 01346A5F62851C62F25D73AE /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 5F524B1F47B60F9D6A784898 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + AE30BE6D72416E328EEC3D7A /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 5F524B1F47B60F9D6A784898 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + AE30BE6D72416E328EEC3D7A /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 93R838NHT9; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterPagPluginExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 93R838NHT9; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterPagPluginExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 93R838NHT9; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterPagPluginExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..5e4bb6dec1a499bc10a7d31cc8f38500f5a67611 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + diff --git a/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..413d15623223cdd39a19a316de2ea4a9663d4995 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000000000000000000000000000000000..b689ae57d08361b0774433dbd8ab8a8a7a6aff32 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + PreviewsEnabled + + + diff --git a/ohos/flutter-pag/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ohos/flutter-pag/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000000000000000000000000000000000..ba5d9616006892bafd6e3c54743dcee9cec8c359 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ohos/flutter-pag/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/ohos/flutter-pag/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..9d1a5f09b6978bdd4b43cc4323da06289e8b45cf --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + diff --git a/ohos/flutter-pag/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ohos/flutter-pag/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..413d15623223cdd39a19a316de2ea4a9663d4995 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ohos/flutter-pag/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ohos/flutter-pag/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000000000000000000000000000000000..0dd97beea522d7f55f02c8d52fe579c0b5f0fc36 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + PreviewsEnabled + + + diff --git a/ohos/flutter-pag/example/ios/Runner/AppDelegate.h b/ohos/flutter-pag/example/ios/Runner/AppDelegate.h new file mode 100644 index 0000000000000000000000000000000000000000..185dbcaeefd369516e2bb2c76e96522aaeb5e9ca --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/AppDelegate.h @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef AppDelegate_h +#define AppDelegate_h + +// AppDelegate.h +// AppDelegate +// +// Created by jenmalli on 2022/3/16. +// Copyright © 2022 Tencent. All rights reserved. + +#import +// 此处代码符合行业标准,无需修改 +#import + +@interface AppDelegate : FlutterAppDelegate + +@end + +#endif /* AppDelegate_h */ diff --git a/ohos/flutter-pag/example/ios/Runner/AppDelegate.m b/ohos/flutter-pag/example/ios/Runner/AppDelegate.m new file mode 100644 index 0000000000000000000000000000000000000000..1b4362e841d60d27efb1154ab38914a5577e238c --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/AppDelegate.m @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#import "AppDelegate.h" +#import "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..d36b1fab2d9dea668a4f83df94d525897d9e68dd --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9ada4725e9b0ddb1deab583e5b5102493aa332 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccbfd967d9697cd4b83225558af2911e9571c9b Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..4cde12118dda48d71e01fcb589a74d069c5d7cb5 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..dcdc2306c28505ebc0b6c3a359c4d252bf626b9f Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccbfd967d9697cd4b83225558af2911e9571c9b Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6a84f41e14e27f4b11f16f9ee39279ac98f8d5ac Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0e1f58536026aebc4f1f70e481f6993c9ff088d Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..0bedcf2fd46788ae3a01a423467513ff59b5c120 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 Binary files /dev/null and b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000000000000000000000000000000000000..89c2725b70f1882be97f5214fafe22d27a0ec01e --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ohos/flutter-pag/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ohos/flutter-pag/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..04fd99284e491089e3ba5bf03ef5d9a50304c8da --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ohos/flutter-pag/example/ios/Runner/Base.lproj/Main.storyboard b/ohos/flutter-pag/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..7b24812ced99d49b7e5958f9f5100c202f981634 --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ohos/flutter-pag/example/ios/Runner/Info.plist b/ohos/flutter-pag/example/ios/Runner/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..0dc9ce35a70dbc73769761ea74b0445eb24e3fca --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/Info.plist @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_pag_plugin_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + + diff --git a/ohos/flutter-pag/example/ios/Runner/main.m b/ohos/flutter-pag/example/ios/Runner/main.m new file mode 100644 index 0000000000000000000000000000000000000000..25e2403a1b9730714bfe791756e483eeb402a1fc --- /dev/null +++ b/ohos/flutter-pag/example/ios/Runner/main.m @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/ohos/flutter-pag/example/lib/main.dart b/ohos/flutter-pag/example/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..19c39b449da7e58a62c04f2f31984fecf52dcf7b --- /dev/null +++ b/ohos/flutter-pag/example/lib/main.dart @@ -0,0 +1,431 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'dart:typed_data'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:pag/pag.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + home: MyHome(), + ); + } +} + +class MyHome extends StatefulWidget { + @override + _MyHomeState createState() => _MyHomeState(); +} + +class _MyHomeState extends State { + GlobalKey _fansDanceKey = + GlobalKey(debugLabel: _assetFans); + GlobalKey _fansDanceKey1 = + GlobalKey(debugLabel: _assetFans1); + GlobalKey _assetDanceKey = + GlobalKey(debugLabel: _assetFans); + GlobalKey _assetDanceKey1 = + GlobalKey(debugLabel: _assetFans1); + GlobalKey get assetPagKey => _pagAsset == _assetFans + ? change + ? _fansDanceKey + : _fansDanceKey1 + : change + ? _assetDanceKey + : _assetDanceKey1; + + final GlobalKey networkPagKey = GlobalKey(); + final GlobalKey bytesPagKey = GlobalKey(); + + Uint8List? bytesData; + + // 本地加载资源 + static bool change = false; + static const String _assetFans1 = 'data/fans.pag1'; + static const String _assetDance1 = 'data/dance.pag1'; + static const String _assetFans = 'data/7.pag'; + static const String _assetDance = 'data/dance.pag'; + static const String _assetError = 'data/error.pag'; + String _pagAsset = _assetFans; + int repeatCount = -1; + bool isLoop = false; + double slideValue = 0.0; + bool autoPlay = false; + + void changeAsset() { + setState(() { + _pagAsset = _pagAsset == _assetFans ? _assetDance : _assetFans; + }); + } + + @override + void initState() { + rootBundle.load("data/fans.pag").then((data) { + setState(() { + bytesData = Uint8List.view(data.buffer); + }); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('PAGView example app'), + ), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ///TODO: PAGView加载本地资源 + Padding( + padding: EdgeInsets.only(top: 20, left: 12, bottom: 20), + child: Text( + "PAGView加载本地资源:", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ), + SizedBox( + width: 100, + height: 100, + child: PAGView.asset( + _pagAsset, + repeatCount: repeatCount, + initProgress: slideValue, + autoPlay: autoPlay, + key: assetPagKey, + ), + ), + SizedBox( + width: 400, + height: 200, + child: Column(children: [ + Row( + children: [ + Text('是否循环:'), + Switch( + value: isLoop, + onChanged: (bool value) { + setState(() { + isLoop = value; + repeatCount = value ? -1 : 0; + change = !change; + }); + }) + ], + ), + Row(children: [ + Text('初始化进度:'), + Slider( + value: slideValue, + onChanged: (value) { + setState(() { + slideValue = value; + }); + }), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.published_with_changes_sharp, + color: Colors.black54, + ), + onPressed: () { + // 重置 + setState(() { + change = !change; + }); + }, + ) + ]), + Row(children: [ + Text('是否自动播放:'), + Switch( + value: autoPlay, + onChanged: (bool value) { + setState(() { + autoPlay = value; + change = !change; + }); + // assetPagKey.currentState.setProgress(55.0); + }) + ]), + Row(children: [ + Text('获取图层'), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.published_with_changes_sharp, + color: Colors.black54, + ), + onPressed: () async { + var aa = await assetPagKey.currentState?.getLayersUnderPoint(50, 50); + print(aa); + }), + ]), + ]), + ), + Padding( + padding: EdgeInsets.only(left: 12, top: 10), + child: Row( + children: [ + IconButton( + iconSize: 30, + icon: const Icon( + Icons.pause_circle, + color: Colors.black54, + ), + onPressed: () { + // 暂停 + assetPagKey.currentState?.pause(); + }, + ), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.play_circle, + color: Colors.black54, + ), + onPressed: () { + //播放 + assetPagKey.currentState?.start(); + }, + ), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.published_with_changes_sharp, + color: Colors.black54, + ), + onPressed: changeAsset), + Text( + "<= 请点击控制动画(可切换)", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ], + ), + ), + + /// TODO: PAGView加载网络资源 + Padding( + padding: EdgeInsets.only(top: 50, left: 12, bottom: 20), + child: Text( + "PAGView加载网络资源:", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ), + PAGView.network( + "https://svipwebwx-30096.sz.gfp.tencent-cloud.com/file1647585475981.pag", + repeatCount: PAGView.REPEAT_COUNT_LOOP, + initProgress: 0.25, + autoPlay: true, + key: networkPagKey, + ), + Padding( + padding: EdgeInsets.only(left: 12, top: 10), + child: Row( + children: [ + IconButton( + iconSize: 30, + icon: const Icon( + Icons.pause_circle, + color: Colors.black54, + ), + onPressed: () { + // 暂停 + networkPagKey.currentState?.pause(); + }, + ), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.pause_circle, + color: Colors.red, + ), + onPressed: () { + // 停止 + networkPagKey.currentState?.stop(); + }, + ), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.play_circle, + color: Colors.black54, + ), + onPressed: () { + // 播放 + networkPagKey.currentState?.start(); + }, + ), + Text( + "<= 请点击控制动画", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ], + ), + ), + + /// TODO: PAGView加载二进制资源 + Padding( + padding: EdgeInsets.only(top: 50, left: 12, bottom: 20), + child: Text( + "PAGView加载二进制资源:", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ), + Visibility( + visible: bytesData?.isNotEmpty == true, + child: PAGView.bytes( + bytesData, + repeatCount: PAGView.REPEAT_COUNT_LOOP, + initProgress: 0.25, + autoPlay: true, + key: bytesPagKey, + ), + ), + Padding( + padding: EdgeInsets.only(left: 12, top: 10), + child: Row( + children: [ + IconButton( + iconSize: 30, + icon: const Icon( + Icons.pause_circle, + color: Colors.black54, + ), + onPressed: () { + // 暂停 + bytesPagKey.currentState?.pause(); + }, + ), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.delete, + color: Colors.red, + ), + onPressed: () { + // 销毁 + bytesPagKey.currentState?.dispose(); + + }, + ), + IconButton( + iconSize: 30, + icon: const Icon( + Icons.play_circle, + color: Colors.black54, + ), + onPressed: () { + // 播放 + bytesPagKey.currentState?.start(); + }, + ), + Text( + "<= 请点击控制动画", + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ], + ), + ), + + /// TODO: PAGView加载二进制资源 + Padding( + padding: EdgeInsets.only(top: 20, left: 12, bottom: 20), + child: Text( + "PAGView加载失败的默认占位图:", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ), + SizedBox( + width: 100, + height: 100, + child: PAGView.asset( + _assetError, + repeatCount: PAGView.REPEAT_COUNT_LOOP, + initProgress: 0.25, + autoPlay: true, + defaultBuilder: (context) { + return Container( + color: Colors.grey, + alignment: Alignment.center, + margin: EdgeInsets.all(16), + child: Text("load fail"), + ); + }, + ), + ), + /// TODO: 加载大图 + Padding( + padding: EdgeInsets.only(top: 20, left: 12, bottom: 20), + child: Text( + "PAGView加载大图:", + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.black54), + ), + ), + SizedBox( + child: PAGView.asset( + 'data/PAG_LOGO.pag', + repeatCount: PAGView.REPEAT_COUNT_LOOP, + initProgress: 0.25, + autoPlay: true, + defaultBuilder: (context) { + return Container( + color: Colors.grey, + alignment: Alignment.center, + margin: EdgeInsets.all(16), + child: Text("load fail"), + ); + }, + ), + ), + ], + ), + )); + } +} diff --git a/ohos/flutter-pag/example/ohos/.gitignore b/ohos/flutter-pag/example/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..6ca13b3170eec5dd5ac5ad7f1c4dd0118845f473 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/.gitignore @@ -0,0 +1,19 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +*.har +**/BuildProfile.ets +**/oh-package-lock.json5 + +**/src/main/resources/rawfile/flutter_assets/ +**/libs/arm64-v8a/libapp.so +**/libs/arm64-v8a/libflutter.so +**/libs/arm64-v8a/libvmservice_snapshot.so diff --git a/ohos/flutter-pag/example/ohos/AppScope/app.json5 b/ohos/flutter-pag/example/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..0dfb6d8945d95f01fe27baae79f45d3049f22557 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.example", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/AppScope/resources/base/element/string.json b/ohos/flutter-pag/example/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..810f4a362c1d177309eec4f2efe5cac2f4558c28 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "example" + } + ] +} diff --git a/ohos/flutter-pag/example/ohos/AppScope/resources/base/media/app_icon.png b/ohos/flutter-pag/example/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/flutter-pag/example/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/flutter-pag/example/ohos/build-profile.json5 b/ohos/flutter-pag/example/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..26bea001ac6999860a2890121e380c122e6b601b --- /dev/null +++ b/ohos/flutter-pag/example/ohos/build-profile.json5 @@ -0,0 +1,28 @@ +{ + "app": { + "signingConfigs": [ + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/.gitignore b/ohos/flutter-pag/example/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/build-profile.json5 b/ohos/flutter-pag/example/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/hvigorfile.ts b/ohos/flutter-pag/example/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/flutter-pag/example/ohos/entry/oh-package.json5 b/ohos/flutter-pag/example/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..60efeb6d2ad3314ded81732f43b5cf021181d1b2 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "pag": "file:../har/pag.har" + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/flutter-pag/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8bc48be8773196f34cccb15cf517f87f5c6b94d2 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility, FlutterEngine } from '@ohos/flutter_ohos'; +import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; + +export default class EntryAbility extends FlutterAbility { + configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + GeneratedPluginRegistrant.registerWith(flutterEngine) + } +} diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/ets/pages/Index.ets b/ohos/flutter-pag/example/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..1125f9fdd95f4310a182c1c9e3680f37f73686c9 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +let storage = LocalStorage.getShared() +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry(storage) +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + @LocalStorageLink('viewId') viewId: string = ""; + + build() { + Column() { + FlutterPage({ viewId: this.viewId }) + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets b/ohos/flutter-pag/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets new file mode 100644 index 0000000000000000000000000000000000000000..8a5d8a9dfb7145902e57256e2889a652567711f4 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/ets/plugins/GeneratedPluginRegistrant.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { FlutterEngine, Log } from '@ohos/flutter_ohos'; +import FlutterPagPlugin from 'pag'; + +/** + * Generated file. Do not edit. + * This file is generated by the Flutter tool based on the + * plugins that support the Ohos platform. + */ + +const TAG = "GeneratedPluginRegistrant"; + +export class GeneratedPluginRegistrant { + + static registerWith(flutterEngine: FlutterEngine) { + try { + flutterEngine.getPlugins()?.add(new FlutterPagPlugin()); + } catch (e) { + Log.e( + TAG, + "Tried to register plugins with FlutterEngine (" + + flutterEngine + + ") failed."); + Log.e(TAG, "Received exception while registering", e); + } + } +} diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/module.json5 b/ohos/flutter-pag/example/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/element/color.json b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/element/string.json b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..67e0f4ff4ac762d1714f6e215c6636a4ad3d620e --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "example" + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/media/icon.png b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/flutter-pag/example/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..67e0f4ff4ac762d1714f6e215c6636a4ad3d620e --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "example" + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/flutter-pag/example/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..601e2b5a1c273aa04920b126e3ab715a4450e58f --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "example" + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/module.json5 b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/flutter-pag/example/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/flutter-pag/example/ohos/hvigor/hvigor-config.json5 b/ohos/flutter-pag/example/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..541ba35711b75986f9295410ee38fdb8f2572878 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "modelVersion": "5.0.0", + "dependencies": { + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/hvigorfile.ts b/ohos/flutter-pag/example/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..8f2d2aafe6d6a3a71a9944ebd0c91fbc308ac9d1 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/hvigorfile.ts @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/ohos/oh-package.json5 b/ohos/flutter-pag/example/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..0df13ad348f62a5dfe0d76bbd753f0bbaefe8eb8 --- /dev/null +++ b/ohos/flutter-pag/example/ohos/oh-package.json5 @@ -0,0 +1,20 @@ +{ + "modelVersion": "5.0.0", + "name": "example", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har" + }, + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "overrides": { + "@ohos/flutter_ohos": "file:./har/flutter.har", + "pag": "file:./har/pag.har", + "@ohos/flutter_module": "file:./entry" + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/example/pubspec.yaml b/ohos/flutter-pag/example/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..afd12044adfc9df1e50db08cf9815cb6fb18781c --- /dev/null +++ b/ohos/flutter-pag/example/pubspec.yaml @@ -0,0 +1,72 @@ +name: flutter_pag_plugin_example +description: Demonstrates how to use the flutter_pag_plugin plugin. + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +environment: + sdk: ">=2.12.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + pag: + # When depending on this package from a real application you should use: + # flutter_pag_plugin: ^x.y.z + # See https://dart.dev/tools/pub/dependencies#version-constraints + # The example app is bundled with the plugin so we use a path dependency on + # the parent directory to use the current plugin's version. + path: ../ + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - data/ + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/ohos/flutter-pag/example/test/widget_test.dart b/ohos/flutter-pag/example/test/widget_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..122e7754ac0ac7d66acc574b35d818bc3ebf932b --- /dev/null +++ b/ohos/flutter-pag/example/test/widget_test.dart @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_pag_plugin_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data!.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/ohos/flutter-pag/ios/.gitignore b/ohos/flutter-pag/ios/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0c885071e36bc0722eaa426909d674968db20114 --- /dev/null +++ b/ohos/flutter-pag/ios/.gitignore @@ -0,0 +1,38 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig +/Flutter/ephemeral/ +/Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/ohos/flutter-pag/ios/Assets/.gitkeep b/ohos/flutter-pag/ios/Assets/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/flutter-pag/ios/Classes/FlutterPagPlugin.h b/ohos/flutter-pag/ios/Classes/FlutterPagPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..5cd2ac179a0ed603a8333af6e4295e365c92b8e3 --- /dev/null +++ b/ohos/flutter-pag/ios/Classes/FlutterPagPlugin.h @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef PLATFORM_VIEW_OHOS_NAPI_H +#define PLATFORM_VIEW_OHOS_NAPI_H +#import + +@interface FlutterPagPlugin : NSObject +@end +#endif \ No newline at end of file diff --git a/ohos/flutter-pag/ios/Classes/FlutterPagPlugin.m b/ohos/flutter-pag/ios/Classes/FlutterPagPlugin.m new file mode 100644 index 0000000000000000000000000000000000000000..97af135866caf33ad00c8c7c5f8fc35ac3c0ce50 --- /dev/null +++ b/ohos/flutter-pag/ios/Classes/FlutterPagPlugin.m @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#import "FlutterPagPlugin.h" +#import "TGFlutterPagRender.h" +#import "TGFlutterPagDownloadManager.h" + +/** + FlutterPagPlugin,处理flutter MethodChannel约定的方法 + */ +#define PlayCallback @"PAGCallback" +#define ArgumentEvent @"PAGEvent" +#define ArgumentTextureId @"textureId" + +@interface FlutterPagPlugin() + +/// flutter引擎注册的textures对象 +@property(nonatomic, weak) NSObject* textures; + +/// flutter引擎注册的registrar对象 +@property(nonatomic, weak) NSObject* registrar; + +/// 保存textureId跟render对象的对应关系 +@property (nonatomic, strong) NSMutableDictionary *renderMap; + +/// pag对象的缓存 +@property (nonatomic, strong)NSCache *cache; + +/// 用于通信的channel +@property (nonatomic, strong)FlutterMethodChannel* channel; + +@end + +@implementation FlutterPagPlugin ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = [FlutterMethodChannel + methodChannelWithName:@"flutter_pag_plugin" + binaryMessenger:[registrar messenger]]; + FlutterPagPlugin* instance = [[FlutterPagPlugin alloc] init]; + instance.textures = registrar.textures; + instance.registrar = registrar; + instance.channel = channel; + [registrar addMethodCallDelegate:instance channel:channel]; +} + +- (void)getLayersUnderPoint:(id)arguments result:(FlutterResult _Nonnull)result { + NSNumber* textureId = arguments[@"textureId"]; + NSNumber* x = arguments[@"x"]; + NSNumber* y = arguments[@"y"]; + TGFlutterPagRender *render = [_renderMap objectForKey:textureId]; + NSArray *names = [render getLayersUnderPoint:CGPointMake(x.doubleValue, y.doubleValue)]; + result(names); +} + +- (void)release:(id)arguments result:(FlutterResult _Nonnull)result { + NSNumber* textureId = arguments[@"textureId"]; + if(textureId == nil){ + result(@""); + return; + } + [self.textures unregisterTexture:textureId.intValue]; + TGFlutterPagRender *render = [_renderMap objectForKey:textureId]; + [render releaseRender]; + [_renderMap removeObjectForKey:textureId]; + result(@""); +} + +- (void)setProgress:(id)arguments result:(FlutterResult _Nonnull)result { + NSNumber* textureId = arguments[@"textureId"]; + if(textureId == nil){ + result(@""); + return; + } + double progress = 0.0; + if (arguments[@"progress"]) { + progress = [arguments[@"progress"] doubleValue]; + } + TGFlutterPagRender *render = [_renderMap objectForKey:textureId]; + [render setProgress:progress]; + result(@""); +} + +- (void)pause:(id)arguments result:(FlutterResult _Nonnull)result { + NSNumber* textureId = arguments[@"textureId"]; + if(textureId == nil){ + result(@""); + return; + } + TGFlutterPagRender *render = [_renderMap objectForKey:textureId]; + [render pauseRender]; + result(@""); +} + +- (void)stop:(id)arguments result:(FlutterResult _Nonnull)result { + NSNumber* textureId = arguments[@"textureId"]; + if(textureId == nil){ + result(@""); + return; + } + TGFlutterPagRender *render = [_renderMap objectForKey:textureId]; + [render stopRender]; + result(@""); +} + +- (void)start:(id)arguments result:(FlutterResult _Nonnull)result { + NSNumber* textureId = arguments[@"textureId"]; + if(textureId == nil){ + result(@""); + return; + } + TGFlutterPagRender *render = [_renderMap objectForKey:textureId]; + [render startRender]; + result(@""); +} + +- (void)initPag:(id)arguments result:(FlutterResult _Nonnull)result { + if (arguments == nil || (arguments[@"assetName"] == NSNull.null && arguments[@"url"] == NSNull.null && arguments[@"bytesData"] == NSNull.null)) { + result(@-1); + NSLog(@"showPag arguments is nil"); + return; + } + double initProgress = 0.0; + if (arguments[@"initProgress"]) { + initProgress = [arguments[@"initProgress"] doubleValue]; + } + int repeatCount = -1; + if(arguments[@"repeatCount"]){ + repeatCount = [[arguments objectForKey:@"repeatCount"] intValue]; + } + + BOOL autoPlay = NO; + if(arguments[@"autoPlay"]){ + autoPlay = [[arguments objectForKey:@"autoPlay"] boolValue]; + } + + NSString* assetName = arguments[@"assetName"]; + NSData *pagData = nil; + if ([assetName isKindOfClass:NSString.class] && assetName.length > 0) { + NSString *key = assetName; + pagData = [self getCacheData:key]; + if (!pagData) { + NSString* package = arguments[@"package"]; + NSString* resourcePath; + if(package && [package isKindOfClass:NSString.class] && package.length > 0){ + resourcePath = [self.registrar lookupKeyForAsset:assetName fromPackage:package]; + }else{ + resourcePath = [self.registrar lookupKeyForAsset:assetName]; + } + + resourcePath = [[NSBundle mainBundle] pathForResource:resourcePath ofType:nil]; + + pagData = [NSData dataWithContentsOfFile:resourcePath]; + [self setCacheData:key data:pagData]; + + } + [self pagRenderWithPagData:pagData progress:initProgress repeatCount:repeatCount autoPlay:autoPlay result:result]; + } + NSString* url = arguments[@"url"]; + if ([url isKindOfClass:NSString.class] && url.length > 0) { + NSURLSessionDownloadTask *task; + [task resume]; + NSString *key = url; + pagData = [self getCacheData:key]; + if (!pagData) { + __weak typeof(self) weak_self = self; + [TGFlutterPagDownloadManager download:url completionHandler:^(NSData * _Nonnull data, NSError * _Nonnull error) { + if (data) { + [weak_self setCacheData:key data:pagData]; + [weak_self pagRenderWithPagData:data progress:initProgress repeatCount:repeatCount autoPlay:autoPlay result:result]; + }else{ + result(@-1); + } + }]; + }else{ + [self pagRenderWithPagData:pagData progress:initProgress repeatCount:repeatCount autoPlay:autoPlay result:result]; + } + } + + id bytesData = arguments[@"bytesData"]; + if(bytesData != nil && [bytesData isKindOfClass:FlutterStandardTypedData.class]){ + FlutterStandardTypedData *typedData = bytesData; + if(typedData.type == FlutterStandardDataTypeUInt8 && typedData.data != nil){ + [self pagRenderWithPagData:typedData.data progress:initProgress repeatCount:repeatCount autoPlay:autoPlay result:result]; + }else{ + result(@-1); + } + } +} + +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + + id arguments = call.arguments; + if ([@"getPlatformVersion" isEqualToString:call.method]) { + result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); + } else if([@"initPag" isEqualToString:call.method]){ + [self initPag:arguments result:result]; + } else if([@"start" isEqualToString:call.method]){ + [self start:arguments result:result]; + } else if([@"stop" isEqualToString:call.method]){ + [self stop:arguments result:result]; + } else if([@"pause" isEqualToString:call.method]){ + [self pause:arguments result:result]; + } else if([@"setProgress" isEqual:call.method]){ + [self setProgress:arguments result:result]; + } else if([@"release" isEqualToString:call.method]){ + [self release:arguments result:result]; + } else if([@"getLayersUnderPoint" isEqualToString:call.method]){ + [self getLayersUnderPoint:arguments result:result]; + } else { + result(FlutterMethodNotImplemented); + } +} + +-(void)pagRenderWithPagData:(NSData *)pagData progress:(double)progress repeatCount:(int)repeatCount autoPlay:(BOOL)autoPlay result:(FlutterResult)result{ + __block int64_t textureId = -1; + __weak typeof(self) weakSelf = self; + TGFlutterPagRender *render = [[TGFlutterPagRender alloc] initWithPagData:pagData progress:progress frameUpdateCallback:^{ + [weakSelf.textures textureFrameAvailable:textureId]; + } eventCallback:^(NSString * event) { + [weakSelf.channel invokeMethod:PlayCallback arguments:@{ArgumentTextureId:@(textureId), ArgumentEvent:event}]; + }]; + [render setRepeatCount:repeatCount]; + textureId = [self.textures registerTexture:render]; + if(_renderMap == nil){ + _renderMap = [[NSMutableDictionary alloc] init]; + } + [_renderMap setObject:render forKey:@(textureId)]; + result(@{@"textureId":@(textureId), @"width":@([render size].width), @"height":@([render size].height)}); + if(autoPlay){ + [render startRender]; + } +} + +-(NSData *)getCacheData:(NSString *)key{ + return [self.cache objectForKey:key]; +} + +-(void)setCacheData:(NSString *)key data:(NSData *)data{ + if (data == nil || key == nil) { + return; + } + [self.cache setObject:data forKey:key cost:data.length]; +} + +-(NSCache *)cache{ + if (!_cache) { + _cache = [[NSCache alloc] init]; + ///缓存64m + _cache.totalCostLimit = 64*1024*1024; + _cache.countLimit = 32; + } + return _cache; +} +@end diff --git a/ohos/flutter-pag/ios/Classes/TGFlutterPagDownloadManager.h b/ohos/flutter-pag/ios/Classes/TGFlutterPagDownloadManager.h new file mode 100644 index 0000000000000000000000000000000000000000..759f56007fa445a393223571354501aa0bc99ea1 --- /dev/null +++ b/ohos/flutter-pag/ios/Classes/TGFlutterPagDownloadManager.h @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef PLATFORM_VIEW_OHOS_NAPI_H +#define PLATFORM_VIEW_OHOS_NAPI_H +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + Pag文件下载工具 + */ +@interface TGFlutterPagDownloadManager : NSObject + +///下载pag文件 ++(void)download:(NSString *)urlStr completionHandler:(void (^)(NSData * data, NSError * error))handler; + +@end + +NS_ASSUME_NONNULL_END +#endif diff --git a/ohos/flutter-pag/ios/Classes/TGFlutterPagDownloadManager.m b/ohos/flutter-pag/ios/Classes/TGFlutterPagDownloadManager.m new file mode 100644 index 0000000000000000000000000000000000000000..89a65822c47c22a1709f3424fbae59bdd2e54b8b --- /dev/null +++ b/ohos/flutter-pag/ios/Classes/TGFlutterPagDownloadManager.m @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import "TGFlutterPagDownloadManager.h" +#import + +#define CACHE_DIR @"pagCache" + +@implementation TGFlutterPagDownloadManager + ++(void)download:(NSString *)urlStr completionHandler:(void (^)(NSData * data, NSError * error))handler{ + NSString *cachePath = [TGFlutterPagDownloadManager cachePath:urlStr]; + if(cachePath == nil){ + handler(nil, [[NSError alloc] initWithDomain:NSURLErrorDomain code:-1 userInfo:nil]); + return; + } + if ([[NSFileManager defaultManager] fileExistsAtPath:cachePath]) { + NSData *data = [NSData dataWithContentsOfFile:cachePath]; + if (data) { + handler(data, nil); + return; + } + + } + NSURL *url = [NSURL URLWithString:urlStr]; + NSURLRequest *request = [NSURLRequest requestWithURL:url]; + NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] + dataTaskWithRequest:request + completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + handler(data, error); + if (data) { + [TGFlutterPagDownloadManager saveData:data path:cachePath]; + } + }]; + [dataTask resume]; +} + ++(NSString *)cacheDir{ + NSArray *cachePaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + static NSString *cacheDir; + if (!cacheDir) { + cacheDir= [NSString stringWithFormat:@"%@/%@", cachePaths.firstObject, CACHE_DIR]; + } + return cacheDir; +} + ++(NSString *)cachePath:(NSString *)url{ + if (![url isKindOfClass:NSString.class] || url.length <= 0) { + return nil; + } + + NSString *key = [TGFlutterPagDownloadManager md5:url]; + return [NSString stringWithFormat:@"%@/%@", [self cacheDir], key]; +} + ++(NSString *)md5:(NSString *)str{ + const char* input = [str UTF8String]; + unsigned char result[CC_MD5_DIGEST_LENGTH]; + CC_MD5(input, (CC_LONG)strlen(input), result); + + NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; + for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { + [digest appendFormat:@"%02x", result[i]]; + } + return digest; +} + ++(void)saveData:(NSData *)data path:(NSString *)cachePath{ + NSString *cahceDir = [TGFlutterPagDownloadManager cacheDir]; + if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath]) { + [[NSFileManager defaultManager] createDirectoryAtPath:cahceDir withIntermediateDirectories:YES attributes:nil error:nil]; + } + [data writeToFile:cachePath atomically:YES]; +} + +@end diff --git a/ohos/flutter-pag/ios/Classes/TGFlutterPagRender.h b/ohos/flutter-pag/ios/Classes/TGFlutterPagRender.h new file mode 100644 index 0000000000000000000000000000000000000000..f3a2a0993e3c27dc5a2c0a3aa13e5b1cfd52d714 --- /dev/null +++ b/ohos/flutter-pag/ios/Classes/TGFlutterPagRender.h @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef PLATFORM_VIEW_OHOS_NAPI_H +#define PLATFORM_VIEW_OHOS_NAPI_H + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +#define EventStart @"onAnimationStart" +#define EventEnd @"onAnimationEnd" +#define EventCancel @"onAnimationCancel" +#define EventRepeat @"onAnimationRepeat" + +typedef void(^FrameUpdateCallback)(void); + +typedef void(^PAGEventCallback)(NSString *); + +/** + Pag纹理渲染类 + */ +@interface TGFlutterPagRender : NSObject + +///当前pag的size +@property(nonatomic, readonly) CGSize size; + +- (instancetype)initWithPagData:(NSData*)pagData + progress:(double)initProgress + frameUpdateCallback:(FrameUpdateCallback)frameUpdateCallback + eventCallback:(PAGEventCallback)eventCallback; + +- (void)startRender; + +- (void)stopRender; + +- (void)pauseRender; + +- (void)releaseRender; + +- (void)setProgress:(double)progress; + +- (void)setRepeatCount:(int)repeatCount; + +- (NSArray *)getLayersUnderPoint:(CGPoint)point; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/ohos/flutter-pag/ios/Classes/TGFlutterPagRender.mm b/ohos/flutter-pag/ios/Classes/TGFlutterPagRender.mm new file mode 100644 index 0000000000000000000000000000000000000000..c495730a67eba0af2abdeb58743b33823cdbf744 --- /dev/null +++ b/ohos/flutter-pag/ios/Classes/TGFlutterPagRender.mm @@ -0,0 +1,193 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import "TGFlutterPagRender.h" +#import +#import +#import +#import +#import +#include +#include +#include + +@interface TGFlutterPagRender() + +@property(nonatomic, strong)PAGSurface *surface; + +@property(nonatomic, strong)PAGPlayer* player; + +@property(nonatomic, strong)PAGFile* pagFile; + +@property(nonatomic, assign)double initProgress; + +@property(nonatomic, assign)BOOL endEvent; + + +@end + +static int64_t GetCurrentTimeUS() { + static auto START_TIME = std::chrono::high_resolution_clock::now(); + auto now = std::chrono::high_resolution_clock::now(); + auto ns = std::chrono::duration_cast(now - START_TIME); + return static_cast(ns.count() * 1e-3); +} + +@implementation TGFlutterPagRender +{ + FrameUpdateCallback _frameUpdateCallback; + PAGEventCallback _eventCallback; + CADisplayLink *_displayLink; + int _lastUpdateTs; + int _repeatCount; + int64_t start; + int64_t _currRepeatCount; +} + +- (CVPixelBufferRef)copyPixelBuffer { + + int64_t duration = [_player duration]; + if(duration <= 0){ + duration = 1; + } + + int64_t timestamp = GetCurrentTimeUS(); + if(start <= 0){ + start = timestamp; + } + auto count = (timestamp - start) / duration; + double value = 0; + if (_repeatCount >= 0 && count >= _repeatCount) { + value = 1; + if(!_endEvent){ + _endEvent = YES; + _eventCallback(EventEnd); + } + } else { + _endEvent = NO; + double playTime = (timestamp - start) % duration; + value = static_cast(playTime) / duration; + if (_currRepeatCount < count) { + _currRepeatCount = count; + _eventCallback(EventRepeat); + } + } + [_player setProgress:value]; + [_player flush]; + CVPixelBufferRef target = [_surface getCVPixelBuffer]; + CVBufferRetain(target); + return target; +} + +- (instancetype)initWithPagData:(NSData*)pagData + progress:(double)initProgress + frameUpdateCallback:(FrameUpdateCallback)frameUpdateCallback + eventCallback:(PAGEventCallback)eventCallback +{ + if (self = [super init]) { + _frameUpdateCallback = frameUpdateCallback; + _eventCallback = eventCallback; + _initProgress = initProgress; + if(pagData){ + _pagFile = [PAGFile Load:pagData.bytes size:pagData.length]; + _player = [[PAGPlayer alloc] init]; + [_player setComposition:_pagFile]; + _surface = [PAGSurface MakeFromGPU:CGSizeMake(_pagFile.width, _pagFile.height)]; + [_player setSurface:_surface]; + [_player setProgress:initProgress]; + [_player flush]; + _frameUpdateCallback(); + } + } + return self; +} + +- (void)startRender +{ + if (!_displayLink) { + _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)]; + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; + } + if(start <= 0){ + start = GetCurrentTimeUS(); + } + _eventCallback(EventStart); +} + +- (void)stopRender +{ + if (_displayLink) { + [_displayLink invalidate]; + _displayLink = nil; + } + [_player setProgress:_initProgress]; + [_player flush]; + _frameUpdateCallback(); + if(!_endEvent){ + _endEvent = YES; + _eventCallback(EventEnd); + } + _eventCallback(EventCancel); +} + +- (void)pauseRender{ + if (_displayLink) { + [_displayLink invalidate]; + _displayLink = nil; + } +} +- (void)setRepeatCount:(int)repeatCount{ + _repeatCount = repeatCount; +} + +- (void)setProgress:(double)progress{ + [_player setProgress:progress]; + [_player flush]; + _frameUpdateCallback(); +} + +- (NSArray *)getLayersUnderPoint:(CGPoint)point{ + NSArray* layers = [_player getLayersUnderPoint:point]; + NSMutableArray *layerNames = [[NSMutableArray alloc] init]; + for (PAGLayer *layer in layers) { + [layerNames addObject:layer.layerName]; + } + return layerNames; +} + +- (CGSize)size{ + return CGSizeMake(_pagFile.width, _pagFile.height); +} + +- (void)update +{ + _frameUpdateCallback(); +} + +- (void)releaseRender{ + if (_displayLink) { + [_displayLink invalidate]; + _displayLink = nil; + } +} + +- (void)dealloc { + _frameUpdateCallback = nil; + _eventCallback = nil; + _surface = nil; + self.pagFile = nil; + self.player = nil; +} +@end diff --git a/ohos/flutter-pag/ios/pag.podspec b/ohos/flutter-pag/ios/pag.podspec new file mode 100644 index 0000000000000000000000000000000000000000..2f2f73d185b7153d85c9f5d833938f59ee97f0f8 --- /dev/null +++ b/ohos/flutter-pag/ios/pag.podspec @@ -0,0 +1,39 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint flutter_pag_plugin.podspec` to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'pag' + s.version = '0.0.1' + s.summary = 'A new Flutter plugin.' + s.description = <<-DESC +A new Flutter plugin. + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.static_framework = true + s.dependency 'Flutter' + s.dependency 'libpag' + s.platform = :ios, '9.0' + s.library = 'c++' + + # Flutter.framework does not contain a i386 slice. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } +end diff --git a/ohos/flutter-pag/lib/pag.dart b/ohos/flutter-pag/lib/pag.dart new file mode 100644 index 0000000000000000000000000000000000000000..db2f8ddc168764478aa83629def12d72c258a0ea --- /dev/null +++ b/ohos/flutter-pag/lib/pag.dart @@ -0,0 +1,316 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'dart:async'; + +import 'dart:io'; + +typedef PAGCallback = void Function(); +// typedef OnViewCreated = Function(PageViewController); + +class PAGView extends StatefulWidget { + double? width; + double? height; + + /// 二进制动画数据 + Uint8List? bytesData; + + /// 网络资源,动画链接 + String? url; + + /// flutter动画资源路径 + String? assetName; + + /// asset package + String? package; + + /// 初始化时播放进度 + double initProgress; + + /// 初始化后自动播放 + bool autoPlay; + + /// 循环次数 + int repeatCount; + + /// 初始化完成 + PAGCallback? onInit; + + /// Notifies the start of the animation. + PAGCallback? onAnimationStart; + + /// Notifies the end of the animation. + PAGCallback? onAnimationEnd; + + /// Notifies the cancellation of the animation. + PAGCallback? onAnimationCancel; + + /// Notifies the repetition of the animation. + PAGCallback? onAnimationRepeat; + + /// 加载失败时的默认控件构造器 + Widget Function(BuildContext context)? defaultBuilder; + + static const int REPEAT_COUNT_LOOP = -1; //无限循环 + static const int REPEAT_COUNT_DEFAULT = 1; //默认仅播放一次 + + PAGView.network( + this.url, { + this.width, + this.height, + this.repeatCount = REPEAT_COUNT_DEFAULT, + this.initProgress = 0, + this.autoPlay = false, + this.onInit, + this.onAnimationStart, + this.onAnimationEnd, + this.onAnimationCancel, + this.onAnimationRepeat, + this.defaultBuilder, + Key? key, + }) : super(key: key); + + PAGView.asset( + this.assetName, { + this.width, + this.height, + this.repeatCount = REPEAT_COUNT_DEFAULT, + this.initProgress = 0, + this.autoPlay = false, + this.package, + this.onInit, + this.onAnimationStart, + this.onAnimationEnd, + this.onAnimationCancel, + this.onAnimationRepeat, + this.defaultBuilder, + Key? key, + }) : super(key: key); + + PAGView.bytes( + this.bytesData, { + this.width, + this.height, + this.repeatCount = REPEAT_COUNT_DEFAULT, + this.initProgress = 0, + this.autoPlay = false, + this.package, + this.onInit, + this.onAnimationStart, + this.onAnimationEnd, + this.onAnimationCancel, + this.onAnimationRepeat, + this.defaultBuilder, + Key? key, + }) : super(key: key); + + @override + PAGViewState createState() => PAGViewState(); +} + +class PAGViewState extends State { + bool _hasLoadTexture = false; + int _textureId = -1; + + double rawWidth = 0; + double rawHeight = 0; + + // 原生接口 + static const String _nativeInit = 'initPag'; + static const String _getSize = 'getSize'; + static const String _nativeRelease = 'release'; + static const String _nativeStart = 'start'; + static const String _nativeStop = 'stop'; + static const String _nativePause = 'pause'; + static const String _nativeSetProgress = 'setProgress'; + static const String _nativeGetPointLayer = 'getLayersUnderPoint'; + + // 参数 + static const String _argumentTextureId = 'textureId'; + static const String _argumentAssetName = 'assetName'; + static const String _argumentPackage = 'package'; + static const String _argumentUrl = 'url'; + static const String _argumentBytes = 'bytesData'; + static const String _argumentRepeatCount = 'repeatCount'; + static const String _argumentInitProgress = 'initProgress'; + static const String _argumentAutoPlay = 'autoPlay'; + static const String _argumentWidth = 'width'; + static const String _argumentHeight = 'height'; + static const String _argumentPointX = 'x'; + static const String _argumentPointY = 'y'; + static const String _argumentProgress = 'progress'; + static const String _argumentEvent = 'PAGEvent'; + + // 监听该函数 + static const String _playCallback = 'PAGCallback'; + static const String _eventStart = 'onAnimationStart'; + static const String _eventEnd = 'onAnimationEnd'; + static const String _eventCancel = 'onAnimationCancel'; + static const String _eventRepeat = 'onAnimationRepeat'; + static const String _eventUpdate = 'onAnimationUpdate'; + // 回调监听 + static MethodChannel _channel = (const MethodChannel('flutter_pag_plugin') + ..setMethodCallHandler((result) { + if (result.method == _playCallback) { + callbackHandlers[result.arguments[_argumentTextureId]] + ?.call(result.arguments[_argumentEvent]); + } + + return Future.value(); + })); + + static Map callbackHandlers = {}; + + @override + void initState() { + super.initState(); + newTexture(); + } + + // 初始化 + void newTexture() async { + int repeatCount = widget.repeatCount <= 0 && + widget.repeatCount != PAGView.REPEAT_COUNT_LOOP + ? PAGView.REPEAT_COUNT_DEFAULT + : widget.repeatCount; + double initProcess = widget.initProgress < 0 ? 0 : widget.initProgress; + try { + dynamic result = await _channel.invokeMethod(_nativeInit, { + _argumentAssetName: widget.assetName, + _argumentPackage: widget.package, + _argumentUrl: widget.url, + _argumentBytes: widget.bytesData, + _argumentRepeatCount: repeatCount, + _argumentInitProgress: initProcess, + _argumentAutoPlay: widget.autoPlay + }); + if (result is Map) { + _textureId = result[_argumentTextureId]; + rawWidth = result[_argumentWidth] / 1.0 ?? 0; + rawHeight = result[_argumentHeight] / 1.0 ?? 0; + } + if (mounted) { + setState(() { + _hasLoadTexture = true; + }); + widget.onInit?.call(); + } else { + _channel.invokeMethod(_nativeRelease, {_argumentTextureId: _textureId}); + } + } catch (e) { + print('PAGViewState error: $e'); + } + // 事件回调 + if (_textureId >= 0) { + var events = { + _eventStart: widget.onAnimationStart, + _eventEnd: widget.onAnimationEnd, + _eventCancel: widget.onAnimationCancel, + _eventRepeat: widget.onAnimationRepeat, + }; + callbackHandlers[_textureId] = (event) { + events[event]?.call(); + }; + } + } + + /// 开始 + void start() { + if (!_hasLoadTexture) { + return; + } + _channel.invokeMethod(_nativeStart, {_argumentTextureId: _textureId}); + } + + /// 停止 + void stop() { + if (!_hasLoadTexture) { + return; + } + _channel.invokeMethod(_nativeStop, {_argumentTextureId: _textureId}); + } + + /// 暂停 + void pause() { + if (!_hasLoadTexture) { + return; + } + _channel.invokeMethod(_nativePause, {_argumentTextureId: _textureId}); + } + + /// 设置进度 + void setProgress(double progress) { + if (!_hasLoadTexture) { + return; + } + _channel.invokeMethod(_nativeSetProgress, + {_argumentTextureId: _textureId, _argumentProgress: progress}); + } + + /// 获取某一位置的图层 + Future> getLayersUnderPoint(double x, double y) async { + if (!_hasLoadTexture) { + return []; + } + return (await _channel.invokeMethod(_nativeGetPointLayer, { + _argumentTextureId: _textureId, + _argumentPointX: x, + _argumentPointY: y + }) as List) + .map((e) => e.toString()) + .toList(); + } + + @override + Widget build(BuildContext context) { + int repeatCount = widget.repeatCount <= 0 && + widget.repeatCount != PAGView.REPEAT_COUNT_LOOP + ? PAGView.REPEAT_COUNT_DEFAULT + : widget.repeatCount; + double initProcess = widget.initProgress < 0 ? 0 : widget.initProgress; + + if (_hasLoadTexture) { + return Container( + width: widget.width ?? (rawWidth / 2), + height: widget.height ?? (rawHeight / 2), + child: Platform.operatingSystem == 'ohos' + ? _getPlatformFaceView() + : Texture(textureId: _textureId), + ); + } else { + return widget.defaultBuilder?.call(context) ?? Container(); + } + } + + Widget _getPlatformFaceView() { + return OhosView( + viewType: 'flutter_pag_plugin', + onPlatformViewCreated: _onPlatformViewCreated, + creationParams: _textureId, + creationParamsCodec: const StandardMessageCodec(), + ); + } + + void _onPlatformViewCreated(int id) { + } + + @override + void dispose() { + _channel.invokeMethod(_nativeRelease, {_argumentTextureId: _textureId}); + callbackHandlers.remove(_textureId); + super.dispose(); + } +} diff --git a/ohos/flutter-pag/ohos/.gitignore b/ohos/flutter-pag/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/ohos/flutter-pag/ohos/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/BuildProfile.ets b/ohos/flutter-pag/ohos/BuildProfile.ets new file mode 100644 index 0000000000000000000000000000000000000000..9419150d8cc36adaf449c4abe945bc58e1aaed19 --- /dev/null +++ b/ohos/flutter-pag/ohos/BuildProfile.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +export const HAR_VERSION = '1.0.0'; +export const BUILD_MODE_NAME = 'debug'; +export const DEBUG = true; +export const TARGET_NAME = 'default'; + +/** + * BuildProfile Class is used only for compatibility purposes. + */ +export default class BuildProfile { + static readonly HAR_VERSION = HAR_VERSION; + static readonly BUILD_MODE_NAME = BUILD_MODE_NAME; + static readonly DEBUG = DEBUG; + static readonly TARGET_NAME = TARGET_NAME; +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/Index.ets b/ohos/flutter-pag/ohos/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d0c5e99ac9a0110b707ab09f921352db239c8e6 --- /dev/null +++ b/ohos/flutter-pag/ohos/Index.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterPagPlugin } from './src/main/ets/io/flutter/plugins/pag/entryability/FlutterPagPlugin'; + +export default FlutterPagPlugin; diff --git a/ohos/flutter-pag/ohos/build-profile.json5 b/ohos/flutter-pag/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..697dff23e224373edb713dc2b8a08ed7341d5b4c --- /dev/null +++ b/ohos/flutter-pag/ohos/build-profile.json5 @@ -0,0 +1,31 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + }, + "consumerFiles": [ + "./consumer-rules.txt" + ] + } + }, + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest" + } + ] +} diff --git a/ohos/flutter-pag/ohos/consumer-rules.txt b/ohos/flutter-pag/ohos/consumer-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/flutter-pag/ohos/hvigorfile.ts b/ohos/flutter-pag/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..d3aba127d60569f70f3bc6eacc9db994eb9af8f6 --- /dev/null +++ b/ohos/flutter-pag/ohos/hvigorfile.ts @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { harTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/ohos/flutter-pag/ohos/obfuscation-rules.txt b/ohos/flutter-pag/ohos/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..69c4d6a8a5531548e4886fa766090c5c157a87d9 --- /dev/null +++ b/ohos/flutter-pag/ohos/obfuscation-rules.txt @@ -0,0 +1,18 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/oh-package.json5 b/ohos/flutter-pag/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..933d1a35d726db91c17ae546fc08514d9ce89ed2 --- /dev/null +++ b/ohos/flutter-pag/ohos/oh-package.json5 @@ -0,0 +1,15 @@ +{ + "name": "pag", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "Index.ets", + "author": "", + "license": "Apache-2.0", + "dependencies": { + "@ohos/flutter_ohos": "file:./har/flutter.har", + "@tencent/libpag": "^4.4.9" + }, + "devDependencies": { + "@ohos/hypium": "1.0.6" + } +} diff --git a/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/EntryAbility.ets b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3caa9149aa30e03926cb96d73dd18926a3b0ad6 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/EntryAbility.ets @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' +import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; +import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine'; +import { FlutterPagPlugin } from './FlutterPagPlugin'; + +export default class EntryAbility extends FlutterAbility { + configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + GeneratedPluginRegistrant.registerWith(flutterEngine) + this.addPlugin(new FlutterPagPlugin()); + } +} diff --git a/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/FlutterPagPlugin.ets b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/FlutterPagPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..bada3db9cf2015e3d29e65a78a469a02a16b0610 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/FlutterPagPlugin.ets @@ -0,0 +1,190 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { PAGFile } from '@tencent/libpag'; +import { FlutterPlugin, + FlutterPluginBinding } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; +import { PagFactory } from './PagFactory'; +import MethodChannel, { + MethodCallHandler, + MethodResult +} from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; +import MethodCall from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall'; +import StandardMethodCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec'; +import fs from '@ohos.file.fs'; +import common from '@ohos.app.ability.common'; +import emitter from '@ohos.events.emitter'; + +AppStorage.setOrCreate('urlList', []) + +interface pagConfig { + textureId: number|undefined, + isUsed: boolean, + assetName?: string, + url: string|ArrayBuffer, + type: string, + autoPlay: boolean, + initProgress: number, + repeatCount: number +} + + +// 原生接口 +let _nativeInit: String = "initPag"; +let _getSize: String = "getSize"; +let _nativeRelease: String = "release"; +let _nativeStart: String = "start"; +let _nativeStop: String = "stop"; +let _nativePause:String = "pause"; +let _nativeSetProgress:String = "setProgress"; +let _nativeGetPointLayer:String = "getLayersUnderPoint"; + +enum enumsActions { + 'start' = "onAnimationStart", + 'stop' = "onAnimationEnd", + 'pause' = "onAnimationCancel", + 'repeat'= "onAnimationRepeat", + 'update'= "onAnimationUpdate" +} +export class FlutterPagPlugin implements FlutterPlugin, MethodCallHandler { + private methodChannel: MethodChannel | null = null; + private binding: FlutterPluginBinding | null = null; + getUniqueClassName(): string { + return 'FlutterPagPlugin'; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.binding = binding; + this.methodChannel = new MethodChannel(binding.getBinaryMessenger(), `flutter_pag_plugin`, StandardMethodCodec.INSTANCE); + this.methodChannel.setMethodCallHandler(this); + binding.getPlatformViewRegistry()?. + registerViewFactory('flutter_pag_plugin', new PagFactory(binding.getBinaryMessenger(), StandardMessageCodec.INSTANCE)); + this.addEventlisener() + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + // 接受Dart侧发来的消息 + let method: string = call.method; + switch (method) { + case _nativeInit: + this.initPag(call, result) + break; + case _nativeStart: + case _nativeStop: + case _nativePause: + case _nativeSetProgress: + case _nativeRelease: + this.setState(method, call); + result.success('') + break; + case _nativeGetPointLayer: + this.setState(method, call, result); + break; + default: + result.notImplemented(); + break; + } + } + async initPag(call: MethodCall, result: MethodResult) { + let assetName: string = call.argument('assetName'); + let bytes: Uint8Array = call.argument('bytesData'); + let url: string = call.argument('url'); + let repeatCount: number = call.argument('repeatCount'); + let initProgress: number = call.argument('initProgress'); + let autoPlay: boolean = call.argument('autoPlay'); + let context = getContext(this) as common.UIAbilityContext; + let dir = context.filesDir; + const textureId = this.binding?.getTextureRegistry().getTextureId(); + let filePath: string = dir + `pag_${textureId}.pag`; + let type = url != null ? 'url' : bytes != null ? 'bytes' : 'assetName' + let data = url != null ? url : bytes != null ? bytes : assetName; + + let _urlList: SubscribedAbstractProperty = AppStorage.link('urlList'); + const urlList = _urlList.get() + urlList.push({ + url: data, + type: type, + autoPlay: autoPlay, + initProgress: initProgress, + repeatCount: repeatCount, + textureId: textureId, + isUsed: false, + }) + _urlList.set(urlList); + + let file = await this.getFileDetail(type, data); + if (file) { + result.success({ + 'width': file.width(), + 'height': file.height(), + 'textureId': textureId + }); + } + } + + async getFileDetail(type: string, value: string|ArrayBuffer): Promise { + if (type == 'url') { + return await PAGFile.LoadFromPathAsync(value as string); + } else if (type == 'bytes') { + return await PAGFile.LoadFromBytes(new Uint8Array(value as ArrayBuffer).buffer); + } + let manager = getContext(this).resourceManager; + return await PAGFile.LoadFromAssets(manager, 'flutter_assets/' + value as string); + } + + setState(state: string, call:MethodCall, result?: MethodResult) { + const textureId = this.getTextureId(call) + const progress: number|undefined = call.argument('progress') + const x: number|undefined = call.argument('x') + const y: number|undefined = call.argument('y') + let eventData: emitter.EventData = { + data: { + 'type': 'action', + "pagPlayState": state, + 'progress': progress, + 'x': x, + 'y': y, + } + } + let innerEvent: emitter.InnerEvent = { eventId: textureId, } + emitter.emit(innerEvent, eventData) + + let innerEventOn: emitter.InnerEvent = { eventId: textureId } + emitter.on(innerEventOn, data => { + if (data?.data?.type === _nativeGetPointLayer) { + if (data?.data.list) { + result?.success(data?.data.list); + } + } + }) + } + + getTextureId(call:MethodCall):number { + return call.argument('textureId'); + } + addEventlisener() { + let innerEvent: emitter.InnerEvent = { eventId: 0 } + emitter.on(innerEvent, data => { + if (data?.data?.type === 'callback') { + this.methodChannel?.invokeMethod('PAGCallback', { + textureId: data?.data?.textureId, + PAGEvent: data?.data?.PAGEvent, + }) + } + }) + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void {} +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/PagFactory.ets b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/PagFactory.ets new file mode 100644 index 0000000000000000000000000000000000000000..ca77ff06a865433aad8d4e27dfeb17ae293afb14 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/PagFactory.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import PlatformViewFactory from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory'; +import { PagView } from './PagView'; +import common from '@ohos.app.ability.common'; +import PlatformView from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView'; + +export class PagFactory extends PlatformViewFactory { + message: BinaryMessenger; + private view: PagView | null = null; + + constructor(message: BinaryMessenger, createArgsCodes: MessageCodec) { + super(createArgsCodes); + this.message = message; + } + + public create(context: common.Context, viewId: number, args: Object): PlatformView { + this.view = new PagView(context, viewId, args, this.message) + return this.view; + } + public getView() { + return this.view; + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/PagView.ets b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/PagView.ets new file mode 100644 index 0000000000000000000000000000000000000000..369783d123807807c4988aabaa79e6fe7aa66cf5 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/entryability/PagView.ets @@ -0,0 +1,241 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { PAGFile, PAGImageView, PAGImageViewController, PAGView, PAGViewController } from '@tencent/libpag'; +import MethodChannel, { + MethodCallHandler +} from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; +import PlatformView, { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView'; +import common from '@ohos.app.ability.common'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import emitter from '@ohos.events.emitter'; + +enum EnumPagPlayState { + ePagPlayNull, + ePagPlayPlaying, + ePagPlayPause, + ePagPlayComplete, + ePagPlayStop +}; + +interface pagConfig { + textureId: number|undefined, + isUsed: boolean, + assetName?: string, + url: string|ArrayBuffer, + type: string, + autoPlay: boolean, + initProgress: number, + repeatCount: number +} + +let _nativeStart: String = "start"; +let _nativeStop: String = "stop"; +let _nativePause:String = "pause"; +let _nativeSetProgress:String = "setProgress"; +let _nativeRelease: String = "release"; +let _nativeGetPointLayer:String = "getLayersUnderPoint"; + +function notifyEvent (event: string, textureId: number|undefined) { + let innerEvent: emitter.InnerEvent = { eventId: 0 } + let eventData: emitter.EventData = { + data: { + 'type': 'callback', + "PAGEvent": event, + 'textureId': textureId + } + } + emitter.emit(innerEvent, eventData) +} +class pagLisener { + textureId: number|undefined; + constructor(id: number|undefined) { + this.textureId = id + } + onAnimationStart() { + notifyEvent('onAnimationStart', this.textureId) + } + onAnimationEnd() { + notifyEvent('onAnimationEnd', this.textureId) + } + onAnimationCancel() { + notifyEvent('onAnimationCancel', this.textureId) + } + onAnimationRepeat() { + notifyEvent('onAnimationRepeat', this.textureId) + } + onAnimationUpdate() { + notifyEvent('onAnimationUpdate', this.textureId) + } +} +@Component +struct PagComponent { + @Prop params: Params + pagView: PagView = this.params.platformView as PagView + @StorageLink('urlList') _urlList: pagConfig[] = [] + @State bkColor: Color = Color.Red + @State viewController: PAGViewController = new PAGViewController(); + textureId: number | undefined; + url: string|ArrayBuffer = ''; + type: string = ''; + assetName: string|undefined = '' + autoPlay: boolean = false; + initProgress: number = 0; + repeatCount: number = 0; + @State show: boolean = true; + + @State isPause: boolean = true; + @State currentStatus: string = "init"; + aboutToAppear(): void { + this.textureId = this.pagView.getTextureId(); + this._urlList.forEach((item) => { + if (!this.url && !this.assetName && this.textureId == item.textureId) { + this.url = item.url; + this.assetName = item.assetName; + this.autoPlay = item.autoPlay; + this.type = item.type; + this.initProgress = item.initProgress; + this.repeatCount = item.repeatCount; + this.buildComposition() + } + }) + + this.addEventlisener(); + } + /** + * 页面销毁时释放动画资源 + */ + aboutToDisappear(): void { + console.info('aboutToDisappear'); + } + async buildComposition() { + let file = await this.getFileDetail(this.type, this.url); + this.viewController.setComposition(file); + this.viewController.setRepeatCount(this.repeatCount); + this.viewController.setProgress(this.initProgress); + if (this.autoPlay) { + this.viewController.play() + } + this.viewController.addListener(new WeakRef(new pagLisener(this.textureId))) + } + + async getFileDetail(type: string, value: string|ArrayBuffer): Promise { + if (type == 'url') { + return await PAGFile.LoadFromPathAsync(value as string); + } else if (type == 'bytes') { + return await PAGFile.LoadFromBytes(new Uint8Array(value as ArrayBuffer).buffer); + } + let manager = getContext(this).resourceManager; + return await PAGFile.LoadFromAssets(manager, 'flutter_assets/' + value as string); + } + notifyEvent(event: string) { + let innerEvent: emitter.InnerEvent = { eventId: 0 } + let eventData: emitter.EventData = { + data: { + 'type': 'callback', + "PAGEvent": event, + 'textureId': this.textureId + } + } + emitter.emit(innerEvent, eventData) + } + addEventlisener() { + let innerEvent: emitter.InnerEvent = { eventId: this.textureId as number } + emitter.on(innerEvent, data => { + if (data?.data?.type === 'action') { + switch (data?.data?.pagPlayState) { + case _nativeStart: + this.viewController.play(); + break; + case _nativeStop: + this.viewController.setProgress(0); + this.viewController.pause(); + break; + case _nativePause: + this.viewController.pause(); + break; + case _nativeSetProgress: + this.viewController.setProgress(data?.data?.progress); + break; + case _nativeRelease: + this.show = false; + this.viewController.freeCache(); + break; + case _nativeGetPointLayer: + let innerEvent: emitter.InnerEvent = { eventId: this.textureId as number } + let layerNames:Array = []; + let layers = this.viewController.getLayersUnderPoint(data?.data?.x, data?.data?.y); + layers.forEach(item => { + layerNames.push(item.layerName()); + }) + let eventData: emitter.EventData = { + data: { + 'type': _nativeGetPointLayer, + 'list': layerNames + } + } + emitter.emit(innerEvent, eventData) + break; + } + } + }) + } + build() { + Column() { + if (this.show) { + PAGView({ + controller: this.viewController + }) + } + }.alignItems(HorizontalAlign.Center) + .justifyContent(FlexAlign.Center) + .direction(Direction.Ltr) + .width('100%') + .height('100%') + } +} + +@Builder +function PagBuilder(params: Params) { + PagComponent({ params: params }) +} + +AppStorage.setOrCreate('config', {}) + +@Observed +export class PagView extends PlatformView implements MethodCallHandler { + type: string = "test"; + textureId: number; + + index: number = 1; + + constructor(context: common.Context, viewId: number, args: ESObject, message: BinaryMessenger) { + super(); + // 注册消息通道 + this.textureId = args as number; + } + onMethodCall() { + + } + getView(): WrappedBuilder<[Params]> { + return new WrappedBuilder(PagBuilder); + } + getTextureId(): number { + return this.textureId; + } + + dispose(): void { + } +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/plugins/GeneratedPluginRegistrant.ets b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/plugins/GeneratedPluginRegistrant.ets new file mode 100644 index 0000000000000000000000000000000000000000..40f130cd4ad66fbe957f382dc9d34c384d33341c --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/ets/io/flutter/plugins/pag/plugins/GeneratedPluginRegistrant.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterEngine, Log } from '@ohos/flutter_ohos'; + +/** + * Generated file. Do not edit. + * This file is generated by the Flutter tool based on the + * plugins that support the Ohos platform. + */ + +const TAG = "GeneratedPluginRegistrant"; + +export class GeneratedPluginRegistrant { + + static registerWith(flutterEngine: FlutterEngine) { + try { + } catch (e) { + Log.e( + TAG, + "Tried to register plugins with FlutterEngine (" + + flutterEngine + + ") failed."); + Log.e(TAG, "Received exception while registering", e); + } + } +} diff --git a/ohos/flutter-pag/ohos/src/main/module.json5 b/ohos/flutter-pag/ohos/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..782197df08328472a983fa61840bf5e9dd9c9a1e --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/module.json5 @@ -0,0 +1,11 @@ +{ + "module": { + "name": "pag", + "type": "har", + "deviceTypes": [ + "default", + "tablet", + "2in1" + ] + } +} diff --git a/ohos/flutter-pag/ohos/src/main/resources/base/element/string.json b/ohos/flutter-pag/ohos/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from package" + } + ] +} diff --git a/ohos/flutter-pag/ohos/src/main/resources/en_US/element/string.json b/ohos/flutter-pag/ohos/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from package" + } + ] +} diff --git a/ohos/flutter-pag/ohos/src/main/resources/zh_CN/element/string.json b/ohos/flutter-pag/ohos/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from package" + } + ] +} diff --git a/ohos/flutter-pag/ohos/src/ohosTest/ets/test/Ability.test.ets b/ohos/flutter-pag/ohos/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..14a4559e82070c2129207f876144e4a7e7d58788 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }) + }) +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/src/ohosTest/ets/test/List.test.ets b/ohos/flutter-pag/ohos/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff8be109c54ec5ef0f149f3f10511951f27b1870 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/src/ohosTest/module.json5 b/ohos/flutter-pag/ohos/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..ca56237defc7f750f58ac9230f969ad3fcf2c432 --- /dev/null +++ b/ohos/flutter-pag/ohos/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "pag_test", + "type": "feature", + "deviceTypes": [ + "default", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/ohos/flutter-pag/ohos/src/test/List.test.ets b/ohos/flutter-pag/ohos/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f43cd6d3fadd0cd4d3659bb1f633679116e4358e --- /dev/null +++ b/ohos/flutter-pag/ohos/src/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/ohos/flutter-pag/ohos/src/test/LocalUnit.test.ets b/ohos/flutter-pag/ohos/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..3d8b8c548215a817614ac1e7fb1bcc7ef8b6597e --- /dev/null +++ b/ohos/flutter-pag/ohos/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, () => { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/flutter-pag/pubspec.yaml b/ohos/flutter-pag/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..730d16b62dec6b3aa69ed66cf6d924d1f0117c93 --- /dev/null +++ b/ohos/flutter-pag/pubspec.yaml @@ -0,0 +1,79 @@ +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: pag +description: PAG for flutter +version: 1.0.4 +homepage: https://github.com/libpag/pag-flutter + +environment: + sdk: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # This section identifies this Flutter project as a plugin project. + # The 'pluginClass' and Android 'package' identifiers should not ordinarily + # be modified. They are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + platforms: + android: + package: com.example.flutter_pag_plugin + pluginClass: FlutterPagPlugin + ios: + pluginClass: FlutterPagPlugin + ohos: + pluginClass: FlutterPagPlugin + + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # To add custom fonts to your plugin package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages