diff --git a/.gitignore b/.gitignore index 021b06b..31f01ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ *.iml .gradle /local.properties -/gradle.properties /.idea/workspace.xml /.idea/libraries .DS_Store diff --git a/.travis.yml b/.travis.yml index 9b077fa..011fcb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,35 @@ -sudo: false - language: android jdk: oraclejdk8 android: components: - - - tools - - - build-tools-23.0.2 - - android-24 - # support lib + - tools # to get the new `repository-11.xml` + - tools # see https://github.com/travis-ci/travis-ci/issues/6040#issuecomment-219367943) + - platform-tools + - build-tools-26.0.2 + - android-26 + - extra-google-m2repository - extra-android-m2repository - - extra-android-support + licenses: + - android-sdk-license-.+ + - android-sdk-preview-license-.+ + - google-gdk-license-.+ + +# Emulator Management: Create, Start and Wait +before_script: + - echo no | android create avd --force -n test -t android-26 --abi armeabi-v7a + - emulator -avd test -no-audio -no-window & + - touch bintray.properties script: - - ./gradlew clean assembleRelease --stacktrace + - android-wait-for-emulator + - adb shell input keyevent 82 -before_install: - - chmod +x gradlew +notifications: + email: + - gudong.name@gmail.com +# +#cache: +# directories: +# - $HOME/.m2 +# - $HOME/.gradle \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0cc58a5 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ + +##License + + Copyright (C) 2015 GuDong + + This file is part of GdTranslate + + GdTranslate is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GdTranslate is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GdTranslate. If not, see . diff --git a/README.md b/README.md index c671149..1f40b9a 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,16 @@ -#咕咚翻译 +# 咕咚翻译 ![icon](/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png "") [![Build Status](https://travis-ci.org/maoruibin/TranslateApp.svg?branch=master)](https://travis-ci.org/maoruibin/TranslateApp) -##介绍 +## 介绍 一个实现『划词翻译』功能的 Android 应用 ,可能是目前 Android 市场上翻译效率最高的一款应用。 -![shot](http://7xr9gx.com1.z0.glb.clouddn.com/gd.gif) +![shot](https://upload-images.jianshu.io/upload_images/588640-bb21211def7c14a3.gif?imageMogr2/auto-orient/strip|imageView2/2/w/393/format/webp) -## 待完成功能 -* 单词显示框支持沉浸式,覆盖状态栏显示。 -* 单词发音 -* 使用 Github 做自动更新 -* 不支持谷歌翻译,如果有人有兴趣添加谷歌,必应翻译,欢迎PR。 -* ~~显示单词信息时增加音标~~ -* ~~生词本为空时的提示信息~~ -`Note:`想要参与贡献代码的同学,请在 develop 分支上操作,欢迎参与,可以提前在 issue 中交流自己要修改的功能模块,同时也欢迎来[Google+社区](https://plus.google.com/u/1/communities/111919086388322816251)一起讨论 咕咚翻译。 -##下载 +## 下载 @@ -28,7 +20,7 @@ 如果想要帮助做内部测试,[欢迎来Google+社区](https://plus.google.com/u/1/communities/111919086388322816251)我会把最新的版本放在 Google+社区。 -##缘起 +## 缘起 自己经常在手机上会阅读一些英文的技术 blog 或者文档,经常会遇到陌生的单词,想必大家都有类似的经历,一般的,如果是上班期间,我可能会打开谷歌翻译,然后查词,但是当你不在电脑旁,就只能通过手机上的翻译软件来翻译生词,所以这时我们通常遇到生词会这样操作,长按生词、选择复制、点击 Home 键、找到翻译 App,有道翻译或者谷歌翻译之类的,然后长按输入框,选择粘贴,此时你才可以看到那个生词的意思。其实这是一个非常考验用户耐性的事,连续操作几次,不烦才怪呢。 我也是,自己以前在 Medium 上阅读文章时经常做这样的事,后来我想能不能简单点呢,所以就有了咕咚翻译这个 App,咕咚是我的网名呢~ @@ -43,70 +35,51 @@ V2EX 上对 App 的讨论 [咕咚翻译](https://www.v2ex.com/t/259288#reply69) Google+ [咕咚翻译社群](https://plus.google.com/u/1/communities/111919086388322816251) -## 已知 Bug -* ~~查词时,输入框下面应该会显示"查词中...",目前不能显示出来~~ -* 连续两次复制单词,程序奔溃。 -* 在本应用外收藏成功单词后,没有成功提示 ## 技术点 * 1、全程使用 [Dagger2](https://github.com/google/dagger) 对项目进行类依赖管理 * 2、项目使用标准的 MVP 架构,[关于 MVP 的一篇博客](http://gudong.name/advanced/2015/11/23/gank_mvp_introduce.html) * 3、实现对粘贴板的监听以及访问 -* 4、无需权限显示悬浮窗 -* 5、[RxJava](https://github.com/ReactiveX/RxJava) 的使用 +* 4、无需权限显示悬浮窗(6.0悬浮窗权限适配) +* 5、使用 [RxJava](https://github.com/ReactiveX/RxJava) 探索函数式编程 * 6、使用 [Retrofit2](https://github.com/square/retrofit) 进行网络请求 * 7、开机自启动 -* 8、泛型 +* 8、Android 6.0 [自定义文本操作栏](http://www.jianshu.com/p/40e84359d683) -`Note` 3、4都是借鉴自[廖祜秋](https://github.com/liaohuqiu/)的开源项目[android-UCToast](https://github.com/liaohuqiu/android-UCToast),感谢~ - -## 更新日志 - -### V1.3.5 -* 增加每日一句 +`Note` 3、4都是借鉴自[廖祜秋](https://github.com/liaohuqiu/)的开源项目[android-UCToast](https://github.com/liaohuqiu/android-UCToast),感谢~ -### V1.0.0 +## 适配问题 -* 设计: 首页大改版,使用 MaterialDesign 样式重新设计了首页。Thanks @TonyLOfficial(03-05) -* 新增: 划词翻译开关,你可以关闭划词翻译功能了。(03-04) -* 新增: 首页支持灵活的翻译引擎切换(03-07) -* 新增: 长按翻译结果区域,可以选择复制(03-07) -* 更新: 关闭长按句子可以翻译长句的功能。但是主界面支持句子翻译,仅限百度翻译。(03-07) -* 优化: 点击翻译按钮后,让翻译按钮不可用(03-09) -* 优化: 在咕咚翻译主界面,长按复制文本,不再会弹出顶部提示框(03-07) -* 优化: 单词本被移动到了 Toolbar 上面展示。(03-05) -* 更新: 支持 Android 4.1及以上的版本 (03-05) -* 修复: 翻译时不显示 "翻译中" 的提示问题,Thanks @leizhiyuan。(03-04) -* 优化: 单词本为空时显示一个为空提示语,Thanks @leizhiyuan。(03-04) -* 修复: 点击清除按钮后,还可以点击收藏 (03-05) +- [Android 8.0系统上使用WindowManager添加view的一个问题](https://juejin.im/entry/5a3a0ca75188257d391d30ac) -### V0.6.3 +## 更新日志 +[日志列表](./doc/Changelog.md) -* 新增: 划词翻译开关,你可以关闭划词翻译功能了。(03-04) -* 优化: 单词本被移动到了 Toolbar 上面展示。(03-05) -* 修复: 翻译时不显示 "翻译中" 的提示问题,Thanks @leizhiyuan。(03-04) +## 支持一下 +* [去捐赠打赏](http://gudong.name/vdonate/) +* [已捐赠记录](http://gudong.name/1990/03/01/list_pay.html) -### V0.6 +## 贡献者 -* 大幅提高定时设置的稳定性,可以在首页灵活设置显示开关,以及显示间隔时间等。 -* 加入 [Once](https://github.com/jonfinerty/Once) 库用于简化一些一次性操作 -* 加入了 BugHd 作为 bug 统计工具 -* 使用 MVP 对项目进行重构 -* 使用 Dagger2 进行依赖管理 +* [70kg \(70kg\)](https://github.com/70kg) +* [kymjs \(张涛\)](https://github.com/kymjs) +* [leizhiyuan \(Lei Zhiyuan\)](https://github.com/leizhiyuan) +* [LevineLiu \(LevineLiu\)](https://github.com/LevineLiu) +* [LostKe](https://github.com/LostKe) +* [WonShaw \(万宵\)](https://github.com/WonShaw) ## 关于作者 -咕咚,爱折腾、爱新鲜,爱篮球。 - -[个人站点](http://gudong.name/) - -[github](https://github.com/maoruibin) +咕咚,软件工程师,[更多](http://gudong.name/about)。 -[微博](http://weibo.com/u/1874136301) +* 公众号:咕咚同学 +* [个人站点](http://gudong.name) +* [github](https://github.com/maoruibin) +* [微博](http://weibo.com/u/1874136301) -##License +## License Copyright (C) 2015 GuDong diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 90056fd..7d0830c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,19 +1,22 @@ -apply plugin: 'com.android.application' -apply plugin: 'com.neenbedankt.android-apt' -apply plugin: 'me.tatarka.retrolambda' -apply plugin:'im.fir.plugin.gradle' +buildscript { + repositories { + maven { url 'https://maven.fabric.io/public' } + } -fir{ - apiToken '15e5206706b555384608e449d6def6d3' - changeLog '* add upload plugin for fir\n' + - '* add changelog file' + dependencies { + classpath 'io.fabric.tools:gradle:1.22.2' + } } +apply plugin: 'com.android.application' +apply plugin: 'io.fabric' -bughd{ - projectId '56d30214a1de52062800000e' - apiToken 'e244dc781dd8455c9e6e04b62e1328a0' +repositories { + maven { url 'https://maven.fabric.io/public' } } +apply plugin: 'com.neenbedankt.android-apt' +apply plugin: 'me.tatarka.retrolambda' + //格式化打完完成后APK名称中的时间 def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC+8")) @@ -39,8 +42,8 @@ android { vectorDrawables.useSupportLibrary = true //baidu config - buildConfigField "String", "BAIDU_SCREAT_KEY", '"5jlBZtaMuo6Xlx5LOIVC"' - buildConfigField "String", "BAIDU_APP_ID", '"20151224000008231"' + buildConfigField "String", "BAIDU_SCREAT_KEY", '""' + buildConfigField "String", "BAIDU_APP_ID", '""' //iciba config buildConfigField "String", "ICIBA_KEY", '"8B660C51C6D4A410DE9D406667729BC4"' @@ -52,12 +55,18 @@ android { buildConfigField "String", "YOUDAO_DOC_TYPE", '"json"' buildConfigField "String", "YOUDAO_VERSION", '"1.2"' + //google config + buildConfigField "String", "GOOGLE_LANGUAGE_ENGLISH", '"en"' + buildConfigField "String", "GOOGLE_LANGUAGE_CHINEASE", '"zh-CN"' + //common value buildConfigField "String", "RESULT_JSON", '"json"' buildConfigField "String", "LANGUAGE_AUTO", '"auto"' buildConfigField "Boolean", "IS_DEBUG", 'true' resValue "string", "tray__authority", "${cfg.package}.tray" + + buildConfigField "Boolean", "IS_ADVANCE", 'false' } signingConfigs { @@ -118,6 +127,11 @@ android { manifestPlaceholders = [UMENG_CHANNEL_VALUE: "dev21"] minSdkVersion cfg.minSdk21 } + //高级用户 + advance { + manifestPlaceholders = [UMENG_CHANNEL_VALUE: "self"] + buildConfigField "Boolean", "IS_ADVANCE", 'true' + } } compileOptions { @@ -128,7 +142,7 @@ android { //set release sign info synchronously def Properties props = new Properties() -def propFile = file('../gradle.properties') +def propFile = file('../local.properties') if (propFile.exists()) { props.load(new FileInputStream(propFile)) if (props != null && @@ -150,8 +164,8 @@ if (propFile.exists()) { dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') - compile files('libs/Bughd_android_sdk_v1.3.7.jar') // Test + compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile "junit:junit:${test.junit}" // Android compile "com.android.support:recyclerview-v7:${libs.supportVersion}" @@ -184,13 +198,41 @@ dependencies { compile "com.jenzz:materialpreference:${libs.materialpreference}" compile "com.github.bumptech.glide:glide:${libs.glide}" - compile ("me.drakeet.library:crashwoodpecker:${libs.crashwoodpecker}"){ + compile("me.drakeet.library:crashwoodpecker:${libs.crashwoodpecker}") { exclude module: 'recyclerview-v7' } - compile project(":headsupcompat") - compile 'net.grandcentrix.tray:tray:0.11.0' + compile "com.readystatesoftware.sqliteasset:sqliteassethelper:${libs.sqliteassethelper}" + + compile "net.grandcentrix.tray:tray:${libs.tray}" + + compile "com.facebook.stetho:stetho:${libs.stetho}" + compile "com.facebook.stetho:stetho-okhttp3:${libs.stetho_okhttp3}" + + compile('me.drakeet.support:about:2.0.2', { + exclude module: 'recyclerview-v7' + exclude module: 'appcompat-v7' + exclude module: 'design' + }) + compile('me.drakeet.multitype:multitype:3.3.3', { + exclude module: 'recyclerview-v7' + exclude module: 'appcompat-v7' + exclude module: 'design' + }) + +// compile ('me.drakeet.support:about-extension:2.0.2', { +// exclude module: 'recyclerview-v7' +// exclude module: 'appcompat-v7' +// exclude module: 'design' +// }) + compile 'com.squareup.picasso:picasso:2.5.2' + compile('com.crashlytics.sdk.android:crashlytics:2.8.0@aar') { + transitive = true; + } + compile('com.crashlytics.sdk.android:answers:1.4.1@aar') { + transitive = true; + } - compile 'com.facebook.stetho:stetho:1.4.2' - compile 'com.facebook.stetho:stetho-okhttp3:1.4.2' -} \ No newline at end of file + compile 'com.github.anzewei:parallaxbacklayout:1.1.9' + compile 'com.airbnb.android:lottie:2.1.0' +} diff --git a/app/fabric.properties b/app/fabric.properties new file mode 100644 index 0000000..c43ace6 --- /dev/null +++ b/app/fabric.properties @@ -0,0 +1,3 @@ +#Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public. +#Sat Feb 03 20:00:56 CST 2018 +apiSecret=2ad97b261aef0185addafa7c358ed28499ebddd6e7b2932f4da6c06e95b0f4ba diff --git a/app/libs/Bughd_android_sdk_v1.3.7.jar b/app/libs/Bughd_android_sdk_v1.3.7.jar deleted file mode 100644 index 5a96211..0000000 Binary files a/app/libs/Bughd_android_sdk_v1.3.7.jar and /dev/null differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 41c98d4..a4e49d1 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -120,4 +120,11 @@ -keep class name.gudong.translate.mvp.model.entity.** {*;} +-dontwarn com.squareup.okhttp.** +-dontwarn com.bumptech.glide.** + +-keep public enum com.github.anzewei.parallaxbacklayout.ParallaxBack$** { + **[] $VALUES; + public *; +} \ No newline at end of file diff --git a/app/src/beta/res/menu/main.xml b/app/src/beta/res/menu/main.xml index 4951d6f..67fdc22 100644 --- a/app/src/beta/res/menu/main.xml +++ b/app/src/beta/res/menu/main.xml @@ -34,64 +34,9 @@ android:title="@string/favorite_list"/> - - - - - - - - - - - - - - - - - - - - - - - + android:title="@string/hist_record"/> - - + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6c5d543..5e957db 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,20 +1,20 @@ + package="name.gudong.translate"> - + - - - + + + - - - - + + + + + android:value="56a45cd9e0f55add0d002d49"/> + android:value="${UMENG_CHANNEL_VALUE}"/> + android:value="60641333d73c37d9db66465ab8f78cc9"/> - - + + - - - + + + + + - - - + - + @@ -69,25 +71,25 @@ android:enabled="true" android:exported="false"> - + - - - + + + - - - - - + + + + + - - - - - + diff --git a/app/src/main/assets/about.html b/app/src/main/assets/about.html index fc5906c..bf2383a 100644 --- a/app/src/main/assets/about.html +++ b/app/src/main/assets/about.html @@ -53,23 +53,27 @@ 咕咚设计开发完成
个人主页   微博   - 知乎   + 知乎   Github  

特别感谢
chenyingsunny   辅助开发
- TonyLOfficial      图标设计
+ TonyLOfficial      图标设计

意见反馈:发邮件给我

+

+查看历史日志 +

如果你喜欢咕咚翻译,也许你还会喜欢我的其他作品。

    -
  1. AppPlus一个可以用于传送、提取APK文件等的工具软件。
  2. -
  3. GankDaily 干货客户端,用于查看每天的技术干货
  4. +
  5. 易剪一个 Android 手机上的剪报助手。
  6. +
  7. AppPlus一个可以用于传送、提取APK文件等的工具软件。
  8. +
  9. GankDaily 干货客户端,用于查看每天的技术干货
\ No newline at end of file diff --git a/app/src/main/assets/about_float_translate.html b/app/src/main/assets/about_float_translate.html new file mode 100644 index 0000000..f6adb9e --- /dev/null +++ b/app/src/main/assets/about_float_translate.html @@ -0,0 +1,38 @@ + + + + + + +

+

划词翻译是我开发这个 APP 的初衷,什么叫划词翻译呢?

+

当你在其他软件中长按复制英文单词后,咕咚翻译会自动获取到你复制的单词,然后查询网络释义,最终直观的显示在手机顶部。

+

从而告别繁杂的查询流程, 比如你在浏览中遇到一个不认识的单词,可以像如下图所示的方式进行快速查词。

+ + 咕咚 + + + \ No newline at end of file diff --git a/app/src/main/assets/changelog.html b/app/src/main/assets/changelog.html index 7b6e6b2..086dde4 100644 --- a/app/src/main/assets/changelog.html +++ b/app/src/main/assets/changelog.html @@ -48,24 +48,20 @@ 咕咚翻译 - 一个实现手机端『划词翻译』功能的 App,可能是目前 Android 市场上翻译效率最高的应用。

-

Version 1.3.6

+

Version 1.8.0

    -
  1. 优化: 为 6.0 设备增加悬浮窗权限申请,解决 MIUI 等部分设备需要手动开启权限的问题
  2. -
  3. 新增: 单词数据备份、恢复(2017-02-05)
  4. -
  5. 新增: 咕咚翻译可以背收藏的生词了,好词就应该死里记(10-01)
  6. -
  7. 新增: 咕咚翻译中可以看到每日一句了(10-07)
  8. -
  9. 新增: 适配 Android M 增加快捷查词(10-06)
  10. -
  11. 新增: 支持手势滑动删除悬浮窗(10-03)
  12. -
  13. 变更: 调换设置与单词本的位置(10-17)
  14. -
  15. 优化: 循环翻译顺序,锁屏停止循环(10-12)
  16. -
  17. 优化: 添加点击按钮的动画(10-04)
  18. -
  19. 优化: 循环显示背单词列表(10-04)
  20. -
  21. 修复: Android N 发音奔溃问题(10-04)
  22. -
  23. 修复: 增加悬浮窗点击事件(10-06)
  24. -
  25. 优化: 首页 menu 中可以查看版本信息了(10-07)
  26. +
  27. 增加: 历史记录,记录所有查询过的单词
  28. +
  29. 增加: 设置增加了控制联想输入的开关
  30. +
  31. 优化: 返回操作增加手势返回,类似微信的滑动返回体验
  32. +
  33. 优化: 连续翻译同一个单词时,不重复发送请求
  34. +
  35. 优化: 关于页面增加开发者介绍以及优化打开速度
+

+ 查看历史日志 +

+

获取咕咚翻译的最近动态,可通过以下方式关注

微博  @大侠咕咚
Github  @GuDong
diff --git a/app/src/main/assets/databases/sample_oxford.zip b/app/src/main/assets/databases/sample_oxford.zip new file mode 100644 index 0000000..2536d68 Binary files /dev/null and b/app/src/main/assets/databases/sample_oxford.zip differ diff --git a/app/src/main/assets/donate_ch.html b/app/src/main/assets/donate_ch.html index 1a23171..cdbd60f 100644 --- a/app/src/main/assets/donate_ch.html +++ b/app/src/main/assets/donate_ch.html @@ -46,5 +46,6 @@ 点击下面的按钮 打开支付宝,即可转账打赏,再次感谢你的支持。

-更多关于捐赠者的话 +咕咚翻译捐赠名单 +更多关于捐赠者的话 \ No newline at end of file diff --git a/app/src/main/assets/lottie/new_year_fire.json b/app/src/main/assets/lottie/new_year_fire.json new file mode 100644 index 0000000..52597b6 --- /dev/null +++ b/app/src/main/assets/lottie/new_year_fire.json @@ -0,0 +1 @@ +{"v":"4.12.2","fr":60,"ip":1,"op":91,"w":600,"h":600,"nm":"合成 1","ddd":0,"assets":[{"id":"comp_5","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[-686,294]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.996078431373,0.866666666667,0.003921568627,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995986519608,0.377431263643,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"形状 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"\r 10 合成 2","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"\r 10 合成 2","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":30,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"\r 10 合成 2","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":330,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"\r 10 合成 2","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"\r 10 合成 2","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":210,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"\r 10 合成 2","refId":"comp_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":150,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"\r 10 合成 1","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"\r 10 合成 1","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"\r 10 合成 1","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"\r 10 合成 1","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"\r 10 合成 1","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"\r 10 合成 1","refId":"comp_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"\r 11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":-0.002,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[0]},{"t":22}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,432,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"n":"0_1_0_0","t":0,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[22.081,-0.526],[20.579,0.956],[19.085,-0.538],[20.579,-2.032]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}]},{"i":{"x":0.253,"y":1},"o":{"x":0.465,"y":0},"n":"0p253_1_0p465_0","t":7,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.519],[-2.239,0.968],[-3.727,-0.519],[-2.239,-2.007]],"c":true}]},{"t":22}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995986519608,0.377431263643,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.69,"y":0.623},"o":{"x":0.371,"y":0},"n":"0p69_0p623_0p371_0","t":0,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.282,"y":1},"o":{"x":0.154,"y":0.095},"n":"0p282_1_0p154_0p095","t":7,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":23}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"形状图层 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[30],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[0]},{"t":28}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300.031,0],"ix":2},"a":{"a":0,"k":[2,-22,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[4,4],"e":[31,31]},{"t":27}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.996078431373,0.376470588235,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[7],"e":[0]},{"t":27}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.043,-22],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_6","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[100],"e":[0]},{"t":44}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":29,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-3.252,-0.061],[-4.739,1.427],[-6.227,-0.061],[-4.739,-1.548]],"c":true}]},{"t":44}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995986519608,0.377431263643,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.882},"o":{"x":0.099,"y":0.231},"n":"0p98_0p882_0p099_0p231","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.523,"y":1},"o":{"x":0.066,"y":0.098},"n":"0p523_1_0p066_0p098","t":29,"s":[-2,0.016],"e":[-10,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":44}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_7","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[100],"e":[0]},{"t":54}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":25,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.061],[-2.239,1.427],[-3.727,-0.061],[-2.239,-1.548]],"c":true}]},{"t":37}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995986519608,0.865933107862,0.004409307592,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.913},"o":{"x":0.099,"y":0.169},"n":"0p98_0p913_0p099_0p169","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0,"y":1},"o":{"x":0.066,"y":0.203},"n":"0_1_0p066_0p203","t":25,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_8","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"\r 10 合成 5","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"\r 10 合成 5","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"\r 10 合成 5","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"\r 10 合成 5","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"\r 10 合成 5","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"\r 10 合成 5","refId":"comp_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"\r 10 合成 6","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"\r 10 合成 6","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":210,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"\r 10 合成 6","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":150,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"\r 10 合成 6","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"\r 10 合成 6","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":30,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"\r 10 合成 6","refId":"comp_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":330,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"\r 12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":-0.002,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[0]},{"t":22}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,432,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"n":"0_1_0_0","t":0,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[22.081,-0.526],[20.579,0.956],[19.085,-0.538],[20.579,-2.032]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}]},{"i":{"x":0.253,"y":1},"o":{"x":0.465,"y":0},"n":"0p253_1_0p465_0","t":7,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.519],[-2.239,0.968],[-3.727,-0.519],[-2.239,-2.007]],"c":true}]},{"t":22}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.737254901961,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.69,"y":0.623},"o":{"x":0.371,"y":0},"n":"0p69_0p623_0p371_0","t":0,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.282,"y":1},"o":{"x":0.154,"y":0.095},"n":"0p282_1_0p154_0p095","t":7,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":23}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"形状图层 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[30],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[0]},{"t":28}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300.031,0],"ix":2},"a":{"a":0,"k":[2,-22,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[4,4],"e":[31,31]},{"t":27}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.996078431373,0.737254901961,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[7],"e":[0]},{"t":27}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.043,-22],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_9","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[100],"e":[0]},{"t":54}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":25,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.061],[-2.239,1.427],[-3.727,-0.061],[-2.239,-1.548]],"c":true}]},{"t":37}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.925490196078,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.913},"o":{"x":0.099,"y":0.169},"n":"0p98_0p913_0p099_0p169","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0,"y":1},"o":{"x":0.066,"y":0.203},"n":"0_1_0p066_0p203","t":25,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_10","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[100],"e":[0]},{"t":44}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":29,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-3.252,-0.061],[-4.739,1.427],[-6.227,-0.061],[-4.739,-1.548]],"c":true}]},{"t":44}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.737254901961,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.882},"o":{"x":0.099,"y":0.231},"n":"0p98_0p882_0p099_0p231","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.523,"y":1},"o":{"x":0.066,"y":0.098},"n":"0p523_1_0p066_0p098","t":29,"s":[-2,0.016],"e":[-10,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":44}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_11","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"\r 10 合成 7","refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"\r 10 合成 7","refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"\r 10 合成 7","refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"\r 10 合成 7","refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"\r 10 合成 7","refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"\r 10 合成 7","refId":"comp_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"\r 10 合成 8","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":330,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"\r 10 合成 8","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"\r 10 合成 8","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":210,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"\r 10 合成 8","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":150,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"\r 10 合成 8","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"\r 10 合成 8","refId":"comp_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":30,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"\r 12","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":-0.002,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[0]},{"t":22}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,432,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"n":"0_1_0_0","t":0,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[22.081,-0.526],[20.579,0.956],[19.085,-0.538],[20.579,-2.032]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}]},{"i":{"x":0.253,"y":1},"o":{"x":0.465,"y":0},"n":"0p253_1_0p465_0","t":7,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.519],[-2.239,0.968],[-3.727,-0.519],[-2.239,-2.007]],"c":true}]},{"t":22}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.866666666667,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.69,"y":0.623},"o":{"x":0.371,"y":0},"n":"0p69_0p623_0p371_0","t":0,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.282,"y":1},"o":{"x":0.154,"y":0.095},"n":"0p282_1_0p154_0p095","t":7,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":23}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"形状图层 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[30],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[0]},{"t":28}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300.031,0],"ix":2},"a":{"a":0,"k":[2,-22,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[4,4],"e":[31,31]},{"t":27}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.866666666667,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[7],"e":[0]},{"t":27}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.043,-22],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_12","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[100],"e":[0]},{"t":54}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":25,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.061],[-2.239,1.427],[-3.727,-0.061],[-2.239,-1.548]],"c":true}]},{"t":37}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.925490196078,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.913},"o":{"x":0.099,"y":0.169},"n":"0p98_0p913_0p099_0p169","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0,"y":1},"o":{"x":0.066,"y":0.203},"n":"0_1_0p066_0p203","t":25,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_13","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[100],"e":[0]},{"t":44}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":29,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-3.252,-0.061],[-4.739,1.427],[-6.227,-0.061],[-4.739,-1.548]],"c":true}]},{"t":44}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.866666666667,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.882},"o":{"x":0.099,"y":0.231},"n":"0p98_0p882_0p099_0p231","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.523,"y":1},"o":{"x":0.066,"y":0.098},"n":"0p523_1_0p066_0p098","t":29,"s":[-2,0.016],"e":[-10,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":44}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_14","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"\r 10 合成 3","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"\r 10 合成 3","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"\r 10 合成 3","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"\r 10 合成 3","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"\r 10 合成 3","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"\r 10 合成 3","refId":"comp_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[150,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":300,"h":50,"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"\r 10 合成 4","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":330,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"\r 10 合成 4","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"\r 10 合成 4","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":210,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"\r 10 合成 4","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":150,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":11,"ty":0,"nm":"\r 10 合成 4","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":12,"ty":0,"nm":"\r 10 合成 4","refId":"comp_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":30,"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[200,25,0],"ix":1},"s":{"a":0,"k":[80,80,100],"ix":6}},"ao":0,"w":400,"h":50,"ip":8,"op":308,"st":8,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"\r 11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":-0.002,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[100],"e":[0]},{"t":22}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[300,432,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0,"y":0},"n":"0_1_0_0","t":0,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[22.081,-0.526],[20.579,0.956],[19.085,-0.538],[20.579,-2.032]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}]},{"i":{"x":0.253,"y":1},"o":{"x":0.465,"y":0},"n":"0p253_1_0p465_0","t":7,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[19.352,-0.519],[-7.527,0.961],[-9.014,-0.526],[-7.527,-2.014]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.519],[-2.239,0.968],[-3.727,-0.519],[-2.239,-2.007]],"c":true}]},{"t":22}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.580392156863,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.69,"y":0.623},"o":{"x":0.371,"y":0},"n":"0p69_0p623_0p371_0","t":0,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.282,"y":1},"o":{"x":0.154,"y":0.095},"n":"0p282_1_0p154_0p095","t":7,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":23}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"形状图层 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":15,"s":[0],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[30],"e":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":27,"s":[30],"e":[0]},{"t":28}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,300.031,0],"ix":2},"a":{"a":0,"k":[2,-22,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":16,"s":[4,4],"e":[31,31]},{"t":27}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"椭圆路径 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.996078431373,0.580392156863,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":16,"s":[7],"e":[0]},{"t":27}],"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[2.043,-22],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"椭圆 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_15","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":47,"s":[100],"e":[0]},{"t":54}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[150,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":25,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-7.527,1.451],[-9.014,-0.036],[-7.527,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-0.752,-0.061],[-2.239,1.427],[-3.727,-0.061],[-2.239,-1.548]],"c":true}]},{"t":37}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.995986519608,0.92439994064,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.913},"o":{"x":0.099,"y":0.169},"n":"0p98_0p913_0p099_0p169","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0,"y":1},"o":{"x":0.066,"y":0.203},"n":"0_1_0p066_0p203","t":25,"s":[-2,0.016],"e":[-11,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":60}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]},{"id":"comp_16","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"\r 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":13.998,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":14.998,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[100],"e":[0]},{"t":44}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[200,25,0],"ix":2},"a":{"a":0,"k":[9,0,0],"ix":1},"s":{"a":0,"k":[600,600,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.429,"y":0.602},"o":{"x":0,"y":0},"n":"0p429_0p602_0_0","t":15,"s":[{"i":[[0,-0.825],[0,0],[0,0.825],[-0.825,0]],"o":[[0,0.825],[-0.825,0],[0,-0.825],[0,0]],"v":[[6.223,-0.047],[1.406,1.436],[-0.088,-0.058],[1.406,-1.552]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}]},{"i":{"x":0.562,"y":1},"o":{"x":0,"y":0},"n":"0p562_1_0_0","t":29,"s":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[5.602,-0.03],[-12.693,1.451],[-14.181,-0.036],[-12.693,-1.524]],"c":true}],"e":[{"i":[[0,-0.821],[0,0],[0,0.821],[-0.821,0]],"o":[[0,0.821],[-0.821,0],[0,-0.821],[0,0]],"v":[[-3.252,-0.061],[-4.739,1.427],[-6.227,-0.061],[-4.739,-1.548]],"c":true}]},{"t":44}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078431373,0.580392156863,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.98,"y":0.882},"o":{"x":0.099,"y":0.231},"n":"0p98_0p882_0p099_0p231","t":14,"s":[0,0.016],"e":[-2,0.016],"to":[-0.13495451211929,0],"ti":[0.20861637592316,0]},{"i":{"x":0.523,"y":1},"o":{"x":0.066,"y":0.098},"n":"0p523_1_0p066_0p098","t":29,"s":[-2,0.016],"e":[-10,0.016],"to":[-1.85248684883118,0],"ti":[1.19837880134583,0]},{"t":44}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[300,312,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[-1112,552]],"c":false},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.909696691176,0.253288119447,0.085618509031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.278431372549,0.094117647059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"形状 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"“乐”轮廓","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":45,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":48,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[100],"e":[0]},{"t":90}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[306,476,0],"ix":2},"a":{"a":0,"k":[77,-56,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.496,0.496,0.833],"y":[0.966,0.966,-1.648]},"o":{"x":[0.175,0.175,0.167],"y":[0.325,0.325,2.648]},"n":["0p496_0p966_0p175_0p325","0p496_0p966_0p175_0p325","0p833_-1p648_0p167_2p648"],"t":45,"s":[23,23,100],"e":[94,94,100]},{"i":{"x":[0.836,0.836,0.833],"y":[1,1,0.854]},"o":{"x":[0.198,0.198,0.167],"y":[0.153,0.153,0.146]},"n":["0p836_1_0p198_0p153","0p836_1_0p198_0p153","0p833_0p854_0p167_0p146"],"t":57,"s":[94,94,100],"e":[109,109,100]},{"t":90}],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.712,-3.263],[1.63,-1.783],[2.701,-0.509],[4.078,0.612],[0,0],[-1.989,-0.562],[-2.754,1.427],[-2.245,2.089],[-1.683,3.366],[-0.971,4.796],[0,6.632],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-6.529,0.409],[-6.426,0.765],[-6.07,0.971],[-5.202,1.224],[-0.256,0.971],[1.018,1.021],[0,0],[4.843,-1.836],[5.252,-1.63],[5.558,-1.377],[5.608,-1.018],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,4.896],[-0.715,3.266],[-1.633,1.786],[-2.704,0.512],[0,0],[1.427,1.733],[1.989,0.559],[2.548,-1.224],[2.242,-2.092],[1.683,-3.366],[0.968,-4.793],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6.22,-0.1],[6.526,-0.406],[6.426,-0.765],[6.067,-0.968],[1.836,-0.203],[0.253,-0.968],[0,0],[-4.184,1.836],[-4.846,1.836],[-5.255,1.633],[-5.561,1.377],[0,0],[0,0],[0,0]],"v":[[28.305,-120.105],[23.256,-52.02],[44.676,-50.643],[45.288,-57.681],[70.533,-57.681],[70.533,-32.436],[69.462,-20.196],[65.943,-12.622],[59.441,-9.18],[49.266,-9.333],[61.812,6.426],[66.938,9.868],[74.052,8.568],[81.243,3.596],[87.134,-4.59],[91.112,-16.83],[92.565,-33.966],[92.565,-57.681],[138.771,-57.681],[130.968,-70.38],[124.848,-64.566],[92.565,-64.566],[92.565,-84.303],[100.062,-89.352],[70.533,-92.718],[70.533,-64.566],[45.747,-64.566],[48.654,-101.439],[67.779,-102.204],[87.21,-103.964],[105.953,-106.564],[122.859,-109.854],[125.996,-111.614],[124.848,-114.597],[110.925,-126.531],[97.385,-121.023],[82.238,-115.821],[66.02,-111.308],[49.266,-107.712],[49.419,-111.231],[57.222,-115.821]],"c":true},"ix":2},"nm":"乐 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-4.184,2.042],[-4.131,2.807],[-3.725,3.366],[-2.654,3.469],[0.406,0.971],[1.018,0.512],[0,0],[4.59,-7.853],[5.202,-6.017]],"o":[[4.181,-2.039],[4.131,-2.804],[3.722,-3.366],[1.121,-1.427],[-0.409,-0.968],[0,0],[-3.366,8.568],[-4.59,7.856],[3.466,-0.918]],"v":[[21.114,-3.213],[33.583,-10.48],[45.365,-19.737],[54.927,-29.988],[55.998,-33.583],[53.856,-35.802],[36.261,-44.217],[24.327,-19.584],[9.639,1.224]],"c":true},"ix":2},"nm":"乐 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[1.224,2.704],[3.672,3.06],[5.661,3.163],[6.832,2.754],[-2.195,-3.569],[-2.092,-4.078],[-1.889,-4.334],[-1.53,-3.978]],"o":[[1.936,-1.63],[-1.224,-2.701],[-3.672,-3.06],[-5.661,-3.16],[2.039,2.654],[2.192,3.572],[2.089,4.081],[1.886,4.337],[0,0]],"v":[[141.066,-9.18],[142.137,-15.683],[134.793,-24.327],[120.794,-33.66],[102.051,-42.534],[108.401,-33.201],[114.827,-21.726],[120.794,-9.104],[125.919,3.366]],"c":true},"ix":2},"nm":"乐 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.278431372549,0.094117647059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[0.909696691176,0.253288119447,0.085618509031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"描边 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":45,"op":165,"st":45,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"“快”轮廓","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[100],"e":[0]},{"t":90}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[371,314,0],"ix":2},"a":{"a":0,"k":[77,-56,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.496,0.496,0.833],"y":[0.966,0.966,-1.648]},"o":{"x":[0.175,0.175,0.167],"y":[0.325,0.325,2.648]},"n":["0p496_0p966_0p175_0p325","0p496_0p966_0p175_0p325","0p833_-1p648_0p167_2p648"],"t":40,"s":[23,23,100],"e":[94,94,100]},{"i":{"x":[0.836,0.836,0.833],"y":[1,1,0.832]},"o":{"x":[0.198,0.198,0.167],"y":[0.177,0.177,0.168]},"n":["0p836_1_0p198_0p177","0p836_1_0p198_0p177","0p833_0p832_0p167_0p168"],"t":52,"s":[94,94,100],"e":[109,109,100]},{"t":90}],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.153,-2.539],[0.203,-2.336],[0,0],[0,0],[0,0],[13.77,-14.994],[-4.552,3.213],[-3.887,4.234],[-3.07,5.255],[-1.944,6.426],[-1.707,-4.896],[-2.142,-4.384],[-2.398,-3.519],[-2.448,-2.142],[-1.377,-0.153],[-1.633,1.733],[0,0],[4.078,2.601],[3.619,3.316],[3.06,3.825],[2.142,3.978],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,2.642],[-0.153,2.539],[0,0],[0,0],[0,0],[-3.06,23.053],[4.805,-2.348],[4.552,-3.213],[3.887,-4.231],[3.07,-5.252],[1.195,4.896],[1.707,4.896],[2.142,4.387],[2.395,3.519],[1.733,1.427],[1.377,0.153],[0,0],[-4.284,-1.63],[-4.081,-2.601],[-3.622,-3.313],[-3.06,-3.825],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[131.427,-89.632],[136.782,-97.277],[114.073,-104.346],[110.724,-98.838],[101.316,-98.838],[101.166,-91.198],[109.985,-91.426],[109.928,-54.765],[100.08,-54.769],[100.974,-62.49],[101.189,-91.366],[101.286,-98.838],[101.286,-118.314],[107.253,-123.947],[79.254,-126.837],[79.254,-98.838],[65.484,-98.838],[69.003,-91.341],[79.254,-91.341],[79.254,-69.859],[79.025,-62.087],[78.489,-54.774],[56.763,-54.774],[60.741,-47.277],[77.877,-47.277],[52.632,9.792],[66.67,1.454],[79.328,-9.715],[89.761,-23.945],[97.279,-41.463],[101.633,-26.775],[107.406,-12.852],[114.215,-0.995],[121.482,7.497],[126.149,9.868],[130.662,7.497],[144.585,-9.639],[132.039,-15.989],[120.488,-24.863],[110.466,-35.573],[102.663,-47.277],[145.044,-47.277],[137.547,-62.271],[131.733,-54.774],[131.427,-54.774]],"c":true},"ix":2},"nm":"快 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-0.715,-9.28],[0,0],[2.548,3.619],[6.629,4.081],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[1.936,7.141],[0,0],[1.53,-1.733],[-2.551,-3.619],[0,0],[0,0],[0,0],[0,0]],"v":[[27.54,9.78],[48.348,9.78],[48.348,-91.965],[52.326,-67.332],[63.648,-82.173],[62.118,-90.203],[48.348,-101.755],[48.348,-118.271],[54.468,-123.318],[27.54,-126.531]],"c":true},"ix":2},"nm":"快 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[-1.224,1.53],[-0.818,4.184],[0,6.632],[1.324,8.568],[1.018,-3.06],[1.171,-2.448],[1.427,-2.089],[1.836,-1.936]],"o":[[1.121,1.633],[1.224,-1.53],[0.815,-4.181],[0,-6.629],[-0.918,3.978],[-1.021,3.06],[-1.174,2.448],[-1.43,2.092],[0,0]],"v":[[17.136,-48.597],[20.655,-48.444],[23.715,-57.012],[24.939,-73.23],[22.95,-96.027],[20.043,-85.47],[16.753,-77.208],[12.852,-70.399],[7.956,-64.356]],"c":true},"ix":2},"nm":"快 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.278431372549,0.094117647059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[0.909696691176,0.253288119447,0.085618509031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"描边 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":40,"op":160,"st":40,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"“春”轮廓","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":35,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":38,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[100],"e":[0]},{"t":90}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[213,280,0],"ix":2},"a":{"a":0,"k":[77,-56,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.496,0.496,0.833],"y":[0.966,0.966,-1.648]},"o":{"x":[0.175,0.175,0.167],"y":[0.325,0.325,2.648]},"n":["0p496_0p966_0p175_0p325","0p496_0p966_0p175_0p325","0p833_-1p648_0p167_2p648"],"t":35,"s":[23,23,100],"e":[94,94,100]},{"i":{"x":[0.836,0.836,0.833],"y":[1,1,0.809]},"o":{"x":[0.198,0.198,0.167],"y":[0.2,0.2,0.191]},"n":["0p836_1_0p198_0p2","0p836_1_0p198_0p2","0p833_0p809_0p167_0p191"],"t":47,"s":[94,94,100],"e":[109,109,100]},{"t":90}],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[-0.868,1.989],[-0.818,2.142],[0,0],[0,0],[0,0],[0,0],[0,0],[0.918,1.174],[2.345,0.512],[0,0],[1.324,-4.996],[0,0],[0,0],[0,0],[1.501,-3.772],[0,0],[0,0],[0,0],[1.028,-2.089],[1.234,-2.039],[0,0],[0,0],[0,0],[14.176,-10.81],[-4.54,2.295],[-4.284,2.654],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.377,-1.121],[-1.327,-0.918],[-1.377,0.409],[-1.021,1.633],[0,0],[6.373,2.195],[5.711,3.672],[0,0],[-4.337,-3.684],[0,0],[0,0],[0,0],[0,0],[6.447,0.808],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.754,4.796]],"o":[[0,0],[0,0],[0,0],[1.018,-1.836],[0.865,-1.989],[0,0],[0,0],[0,0],[0,0],[0,0],[0.712,-2.345],[-0.918,-1.171],[0,0],[-1.124,5.714],[0,0],[0,0],[0,0],[-1.205,4.184],[0,0],[0,0],[0,0],[-1.028,2.245],[-1.028,2.092],[0,0],[0,0],[0,0],[-8.702,13.364],[4.996,-2.039],[4.537,-2.295],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.427,1.327],[1.377,1.124],[2.548,1.736],[1.377,-0.406],[0,0],[-7.956,-1.018],[-6.376,-2.192],[0,0],[0,0],[-4.563,-1.29],[0,0],[0,0],[0,0],[0,0],[4.745,-2.857],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[2.754,-3.672],[0,0]],"v":[[123.318,-84.915],[115.821,-97.614],[109.395,-91.8],[80.172,-91.8],[83.003,-97.538],[85.527,-103.734],[131.733,-103.734],[124.236,-116.433],[117.963,-110.619],[87.975,-110.619],[89.811,-115.821],[89.505,-121.1],[84.609,-123.624],[66.402,-126.684],[62.73,-110.619],[18.972,-110.619],[22.491,-103.734],[60.741,-103.734],[56.682,-91.8],[27.662,-91.8],[31.181,-84.915],[53.825,-84.915],[50.743,-78.413],[47.354,-72.216],[12.9,-72.216],[16.572,-65.331],[43.041,-65.331],[8.721,-29.07],[23.027,-35.573],[36.261,-42.993],[36.261,9.945],[58.293,9.945],[58.293,3.366],[58.153,-18.361],[58.284,-40.48],[93.23,-40.611],[92.952,-25.323],[58.288,-25.221],[58.153,-18.361],[93.491,-18.361],[93.301,-3.532],[58.295,-3.719],[58.676,3.366],[93.177,3.366],[93.177,9.945],[115.209,9.945],[115.209,-39.474],[116.433,-41.769],[120.641,-38.097],[124.695,-35.037],[130.586,-33.048],[134.181,-36.108],[144.738,-51.714],[123.242,-56.534],[105.111,-65.331],[96.147,-65.314],[108.656,-49.737],[96.371,-53.682],[92.702,-47.629],[58.299,-47.646],[64.677,-52.51],[51.052,-54.19],[62.62,-65.355],[96.109,-65.331],[105.14,-65.331],[140.454,-65.331],[132.651,-78.03],[126.531,-72.216],[68.391,-72.216],[76.653,-84.915]],"c":true},"ix":2},"nm":"春 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.278431372549,0.094117647059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[0.909696691176,0.253288119447,0.085618509031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":1,"lj":1,"ml":4,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"st","c":{"a":0,"k":[0.909696691176,0.253288119447,0.085618509031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"描边 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":35,"op":155,"st":35,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"“新”轮廓","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":30,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":33,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":77,"s":[100],"e":[0]},{"t":90}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[294,124,0],"ix":2},"a":{"a":0,"k":[77,-56,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.496,0.496,0.833],"y":[0.966,0.966,-1.648]},"o":{"x":[0.175,0.175,0.167],"y":[0.325,0.325,2.648]},"n":["0p496_0p966_0p175_0p325","0p496_0p966_0p175_0p325","0p833_-1p648_0p167_2p648"],"t":30,"s":[23,23,100],"e":[94,94,100]},{"i":{"x":[0.836,0.836,0.833],"y":[1,1,0.787]},"o":{"x":[0.198,0.198,0.167],"y":[0.223,0.223,0.213]},"n":["0p836_1_0p198_0p223","0p836_1_0p198_0p223","0p833_0p787_0p167_0p213"],"t":42,"s":[94,94,100],"e":[109,109,100]},{"t":90}],"ix":6}},"ao":0,"shapes":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[2.242,-11.831],[5.711,-10.607],[-6.579,12.699],[0,16.424],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-3.519,0.306],[-3.419,0.512],[-2.907,0.665],[-1.633,0.612],[-0.206,0.715],[0.815,0.818],[0,0],[2.089,-1.683],[1.989,-1.274],[2.039,-1.018],[2.345,-0.918],[0,0]],"o":[[0,0],[0,0],[0,12.649],[-2.245,11.834],[11.116,-7.856],[6.579,-12.699],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[2.957,0],[3.519,-0.306],[3.416,-0.509],[2.907,-0.662],[0.815,-0.406],[0.203,-0.712],[0,0],[-2.551,2.142],[-2.092,1.683],[-1.989,1.277],[-2.042,1.021],[0,0],[0,0]],"v":[[111.996,-115.821],[85.374,-119.646],[85.374,-60.435],[82.008,-23.715],[70.074,9.945],[96.62,-20.885],[106.488,-64.566],[106.488,-70.074],[113.985,-70.074],[113.985,9.945],[135.711,9.945],[135.711,-70.074],[145.044,-70.074],[137.547,-82.773],[131.121,-76.959],[106.488,-76.959],[106.488,-103.581],[116.204,-104.04],[126.608,-105.264],[136.094,-107.024],[142.902,-108.936],[144.432,-110.619],[143.514,-112.914],[132.192,-124.848],[125.231,-119.111],[119.111,-114.674],[113.067,-111.231],[106.488,-108.324],[106.488,-111.843]],"c":true},"ix":2},"nm":"新 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.509,-2.192],[1.071,-1.324],[1.53,-0.509],[2.039,0],[0,0],[-1.583,-0.359],[-2.348,0.918],[-1.736,1.886],[-1.224,2.601],[-0.715,3.163],[0,3.366],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-3.519,2.96],[-1.836,2.654],[0.1,0.868],[0.918,0.306],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.121,1.683],[2.957,1.53],[4.284,1.021],[4.487,-0.1],[-1.939,-3.672],[-1.43,-4.181],[0,0],[0,0],[0,0],[0.559,-2.295],[0.662,-2.448],[0.765,-2.395],[0.815,-2.039],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,3.266],[-0.512,2.195],[-1.071,1.327],[-1.53,0.512],[0,0],[1.427,1.936],[1.58,0.356],[2.142,-0.818],[1.733,-1.889],[1.224,-2.601],[0.712,-3.16],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[4.181,-2.448],[3.519,-2.957],[0.712,-0.918],[-0.103,-0.865],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.63,-1.121],[-1.124,-1.683],[-2.96,-1.53],[-4.284,-1.018],[2.039,2.245],[1.936,3.672],[0,0],[0,0],[0,0],[-0.306,1.836],[-0.562,2.295],[-0.665,2.448],[-0.765,2.398],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[35.037,-23.103],[34.272,-14.918],[31.9,-9.639],[27.999,-6.885],[22.644,-6.12],[31.824,6.12],[36.338,9.562],[42.228,8.721],[48.042,4.667],[52.479,-2.066],[55.386,-10.71],[56.457,-20.502],[56.457,-42.075],[79.866,-42.075],[72.216,-54.774],[66.096,-48.96],[56.457,-48.96],[56.457,-64.872],[82.62,-64.872],[74.97,-77.571],[68.697,-71.757],[54.774,-71.757],[66.326,-79.866],[74.358,-88.281],[75.276,-90.959],[73.746,-92.718],[59.211,-98.991],[79.866,-98.991],[72.369,-111.537],[66.096,-105.876],[50.49,-105.876],[59.976,-112.302],[60.741,-116.51],[54.621,-121.329],[43.758,-125.154],[30.6,-126.531],[36.567,-117.657],[41.616,-105.876],[10.557,-105.876],[14.076,-98.991],[55.08,-98.991],[53.779,-92.795],[51.943,-85.68],[49.801,-78.413],[47.43,-71.757],[7.956,-71.757],[11.475,-64.872],[35.037,-64.872],[35.037,-48.96],[10.71,-48.96],[14.229,-42.075],[35.037,-42.075]],"c":true},"ix":2},"nm":"新 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[1.936,0.818],[0,0],[0.509,-3.875],[0.612,-3.875],[0.712,-3.619],[0.815,-2.96],[-2.348,2.548],[-2.142,2.907],[-1.786,3.213],[-1.224,3.266]],"o":[[0,0],[-0.306,3.572],[-0.512,3.878],[-0.612,3.878],[-0.715,3.622],[2.345,-2.042],[2.345,-2.548],[2.142,-2.907],[1.783,-3.213],[0.918,-2.754]],"v":[[30.6,-34.119],[15.147,-38.709],[13.923,-27.54],[12.24,-15.912],[10.251,-4.667],[7.956,5.202],[14.994,-1.683],[21.726,-9.868],[27.617,-19.049],[32.13,-28.764]],"c":true},"ix":2},"nm":"新 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[0.406,1.889],[1.936,2.042],[3.16,1.989],[3.672,1.633],[-0.715,-5.608],[-0.409,-5.814]],"o":[[1.836,-1.324],[-0.409,-1.886],[-1.939,-2.039],[-3.163,-1.989],[1.836,4.796],[0.712,5.611],[0,0]],"v":[[77.112,-16.218],[79.254,-21.038],[75.735,-26.928],[68.085,-32.971],[57.834,-38.403],[61.659,-22.797],[63.342,-5.661]],"c":true},"ix":2},"nm":"新 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[0.05,1.53],[1.733,1.736],[3.569,1.633],[5.608,1.124],[-1.124,-4.231],[-0.306,-5.508]],"o":[[1.53,-0.815],[-0.053,-1.53],[-1.736,-1.733],[-3.572,-1.63],[1.733,2.96],[1.121,4.234],[0,0]],"v":[[41.157,-80.325],[43.376,-83.844],[40.698,-88.74],[32.742,-93.789],[18.972,-97.92],[23.256,-87.134],[25.398,-72.522]],"c":true},"ix":2},"nm":"新 6","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.278431372549,0.094117647059,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[0.909696691176,0.253288119447,0.085618509031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3,"ix":5},"lc":2,"lj":2,"nm":"描边 2","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":30,"op":150,"st":30,"bm":0},{"ddd":0,"ind":14,"ty":0,"nm":"合成 5","refId":"comp_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[306,472,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":15,"op":315,"st":15,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"合成 3","refId":"comp_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":25,"ix":10},"p":{"a":0,"k":[372,314,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":10,"op":310,"st":10,"bm":0},{"ddd":0,"ind":16,"ty":0,"nm":"合成 2","refId":"comp_11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-23,"ix":10},"p":{"a":0,"k":[212,282,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":5,"op":305,"st":5,"bm":0},{"ddd":0,"ind":17,"ty":0,"nm":"合成 4","refId":"comp_14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[292,122,0],"ix":2},"a":{"a":0,"k":[300,300,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":600,"h":600,"ip":0,"op":300,"st":0,"bm":0}]} \ No newline at end of file diff --git a/app/src/main/java/name/gudong/translate/GDApplication.java b/app/src/main/java/name/gudong/translate/GDApplication.java index 4350149..9a8b1a9 100644 --- a/app/src/main/java/name/gudong/translate/GDApplication.java +++ b/app/src/main/java/name/gudong/translate/GDApplication.java @@ -24,11 +24,13 @@ import android.content.Context; import android.support.v7.app.AppCompatDelegate; +import com.crashlytics.android.Crashlytics; import com.facebook.stetho.Stetho; +import com.github.anzewei.parallaxbacklayout.ParallaxHelper; import com.orhanobut.logger.LogLevel; import com.orhanobut.logger.Logger; -import im.fir.sdk.FIR; +import io.fabric.sdk.android.Fabric; import jonathanfinerty.once.Once; import me.drakeet.library.CrashWoodpecker; import me.drakeet.library.PatchMode; @@ -48,10 +50,10 @@ public class GDApplication extends Application { @Override public void onCreate() { super.onCreate(); + Fabric.with(this, new Crashlytics()); AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); mContext = this; setUpSomethingsByDevMode(BuildConfig.IS_DEBUG); - FIR.init(this); Once.initialise(this); mAppComponent = DaggerAppComponent.builder() .appModule(new AppModule(this)) @@ -60,11 +62,13 @@ public void onCreate() { initCrashWoodpecker(); Stetho.initializeWithDefaults(this); + + registerActivityLifecycleCallbacks(ParallaxHelper.getInstance()); } private void initCrashWoodpecker() { CrashWoodpecker.instance() - .withKeys("widget", "me.drakeet") + .withKeys("widget", "name.gudong") .setPatchMode(PatchMode.SHOW_LOG_PAGE) .setPatchDialogUrlToOpen("http://gudong.name") .setPassToOriginalDefaultHandler(true) diff --git a/app/src/main/java/name/gudong/translate/injection/components/ActivityComponent.java b/app/src/main/java/name/gudong/translate/injection/components/ActivityComponent.java index 02641e9..71573f1 100644 --- a/app/src/main/java/name/gudong/translate/injection/components/ActivityComponent.java +++ b/app/src/main/java/name/gudong/translate/injection/components/ActivityComponent.java @@ -24,6 +24,7 @@ import name.gudong.translate.listener.ListenClipboardService; import name.gudong.translate.injection.ActivityScope; import name.gudong.translate.injection.modules.ActivityModule; +import name.gudong.translate.ui.activitys.AboutActivity; import name.gudong.translate.ui.activitys.MainActivity; import name.gudong.translate.ui.activitys.ProcessTextActivity; import name.gudong.translate.ui.activitys.WordsBookActivity; @@ -36,6 +37,7 @@ @Component(modules = {ActivityModule.class},dependencies = {AppComponent.class}) public interface ActivityComponent { void inject(MainActivity activity); + void inject(AboutActivity activity); void inject(WordsBookActivity activity); void inject(ProcessTextActivity activity); void inject(ListenClipboardService service); diff --git a/app/src/main/java/name/gudong/translate/injection/components/AppComponent.java b/app/src/main/java/name/gudong/translate/injection/components/AppComponent.java index b730db6..5fbed9e 100644 --- a/app/src/main/java/name/gudong/translate/injection/components/AppComponent.java +++ b/app/src/main/java/name/gudong/translate/injection/components/AppComponent.java @@ -27,6 +27,7 @@ import dagger.Component; import name.gudong.translate.GDApplication; import name.gudong.translate.mvp.model.ApiBaidu; +import name.gudong.translate.mvp.model.ApiGoogle; import name.gudong.translate.mvp.model.ApiJinShan; import name.gudong.translate.mvp.model.ApiYouDao; import name.gudong.translate.mvp.model.SingleRequestService; @@ -37,6 +38,8 @@ /** * Created by GuDong on 12/27/15 16:41. * Contact with gudong.name@gmail.com. + * + * Updated by Levine on 2/21/17 add google api */ @Singleton @Component(modules = {AppModule.class,ApiServiceModel.class}) @@ -54,6 +57,8 @@ public interface AppComponent { ApiBaidu getApiBaidu(); + ApiGoogle getApiGoogle(); + SingleRequestService getDwnloadService(); } diff --git a/app/src/main/java/name/gudong/translate/injection/modules/ApiServiceModel.java b/app/src/main/java/name/gudong/translate/injection/modules/ApiServiceModel.java index 38121a2..00bb042 100644 --- a/app/src/main/java/name/gudong/translate/injection/modules/ApiServiceModel.java +++ b/app/src/main/java/name/gudong/translate/injection/modules/ApiServiceModel.java @@ -23,18 +23,27 @@ import com.facebook.stetho.okhttp3.StethoInterceptor; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + import javax.inject.Singleton; import dagger.Module; import dagger.Provides; import name.gudong.translate.BuildConfig; +import name.gudong.translate.GDApplication; import name.gudong.translate.mvp.model.ApiBaidu; +import name.gudong.translate.mvp.model.ApiGoogle; import name.gudong.translate.mvp.model.ApiJinShan; import name.gudong.translate.mvp.model.ApiYouDao; import name.gudong.translate.mvp.model.SingleRequestService; import name.gudong.translate.mvp.model.type.ETranslateFrom; +import okhttp3.Cache; import okhttp3.HttpUrl; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; @@ -43,6 +52,8 @@ /** * Created by GuDong on 12/27/15 16:17. * Contact with gudong.name@gmail.com. + * + * Updated by Levine on 2/21/17 add google api */ @Module public class ApiServiceModel { @@ -76,6 +87,10 @@ ApiJinShan provideApiJinShan() { return createService(ETranslateFrom.JIN_SHAN); } + @Provides + @Singleton + ApiGoogle provideApiGoogle(){return createService(ETranslateFrom.GOOGLE);} + private S createService(ETranslateFrom type) { Retrofit.Builder builder = new Retrofit.Builder() .baseUrl(HttpUrl.parse(type.getUrl())) @@ -89,10 +104,30 @@ private S createService(ETranslateFrom type) { @Provides @Singleton OkHttpClient provideOkHttpClient() { + Cache cache = new Cache(GDApplication.get().getCacheDir(), 10240 * 1024); + OkHttpClient.Builder builder = new OkHttpClient.Builder(); if (BuildConfig.DEBUG) { builder.addNetworkInterceptor(new StethoInterceptor()); } + builder.addNetworkInterceptor(new CacheInterceptor()) + .cache(cache) + .connectTimeout(20, TimeUnit.SECONDS) + .readTimeout(20, TimeUnit.SECONDS); return builder.build(); } + + private class CacheInterceptor implements Interceptor { + @Override + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + Response response = chain.proceed(request); + return response.newBuilder() + .removeHeader("Pragma") + .removeHeader("Cache-Control") + //cache for 30 days + .header("Cache-Control", "max-age=" + 3600 * 24 * 30) + .build(); + } + } } diff --git a/app/src/main/java/name/gudong/translate/listener/AlarmReceiver.java b/app/src/main/java/name/gudong/translate/listener/AlarmReceiver.java deleted file mode 100644 index 1f1cd49..0000000 --- a/app/src/main/java/name/gudong/translate/listener/AlarmReceiver.java +++ /dev/null @@ -1,32 +0,0 @@ -package name.gudong.translate.listener; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import name.gudong.translate.R; -import name.gudong.translate.ui.activitys.MainActivity; -import name.gudong.translate.util.HeadsUps; -import name.gudong.translate.util.SpUtils; - - -/** - * Created by drakeet on 7/1/15. - */ -public class AlarmReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - if (SpUtils.isNotifyDayline(context)) { - Intent target = new Intent(context, MainActivity.class); - target.putExtra("from_dayline_remind",true); - HeadsUps.show(context, target, - context.getString(R.string.app_name), - "还没有查看今天的每日一句吧,我已经准备好了。", - R.mipmap.ic_launcher, - R.drawable.icon_notification, - 123123); - } - - } -} diff --git a/app/src/main/java/name/gudong/translate/listener/ListenClipboardService.java b/app/src/main/java/name/gudong/translate/listener/ListenClipboardService.java index 8c0d390..f2af4c0 100755 --- a/app/src/main/java/name/gudong/translate/listener/ListenClipboardService.java +++ b/app/src/main/java/name/gudong/translate/listener/ListenClipboardService.java @@ -24,12 +24,15 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; +import android.app.Activity; import android.app.Service; +import android.app.job.JobScheduler; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.support.v4.content.WakefulBroadcastReceiver; import android.view.View; @@ -49,6 +52,7 @@ import name.gudong.translate.mvp.presenters.BasePresenter; import name.gudong.translate.mvp.presenters.ClipboardPresenter; import name.gudong.translate.mvp.views.ITipFloatView; +import name.gudong.translate.util.AnswerUtil; public final class ListenClipboardService extends Service implements ITipFloatView, TipView.ITipViewListener { @@ -60,8 +64,6 @@ public final class ListenClipboardService extends Service implements ITipFloatVi BroadcastReceiver mScreenStatusReceive; - - @Override public void onCreate() { setUpInject(); @@ -95,9 +97,15 @@ public void onReceive(Context context, Intent intent) { registerReceiver(mScreenStatusReceive, screenStateFilter); } - private void unregisterScreenReceiver(){ - if(mScreenStatusReceive != null){ - unregisterReceiver(mScreenStatusReceive); + private void unregisterScreenReceiver() { + if (mScreenStatusReceive != null) { + try { + //反复开启背单词开关并关闭mainActivity,再快速打开mainActivity,打开背单词开关,再关闭mainActivity + //Service在onStart时,上一次的广播Receiver还没来得及注册,这一次就unRegister + //造成广播未注册就解注册,crash + unregisterReceiver(mScreenStatusReceive); + } catch (IllegalArgumentException e) { + } } } @@ -199,6 +207,7 @@ public void initWithNotFavorite(Result result) { @Override public void onClickFavorite(View view, Result result) { MobclickAgent.onEvent(this, "favorite_service"); + AnswerUtil.actionFavorite("listenClipboard"); mPresenter.startFavoriteAnim(view, new BasePresenter.AnimationEndListener() { @Override public void onAnimationEnd(Animator animation) { @@ -209,7 +218,7 @@ public void onAnimationEnd(Animator animation) { @Override public void onClickPlaySound(View view, Result result) { - MobclickAgent.onEvent(this, "sound_service"); + AnswerUtil.actionSound("listenClipboard"); mPresenter.playSound(result.getMp3FileName(),result.getEnMp3()); mPresenter.startSoundAnim(view); } @@ -281,4 +290,4 @@ public ListenClipboardService getService(){ return ListenClipboardService.this; } } -} \ No newline at end of file +} diff --git a/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java b/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java index f749529..ce2250f 100755 --- a/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java +++ b/app/src/main/java/name/gudong/translate/listener/view/TipViewController.java @@ -47,15 +47,18 @@ import name.gudong.translate.util.Utils; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; import rx.functions.Func1; -public class TipViewController{ +import static name.gudong.translate.mvp.presenters.MainPresenter.KEY_REQUEST_CODE_FOR_NOTI; + +public class TipViewController { private WindowManager mWindowManager; private Context mContext; /** * cache mul tip view */ - private MapmMapTipView = new WeakHashMap<>(); + private Map mMapTipView = new WeakHashMap<>(); private Observable mHideTipTask; @@ -67,7 +70,11 @@ public TipViewController(Context application) { mRecitePreference = new ReciteModulePreference(mContext); } - public void showErrorInfo(String error,TipView.ITipViewListener mListener){ + public void showErrorInfo(String error, TipView.ITipViewListener mListener) { + if (!Utils.checkDrawOverlaysPermissionGranted(mContext)) { + Logger.i("No DrawOverlays Permission, end translation operation"); + return; + } TipView tipView = new TipView(mContext); tipView.setListener(mListener); mWindowManager.addView(tipView, getPopViewParams()); @@ -78,7 +85,7 @@ public void showErrorInfo(String error,TipView.ITipViewListener mListener){ private void closeTipViewCountdown(final TipView tipView, TipView.ITipViewListener mListener) { int duration = mRecitePreference.getDurationTimeWay().getDurationTime(); - Logger.t("recite").d(duration+"秒消失"); + Logger.t("recite").d(duration + "秒消失"); mHideTipTask = Observable.timer(duration, TimeUnit.SECONDS, AndroidSchedulers.mainThread()) .map(new Func1() { @Override @@ -93,21 +100,35 @@ public void onCloseAnimEnd(Animator animation) { return null; } }); - mHideTipTask.subscribe(); + mHideTipTask.subscribe(new Action1() { + @Override + public void call(Object o) { + + } + }, new Action1() { + @Override + public void call(Throwable throwable) { + + } + }); } - private void removeTipViewInner(TipView tipView){ - if(tipView.getParent() != null){ + protected class ReciteException extends Exception{ + + } + + private void removeTipViewInner(TipView tipView) { + if (tipView.getParent() != null) { mWindowManager.removeView(tipView); } } - public void show(Result result,boolean isShowFavoriteButton,boolean isShowDoneMark,TipView.ITipViewListener mListener) { + public void show(Result result, boolean isShowFavoriteButton, boolean isShowDoneMark, TipView.ITipViewListener mListener) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); - boolean isSettingUseSystemNotification = sharedPreferences.getBoolean("preference_show_float_view_use_system",false); - if(Utils.isSDKHigh5() && isSettingUseSystemNotification){ + boolean isSettingUseSystemNotification = sharedPreferences.getBoolean("preference_show_float_view_use_system", false); + if (Utils.isSDKHigh5() && isSettingUseSystemNotification) { StringBuilder sb = new StringBuilder(); - for(String string:result.getExplains()){ + for (String string : result.getExplains()) { sb.append(string).append("\n"); } @@ -124,49 +145,52 @@ public void show(Result result,boolean isShowFavoriteButton,boolean isShowDoneMa NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); // Moves events into the big view - for (String string:result.getExplains()) { + for (String string : result.getExplains()) { inboxStyle.addLine(string); } mBuilder.setStyle(inboxStyle); Intent resultIntent = new Intent(mContext, MainActivity.class); - resultIntent.putExtra("data",result); + resultIntent.putExtra("data", result); PendingIntent resultPendingIntent = PendingIntent.getActivity( - mContext, - 0, - resultIntent, - PendingIntent.FLAG_UPDATE_CURRENT - ); + mContext, + KEY_REQUEST_CODE_FOR_NOTI, + resultIntent, + PendingIntent.FLAG_UPDATE_CURRENT + ); - - mBuilder.addAction(R.drawable.ic_favorite_border_grey_24dp,"收藏",resultPendingIntent); + mBuilder.addAction(R.drawable.ic_favorite_border_grey_24dp, "收藏", resultPendingIntent); NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); Notification note = mBuilder.build(); mNotificationManager.notify(result.getQuery().hashCode(), note); - }else{ + } else { + if (!Utils.checkDrawOverlaysPermissionGranted(mContext)) { + Logger.i("No DrawOverlays Permission, end translation operation"); + return; + } TipView tipView = new TipView(mContext); - mMapTipView.put(result,tipView); + mMapTipView.put(result, tipView); tipView.setListener(mListener); mWindowManager.addView(tipView, getPopViewParams()); tipView.startWithAnim(); - tipView.setContent(result, isShowFavoriteButton,isShowDoneMark); - closeTipViewCountdown(tipView,mListener); + tipView.setContent(result, isShowFavoriteButton, isShowDoneMark); + closeTipViewCountdown(tipView, mListener); } } - public void setWithFavorite(Result result){ + public void setWithFavorite(Result result) { TipView tipView = mMapTipView.get(result); - if(tipView != null){ + if (tipView != null) { tipView.setFavoriteBackground(R.drawable.ic_favorite_pink_24dp); } } - public void setWithNotFavorite(Result result){ + public void setWithNotFavorite(Result result) { TipView tipView = mMapTipView.get(result); - if(tipView != null){ + if (tipView != null) { tipView.setFavoriteBackground(R.drawable.ic_favorite_border_white_24dp); } } @@ -178,7 +202,11 @@ private WindowManager.LayoutParams getPopViewParams() { int flags = 0; int type; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.O){ + type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + }else if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.N_MR1){ + type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; + }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { type = WindowManager.LayoutParams.TYPE_TOAST; } else { type = WindowManager.LayoutParams.TYPE_PHONE; @@ -196,13 +224,13 @@ private WindowManager.LayoutParams getPopViewParams() { } public void removeTipView(Result result) { - if(result == null)return; + if (result == null) return; TipView tipView = mMapTipView.get(result); - if(tipView != null){ + if (tipView != null) { Logger.i("移除 tipView "); removeTipViewInner(tipView); } - if(mHideTipTask != null){ + if (mHideTipTask != null) { Logger.i("移除 tipView 对应的 倒计时"); mHideTipTask.unsubscribeOn(AndroidSchedulers.mainThread()); } diff --git a/app/src/main/java/name/gudong/translate/manager/AlarmManagers.java b/app/src/main/java/name/gudong/translate/manager/AlarmManagers.java deleted file mode 100644 index cec9d86..0000000 --- a/app/src/main/java/name/gudong/translate/manager/AlarmManagers.java +++ /dev/null @@ -1,33 +0,0 @@ -package name.gudong.translate.manager; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; - -import java.util.Calendar; - -import name.gudong.translate.listener.AlarmReceiver; - -public class AlarmManagers { - - public static void register(Context context) { - Calendar today = Calendar.getInstance(); - Calendar now = Calendar.getInstance(); - - today.set(Calendar.HOUR_OF_DAY, 7); - today.set(Calendar.MINUTE, 30); - today.set(Calendar.SECOND, 30); - - if (now.after(today)) { - return; - } - - Intent intent = new Intent("name.gudong.translate.alarm"); - intent.setClass(context, AlarmReceiver.class); - PendingIntent broadcast = PendingIntent.getBroadcast(context, 520, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - manager.set(AlarmManager.RTC_WAKEUP, today.getTimeInMillis(), broadcast); - } -} \ No newline at end of file diff --git a/app/src/main/java/name/gudong/translate/manager/ReciteModulePreference.java b/app/src/main/java/name/gudong/translate/manager/ReciteModulePreference.java index 57edfd5..268378e 100644 --- a/app/src/main/java/name/gudong/translate/manager/ReciteModulePreference.java +++ b/app/src/main/java/name/gudong/translate/manager/ReciteModulePreference.java @@ -2,6 +2,8 @@ import android.content.Context; +import com.orhanobut.logger.Logger; + import net.grandcentrix.tray.TrayPreferences; import name.gudong.translate.mvp.model.type.EDurationTipTime; @@ -9,12 +11,15 @@ import static name.gudong.translate.util.SpUtils.KEY_INTERVAL_TIP_TIME; + /** * Created by GuDong on 08/12/2016 00:16. * Contact with gudong.name@gmail.com. */ public class ReciteModulePreference extends TrayPreferences{ + private static final String TAG = "ReciteModulePreference"; + private static final boolean DEFAULT_IS_RECITE = false; //is open JIT translate or not private static final String KEY_OPEN_JIT = "preference_recite_open_jit"; @@ -28,13 +33,19 @@ public class ReciteModulePreference extends TrayPreferences{ private static final String KEY_PREFERENCE_AUTO_PLAY_SOUND = "preference_auto_play_sound"; + /** + * 当前背诵单词的 query + */ + private static final String KEY_CURRENT_CYCLIC = "CURRENT_CYCLIC"; + + public ReciteModulePreference(final Context context) { super(context, "recite", 1); } //是否开启背单词 public boolean isReciteOpenOrNot(){ - return getBoolean(KEY_RECITE_OPEN,true); + return getBoolean(KEY_RECITE_OPEN, DEFAULT_IS_RECITE); } public void setReciteOpenOrNot(boolean isRecite){ @@ -62,10 +73,24 @@ public String getDurationTipTime() { return getString(KEY_DURATION_TIP_TIME,EDurationTipTime.FOUR_SECOND.name()); } + public void setCurrentCyclicWord(String query){ + put(KEY_CURRENT_CYCLIC,query); + Logger.t(TAG).i("put "+query +" suc"); + } + + public String getCurrentCyclicWord(){ + Logger.t(TAG).i("get "+getString(KEY_CURRENT_CYCLIC,"") +" suc"); + return getString(KEY_CURRENT_CYCLIC,""); + } + public EDurationTipTime getDurationTimeWay() { return EDurationTipTime.valueOf(getDurationTipTime()); } + public int getDurationTime() { + return EDurationTipTime.valueOf(getDurationTipTime()).getDurationTime(); + } + public boolean isPlaySoundAuto(){ return getBoolean(KEY_PREFERENCE_AUTO_PLAY_SOUND,false); diff --git a/app/src/main/java/name/gudong/translate/mvp/model/ApiGoogle.java b/app/src/main/java/name/gudong/translate/mvp/model/ApiGoogle.java new file mode 100644 index 0000000..18da254 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/mvp/model/ApiGoogle.java @@ -0,0 +1,26 @@ +package name.gudong.translate.mvp.model; + +import okhttp3.ResponseBody; +import retrofit2.http.GET; +import retrofit2.http.Query; +import retrofit2.http.Streaming; +import rx.Observable; + +/** + * Created on 2017/2/22 + * + * @author Levine + */ + +public interface ApiGoogle { + + /** + * http://translate.google.cn/translate_a/single?client=gtx&sl=en&tl=zh-CN&dt=t&q=google + */ + @Streaming + @GET("translate_a/single?client=gtx&dt=t&ie=UTF-8&oe=UTF-8&sl=auto") + Observable translateGoogle( + @Query("q") String q, + @Query("tl") String targetLanguage + ); +} diff --git a/app/src/main/java/name/gudong/translate/mvp/model/SingleRequestService.java b/app/src/main/java/name/gudong/translate/mvp/model/SingleRequestService.java index 05bb077..5f85463 100644 --- a/app/src/main/java/name/gudong/translate/mvp/model/SingleRequestService.java +++ b/app/src/main/java/name/gudong/translate/mvp/model/SingleRequestService.java @@ -1,5 +1,7 @@ package name.gudong.translate.mvp.model; + +import name.gudong.translate.mvp.model.entity.RecommendedResponse; import name.gudong.translate.mvp.model.entity.dayline.JinshanDayLineEntity; import okhttp3.ResponseBody; import retrofit2.Call; @@ -17,4 +19,7 @@ public interface SingleRequestService { @GET Observable dayline(@Url String daylineUrl); + + @GET + Observable app_recommend(@Url String app_recommend_url); } diff --git a/app/src/main/java/name/gudong/translate/mvp/model/WarpAipService.java b/app/src/main/java/name/gudong/translate/mvp/model/WarpAipService.java index 5eb4998..6d7bd88 100644 --- a/app/src/main/java/name/gudong/translate/mvp/model/WarpAipService.java +++ b/app/src/main/java/name/gudong/translate/mvp/model/WarpAipService.java @@ -20,33 +20,43 @@ package name.gudong.translate.mvp.model; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import javax.inject.Inject; import name.gudong.translate.BuildConfig; import name.gudong.translate.mvp.model.entity.translate.AbsResult; import name.gudong.translate.mvp.model.entity.translate.BaiDuResult; +import name.gudong.translate.mvp.model.entity.translate.GoogleResult; import name.gudong.translate.mvp.model.entity.translate.JinShanResult; import name.gudong.translate.mvp.model.entity.translate.YouDaoResult; import name.gudong.translate.mvp.model.type.ETranslateFrom; import name.gudong.translate.util.SignUtils; +import okhttp3.ResponseBody; import rx.Observable; import rx.functions.Func1; /** * Created by GuDong on 1/22/16 10:37. * Contact with gudong.name@gmail.com. + * + * Updated by Levine on 2/22/17 add google translation */ public class WarpAipService { private ApiBaidu mApiBaidu; private ApiYouDao mApiYouDao; private ApiJinShan mApiJinShan; + private ApiGoogle mApiGoogle; @Inject - public WarpAipService(ApiBaidu mApiBaidu, ApiJinShan mApiJinShan, ApiYouDao mApiYouDao) { + public WarpAipService(ApiBaidu mApiBaidu, ApiJinShan mApiJinShan, ApiYouDao mApiYouDao, ApiGoogle mApiGoogle) { this.mApiBaidu = mApiBaidu; this.mApiJinShan = mApiJinShan; this.mApiYouDao = mApiYouDao; + this.mApiGoogle = mApiGoogle; } public Observable translate(ETranslateFrom way, String query) { @@ -98,6 +108,33 @@ public Observable call(BaiDuResult result) { } }); break; + case GOOGLE: + String targetLanguage; + //String patternWords = "[a-zA-Z1-9 ]{1,}"; + String patternWords = "[\u4e00-\u9fa5 ]{1,}"; + Pattern r = Pattern.compile(patternWords); + Matcher m = r.matcher(query); + if(!m.matches()){ + targetLanguage = BuildConfig.GOOGLE_LANGUAGE_CHINEASE; + } + else { + targetLanguage = BuildConfig.GOOGLE_LANGUAGE_ENGLISH; + } + + resultObservable = mApiGoogle.translateGoogle(query, targetLanguage) + .flatMap(new Func1>() { + @Override + public Observable call(ResponseBody result) { + GoogleResult googleResult = new GoogleResult(); + try{ + googleResult.setTranslationResult(result.string()); + }catch (IOException e){ + e.printStackTrace(); + } + return Observable.just(googleResult); + } + }); + break; } return resultObservable; } diff --git a/app/src/main/java/name/gudong/translate/mvp/model/entity/RecommendedResponse.java b/app/src/main/java/name/gudong/translate/mvp/model/entity/RecommendedResponse.java new file mode 100644 index 0000000..107f1da --- /dev/null +++ b/app/src/main/java/name/gudong/translate/mvp/model/entity/RecommendedResponse.java @@ -0,0 +1,16 @@ +package name.gudong.translate.mvp.model.entity; + +import android.support.annotation.Keep; + +import java.util.List; + +import me.drakeet.support.about.Recommended; + +@Keep +public class RecommendedResponse { + public int code; + public List data; + + public RecommendedResponse() { + } +} diff --git a/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/GoogleResult.java b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/GoogleResult.java new file mode 100644 index 0000000..8144387 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/GoogleResult.java @@ -0,0 +1,105 @@ +package name.gudong.translate.mvp.model.entity.translate; + +import java.util.ArrayList; +import java.util.List; + +import name.gudong.translate.mvp.model.type.ETranslateFrom; + +/** + * Created on 2017/2/21 + * + * @author Levine + */ + +public class GoogleResult extends AbsResult{ + + /** + * [[["谷歌","google",,,1]],,"en"] + */ + private String translationResult; + + private List getTranslation(){ + List translationList = new ArrayList<>(1); + String[] translation = translationResult.replace("[", "").split("\","); + if(translation.length > 0){ + translationList.add(translation[0].replace("\"", "")); + } + return translationList; + } + + private String getQuery(){ + String[] translation = translationResult.replace("[", "").split("\","); + if(translation.length >1){ + return translation[1].replace("\"", ""); + } + return ""; + } + + @Override + public List wrapTranslation() { + return getTranslation(); + } + + @Override + public List wrapExplains() { + return getTranslation(); + } + + @Override + public String wrapQuery() { + return getQuery(); + } + + @Override + public int wrapErrorCode() { + return 0; + } + + @Override + public String wrapEnPhonetic() { + return null; + } + + @Override + public String wrapAmPhonetic() { + return null; + } + + @Override + public String wrapEnMp3() { + return null; + } + + @Override + public String wrapAmMp3() { + return null; + } + + @Override + public String translateFrom() { + return ETranslateFrom.GOOGLE.name(); + } + + @Override + public String wrapPhEn() { + return null; + } + + @Override + public String wrapPhAm() { + return null; + } + + @Override + public String wrapMp3Name() { + return null; + } + + public String getTranslationResult() { + return translationResult; + } + + public void setTranslationResult(String translationResult) { + this.translationResult = translationResult; + } +} diff --git a/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/HistoryResult.java b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/HistoryResult.java new file mode 100644 index 0000000..89212e9 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/HistoryResult.java @@ -0,0 +1,29 @@ +package name.gudong.translate.mvp.model.entity.translate; + +import com.litesuits.orm.db.annotation.Table; + +/** + * author : ruibin1 (ruibin1@staff.weibo.com) + * create : 2018/2/3 - 下午6:45. + */ + +@Table("tb_hist_words") +public class HistoryResult extends Result { + public static HistoryResult toResult(Result entity) { + HistoryResult result = new HistoryResult(); + result.setId(entity.getId()); + result.setQuery(entity.getQuery()); + result.setAmMp3(entity.getAmMp3()); + result.setEnMp3(entity.getEnMp3()); + result.setCreate_time(entity.getCreate_time()); + result.setUpdate_time(entity.getUpdate_time()); + result.setExplains(entity.getExplains()); + result.setMp3FileName(entity.getMp3FileName()); + result.setPhAm(entity.getPhAm()); + result.setPhEn(entity.getPhEn()); + result.setTranslation(entity.getTranslation()); + result.setUkPhonetic(entity.getUkPhonetic()); + result.setUsPhonetic(entity.getUsPhonetic()); + return result; + } +} diff --git a/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java index c3655e8..3ff34d9 100644 --- a/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java +++ b/app/src/main/java/name/gudong/translate/mvp/model/entity/translate/YouDaoResult.java @@ -77,11 +77,13 @@ public String wrapAmPhonetic() { @Override public String wrapEnMp3() { + if(getBasic() == null)return ""; return getBasic().getUkSpeech(); } @Override public String wrapAmMp3() { + if(getBasic() == null)return ""; return getBasic().getUsSpeech(); } diff --git a/app/src/main/java/name/gudong/translate/mvp/model/type/EDurationTipTime.java b/app/src/main/java/name/gudong/translate/mvp/model/type/EDurationTipTime.java index 6935e3b..3a8f20e 100644 --- a/app/src/main/java/name/gudong/translate/mvp/model/type/EDurationTipTime.java +++ b/app/src/main/java/name/gudong/translate/mvp/model/type/EDurationTipTime.java @@ -26,9 +26,10 @@ */ public enum EDurationTipTime { ONE_SECOND(0,2), - FOUR_SECOND(1,4), - SIX_SECOND(2,6), - TEN_SECOND(3,10); + THREE_SECOND(1,3), + FOUR_SECOND(2,4), + SIX_SECOND(3,6), + TEN_SECOND(4,10); private int mIndex; private int mDurationTime; diff --git a/app/src/main/java/name/gudong/translate/mvp/model/type/ETranslateFrom.java b/app/src/main/java/name/gudong/translate/mvp/model/type/ETranslateFrom.java index b016d09..0021e11 100644 --- a/app/src/main/java/name/gudong/translate/mvp/model/type/ETranslateFrom.java +++ b/app/src/main/java/name/gudong/translate/mvp/model/type/ETranslateFrom.java @@ -21,35 +21,35 @@ package name.gudong.translate.mvp.model.type; import name.gudong.translate.mvp.model.ApiBaidu; +import name.gudong.translate.mvp.model.ApiGoogle; import name.gudong.translate.mvp.model.ApiJinShan; import name.gudong.translate.mvp.model.ApiYouDao; /** * Created by GuDong on 1/22/16 18:12. * Contact with gudong.name@gmail.com. + * + * updated by Levine on 2/21/17 */ public enum ETranslateFrom { - BAI_DU(0,"百度","http://api.fanyi.baidu.com/", ApiBaidu.class), - YOU_DAO(1,"有道","http://fanyi.youdao.com/",ApiYouDao.class), - JIN_SHAN(2,"金山","http://dict-co.iciba.com/",ApiJinShan.class); + BAI_DU("百度","http://api.fanyi.baidu.com/", ApiBaidu.class), + YOU_DAO("有道","http://fanyi.youdao.com/",ApiYouDao.class), + JIN_SHAN("金山","http://dict-co.iciba.com/",ApiJinShan.class), + GOOGLE("谷歌", "http://translate.google.cn/",ApiGoogle.class); + private int index; private String name; private String url; private Class aqiClass; - ETranslateFrom(int index,String name,String url, Class aqiClass) { - this.index = index; + ETranslateFrom(String name,String url, Class aqiClass) { this.name = name; this.url = url; this.aqiClass = aqiClass; } - public int getIndex() { - return index; - } - public String getName() { return name; } @@ -61,4 +61,9 @@ public String getUrl() { public Class getAqiClass() { return aqiClass; } + + @Override + public String toString() { + return getName(); + } } diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/AboutPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/AboutPresenter.java new file mode 100644 index 0000000..d9c4605 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/AboutPresenter.java @@ -0,0 +1,97 @@ +package name.gudong.translate.mvp.presenters; + +import android.content.Context; + +import com.litesuits.orm.LiteOrm; + +import java.util.List; + +import javax.inject.Inject; + +import me.drakeet.multitype.Items; +import me.drakeet.support.about.Card; +import me.drakeet.support.about.Category; +import me.drakeet.support.about.Contributor; +import me.drakeet.support.about.License; +import me.drakeet.support.about.Recommended; +import name.gudong.translate.R; +import name.gudong.translate.mvp.model.SingleRequestService; +import name.gudong.translate.mvp.model.WarpAipService; +import name.gudong.translate.mvp.model.entity.RecommendedResponse; +import name.gudong.translate.mvp.views.IAboutView; +import rx.android.schedulers.AndroidSchedulers; +import rx.functions.Action1; +import rx.schedulers.Schedulers; + +/** + * Created by GuDong on 2017/10/25 00:09. + * Contact with gudong.name@gmail.com. + */ + +public class AboutPresenter extends BasePresenter { + @Inject + public AboutPresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestService singleRequestService, Context context) { + super(liteOrm, apiService, singleRequestService, context); + } + + public void getLinkApps(final Items items) { + formatItems(null, items); + if(true){ + //总是超时 先关闭 + return; + } + mSingleRequestService.app_recommend("https://recommend.wetolink.com/api/v2/app_recommend/pull?limit=50&package_name=name.gudong.translate") + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1() { + @Override + public void call(RecommendedResponse apps) { + List appList = apps.data; + formatItems(appList, items); + } + }, new Action1() { + @Override + public void call(Throwable throwable) { + //call onError to stop crashing the app + //TODO error handling + formatItems(null, items); + throwable.printStackTrace(); + } + }); + } + + private void formatItems(List appList, Items items) { + items.add(new Category("介绍与帮助")); + items.add(new Card(getString(R.string.card_content))); + + items.add(new Category("Developers")); + items.add(new Contributor(R.drawable.profile_circle_for_donate, "gudong", "Developer & designer", "http://weibo.com/maoruibin")); + items.add(new Contributor(R.drawable.header, "TonyLOfficial", "designer", "http://weibo.com/u/2795793021")); + items.add(new Contributor(R.drawable.header, "chenyingsunny", "Developer", "https://github.com/chenyingsunny")); + items.add(new Contributor(R.drawable.header, "leizhiyuan", "Developer", "https://github.com/leizhiyuan")); + items.add(new Contributor(R.drawable.zt, "kymjs", "Developer", "https://github.com/kymjs")); + items.add(new Contributor(R.drawable.header, "WonShaw", "Developer", "https://github.com/WonShaw")); + items.add(new Contributor(R.drawable.header, "LevineLiu", "Developer", "https://github.com/LevineLiu")); + items.add(new Contributor(R.drawable.header, "LostKe", "Developer", "https://github.com/LostKe")); + items.add(new Contributor(R.drawable.seven_kg, "70kg", "Developer", "https://github.com/70kg")); + + if (appList != null && !appList.isEmpty()) { + items.add(new Category("应用推荐")); + items.addAll(appList); + } + items.add(new Category("Open Source Licenses")); + items.add(new License("RxJava", "ReactiveX", License.APACHE_2, "https://github.com/ReactiveX/RxJava")); + items.add(new License("RxAndroid", "ReactiveX", License.APACHE_2, "https://github.com/ReactiveX/RxAndroid")); + items.add(new License("Gson", "Google", License.APACHE_2, "https://github.com/google/gson")); + items.add(new License("Retrofit 2", "square", License.APACHE_2, "https://github.com/square/retrofit")); + items.add(new License("Butter Knife", "JakeWharton", License.APACHE_2, "https://github.com/JakeWharton/butterknife")); + items.add(new License("MultiType", "drakeet", License.APACHE_2, "https://github.com/drakeet/MultiType")); + items.add(new License("about-page", "drakeet", License.APACHE_2, "https://github.com/drakeet/about-page")); + + mView.update(); + } + + private String getString(int card_content) { + return mContext.getString(card_content); + } +} diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java index b6905e9..0e97185 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/BasePresenter.java @@ -28,6 +28,7 @@ import android.media.AudioManager; import android.media.MediaPlayer; import android.net.Uri; +import android.text.TextUtils; import android.view.View; import com.litesuits.orm.LiteOrm; @@ -42,8 +43,10 @@ import name.gudong.translate.manager.FileManager; import name.gudong.translate.mvp.model.SingleRequestService; import name.gudong.translate.mvp.model.WarpAipService; +import name.gudong.translate.mvp.model.entity.translate.HistoryResult; import name.gudong.translate.mvp.model.entity.translate.Result; import name.gudong.translate.mvp.views.IBaseView; +import name.gudong.translate.util.AnswerUtil; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; @@ -66,7 +69,7 @@ public class BasePresenter { protected FileManager mFileManager = new FileManager(); - public BasePresenter(LiteOrm liteOrm, WarpAipService apiService,Context context) { + public BasePresenter(LiteOrm liteOrm, WarpAipService apiService, Context context) { mLiteOrm = liteOrm; mWarpApiService = apiService; mContext = context; @@ -79,21 +82,23 @@ public BasePresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestSe mContext = context; } - public void onCreate(){} + public void onCreate() { + } /** * attach IBaseView to Presenter + * * @param view view */ - public void attachView(V view){ + public void attachView(V view) { this.mView = view; } - public void onDestroy(){ + public void onDestroy() { this.mView = null; } - protected Context getContext(){ + protected Context getContext() { return mContext; } @@ -106,73 +111,67 @@ protected Context getContext(){ public Result isFavorite(String word) { QueryBuilder queryBuilder = new QueryBuilder(Result.class); queryBuilder = queryBuilder.whereEquals("query ", word); - Listlist = mLiteOrm.query(queryBuilder); - if(list.isEmpty()){ + List list = mLiteOrm.query(queryBuilder); + if (list.isEmpty()) { return null; } return list.get(0); } - protected long insertResultToDb(Result entity){ + protected long insertResultToDb(Result entity) { return mLiteOrm.insert(entity); } - protected int deleteResultFromDb(Result entity){ + protected int deleteResultFromDb(Result entity) { return mLiteOrm.delete(entity); } - public void playSound(String fileName,String mp3Url) { - Observable.just(mp3Url) - .subscribe(new Action1() { - @Override - public void call(String entity) { - File cacheFile = mFileManager.getCacheFileByUrl(getContext(), fileName); - if (cacheFile != null && cacheFile.exists()) { - playSound(cacheFile); - return; - } - Call call = mSingleRequestService.downloadSoundFile(mp3Url); - call.enqueue(new Callback() { - @Override - public void onResponse(Call call, Response response) { - if (response.isSuccessful()) { - try { - cacheAndPlaySound(getContext(), fileName, response.body().bytes()); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @Override - public void onFailure(Call call, Throwable t) { - Logger.e(t.getMessage()); - t.printStackTrace(); - } - }); + public void playSound(String fileName, String mp3Url) { + File cacheFile = mFileManager.getCacheFileByUrl(getContext(), fileName); + if (cacheFile != null && cacheFile.exists()) { + playSound(cacheFile); + return; + } + Call call = mSingleRequestService.downloadSoundFile(mp3Url); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + try { + cacheAndPlaySound(getContext(), fileName, response.body().bytes()); + } catch (IOException e) { + e.printStackTrace(); } - }); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Logger.e(t.getMessage()); + t.printStackTrace(); + } + }); } - public void startSoundAnim(View view){ - addScaleAnim(view,1000,null); + public void startSoundAnim(View view) { + addScaleAnim(view, 1000, null); } - public void startFavoriteAnim(View view,AnimationEndListener listener){ - addScaleAnim(view,500,listener); + public void startFavoriteAnim(View view, AnimationEndListener listener) { + addScaleAnim(view, 500, listener); } private void addScaleAnim(View view, long duration, AnimationEndListener listener) { - ObjectAnimator animY = ObjectAnimator.ofFloat(view, "scaleY", 1f,0.5f, 1f, 1.2f,1f); - ObjectAnimator animX = ObjectAnimator.ofFloat(view, "scaleX", 1f,0.5f, 1f, 1.2f,1f); + ObjectAnimator animY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.5f, 1f, 1.2f, 1f); + ObjectAnimator animX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.5f, 1f, 1.2f, 1f); AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.playTogether(animX,animY); + animatorSet.playTogether(animX, animY); animatorSet.setDuration(duration); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); - if(listener != null){ + if (listener != null) { listener.onAnimationEnd(animation); } } @@ -180,7 +179,7 @@ public void onAnimationEnd(Animator animation) { animatorSet.start(); } - public interface AnimationEndListener{ + public interface AnimationEndListener { void onAnimationEnd(Animator animation); } @@ -197,11 +196,11 @@ public void call(File file) { } private void playSound(File file) { - if(file == null)return; + if (file == null) return; Uri myUri = Uri.fromFile(file); - Logger.i("播放 "+file.getAbsolutePath()); + Logger.i("播放 " + file.getAbsolutePath()); MediaPlayer mediaPlayer = new MediaPlayer(); - mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); try { mediaPlayer.setDataSource(getContext(), myUri); mediaPlayer.prepare(); @@ -211,6 +210,7 @@ private void playSound(File file) { mediaPlayer.start(); } + private Callable cacheFileObservable(Context context, String fileName, byte[] data) { return new Callable() { @Override @@ -222,11 +222,12 @@ public File call() throws Exception { /** * make a operation observable + * * @param func * @param * @return the Observable */ - protected Observable makeObservable(final Callable func) { + protected Observable makeObservable(final Callable func) { return Observable.create(new Observable.OnSubscribe() { @Override public void call(Subscriber subscriber) { @@ -238,4 +239,24 @@ public void call(Subscriber subscriber) { } }); } + + void trackTranslate(){ + AnswerUtil.translateSuccess(); + } + + public void trackTranslateFail(String msg){ + AnswerUtil.translateFail(msg); + } + + + void recordHistoryWords(Result entity) { + if(entity==null){ + return; + } + if(TextUtils.isEmpty(entity.getQuery())){ + return; + } + HistoryResult result = HistoryResult.toResult(entity); + mLiteOrm.insert(result); + } } diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java index c1ac0f7..4ca93d5 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/BookPresenter.java @@ -22,49 +22,63 @@ import android.content.ClipData; import android.content.Context; +import android.support.v7.app.AlertDialog; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.litesuits.orm.LiteOrm; import com.litesuits.orm.db.assit.QueryBuilder; import com.orhanobut.logger.Logger; +import com.umeng.analytics.MobclickAgent; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; import javax.inject.Inject; +import jonathanfinerty.once.Once; import name.gudong.translate.listener.clipboard.ClipboardManagerCompat; import name.gudong.translate.mvp.model.SingleRequestService; import name.gudong.translate.mvp.model.WarpAipService; +import name.gudong.translate.mvp.model.entity.translate.HistoryResult; import name.gudong.translate.mvp.model.entity.translate.Result; import name.gudong.translate.mvp.views.IBookView; +import name.gudong.translate.ui.NavigationManager; +import name.gudong.translate.util.SpUtils; import rx.Observable; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Action1; import rx.schedulers.Schedulers; -import static android.support.v7.widget.StaggeredGridLayoutManager.TAG; /** * Created by GuDong on 2/28/16 17:02. * Contact with gudong.name@gmail.com. */ public class BookPresenter extends BasePresenter { - + private static final String KEY_TIP_OF_RECITE_OPEN = "TIP_OF_RECITE_OPEN"; + private static final String KEY_RECITE_MODE_SWITCH = "RECITE_MODE_SWITCH"; + private static final String TAG = "BOOK_PRESENTER"; @Inject public BookPresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestService singleRequestService, Context context) { super(liteOrm, apiService, singleRequestService,context); } public void getWords() { - getAllWordsWarpByObservable() + getWords(false); + } + public void getWords(boolean isHistList) { + getAllWordsWarpByObservable(isHistList) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1>() { @Override public void call(List transResultEntities) { - mView.fillData(transResultEntities); + boolean isReciteMode = SpUtils.isWordBookReciteMode(getContext()); + mView.fillData(transResultEntities, isReciteMode); } }); } @@ -84,8 +98,12 @@ public void deleteWords(Result entity){ }); } - private Observable> getAllWordsWarpByObservable() { - return makeObservable(getAllWordsReal()); + private Observable> getAllWordsWarpByObservable(boolean isHistList) { + if(isHistList){ + return makeObservable(getHistWordsReal()); + }else{ + return makeObservable(getAllWordsReal()); + } } private Observable deleteWordsByObservable(Result entity) { @@ -107,10 +125,32 @@ public List call() throws Exception { }; } + private Callable> getHistWordsReal() { + return new Callable>() { + @Override + public List call() throws Exception { + QueryBuilder qb = new QueryBuilder<>(HistoryResult.class) + .appendOrderDescBy(Result.COL_ID); + + List results = mLiteOrm.query(qb); + List resultsWrapList = new ArrayList<>(); + resultsWrapList.addAll(results); + Logger.i(" results.size() "+results.size()); + return resultsWrapList; + } + }; + } + private Callable deleteWordReal(Result entity) { - return () -> mLiteOrm.delete(entity); + if(entity instanceof HistoryResult){ + HistoryResult result = (HistoryResult) entity; + return () -> mLiteOrm.delete(result); + }else { + return () -> mLiteOrm.delete(entity); + } } + public String getWordsJsonString(Listresults){ Gson gson = new Gson(); return gson.toJson(results); @@ -141,4 +181,43 @@ public void restoreWordsByText(List oriList, String text) { mView.restoreSuccess(results.size()-hasExistCount); } } + + public void checkPointRecite(int wordsSize) { + //当单词数大于 5 个时才提示 + if (!Once.beenDone(KEY_TIP_OF_RECITE_OPEN) && wordsSize>=5) { + Once.markDone(KEY_TIP_OF_RECITE_OPEN); + new AlertDialog.Builder(getContext()) + .setTitle("提示") + .setMessage("检测到你的单词本中已经有不少单词了,建议你前往设置页面,开启定时单词提示,用于帮助你背单词。") + .setPositiveButton("去开启", ((dialog, which) -> { + NavigationManager.gotoSetting(getContext()); + })) + .setNegativeButton("没兴趣",null) + .show(); + } + } + + public void initStatus(boolean isHistList) { + if(isHistList){ + return; + } + Once.toDo(KEY_RECITE_MODE_SWITCH); + // 第一次点击单词本开关需要给用户一个功能提示框 + Once.toDo(KEY_TIP_OF_RECITE_OPEN); + } + + public boolean hasShowReciteModeIntroduce() { + return Once.beenDone(KEY_RECITE_MODE_SWITCH); + } + + public void makeReciteDone(){ + Once.markDone(KEY_RECITE_MODE_SWITCH); + } + + public void clearHist() { + int res = mLiteOrm.deleteAll(HistoryResult.class); + if(res>0){ + mView.showEmptyList(); + } + } } diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/ClipboardPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/ClipboardPresenter.java index 5231133..eb5d799 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/ClipboardPresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/ClipboardPresenter.java @@ -21,6 +21,8 @@ package name.gudong.translate.mvp.presenters; import android.content.Context; +import android.text.TextUtils; +import android.util.Log; import com.litesuits.orm.LiteOrm; import com.litesuits.orm.db.assit.QueryBuilder; @@ -33,6 +35,7 @@ import name.gudong.translate.BuildConfig; import name.gudong.translate.listener.clipboard.ClipboardManagerCompat; +import name.gudong.translate.manager.ReciteModulePreference; import name.gudong.translate.manager.ReciteWordManager; import name.gudong.translate.mvp.model.SingleRequestService; import name.gudong.translate.mvp.model.WarpAipService; @@ -57,13 +60,13 @@ public class ClipboardPresenter extends TipFloatPresenter { @Inject ClipboardManagerCompat mClipboardWatcher; + ReciteModulePreference mRecitePreference; + /** * 循环展示单词结果 */ private List results; - private int currentIndex = -1; - /** * 定时显示 Tip 事件源 */ @@ -75,7 +78,7 @@ public class ClipboardPresenter extends TipFloatPresenter { private ClipboardManagerCompat.OnPrimaryClipChangedListener mListener = () -> { CharSequence content = mClipboardWatcher.getText(); - if(content != null){ + if (content != null) { performClipboardCheck(content.toString()); } }; @@ -86,34 +89,50 @@ public class ClipboardPresenter extends TipFloatPresenter { QueryBuilder queryBuilder = new QueryBuilder(Result.class); queryBuilder = queryBuilder.whereNoEquals(Result.COL_MARK_DONE_ONCE, true); results = mLiteOrm.query(queryBuilder); - Logger.i("result size is "+results.size()); + mRecitePreference = new ReciteModulePreference(getContext()); } @Override - public void onCreate(){ + public void onCreate() { super.onCreate(); initCountdownSetting(); - if(SpUtils.isShowIconInNotification(getContext())){ + if (SpUtils.isShowIconInNotification(getContext())) { Utils.showNormalNotification(getContext()); } } - public boolean isOpenReciteWords(){ + public boolean isOpenReciteWords() { return mReciteManger.isReciteOpenOrNot(); } - public boolean isPlaySoundsAuto(){ + public boolean isPlaySoundsAuto() { return mReciteManger.isPlaySoundAuto(); } - private void initCountdownSetting(){ - mActionShowTip = (t)->{ - if(isOpenReciteWords()){ + private void initCountdownSetting() { + mActionShowTip = (t) -> { + if (isOpenReciteWords()) { Logger.t(KEY_TAG_COUNT_DOWN).i("time is to show words"); - Result result = getResult(); - if(result == null)return; - mView.showResult(result,false); - }else{ + Result result = null; + int index = getResultIndex(); + if (index >= 0) { + result = results.get(index); + } else { + return; + } + if (result == null) return; + mView.showResult(result, false); + //设置下次显示的单词 + if (index != results.size() - 1) { + index++; + }else{ + //重新循环计数 + index = 0; + } + Result afterResult = results.get(index); + mRecitePreference.setCurrentCyclicWord(afterResult.getQuery()); + + } else { Logger.t(KEY_TAG_COUNT_DOWN).i("time is to show words but was close"); } }; @@ -122,29 +141,29 @@ private void initCountdownSetting(){ /** * 开启背单词 */ - public void openTipCyclic(){ + public void openTipCyclic() { EIntervalTipTime tipTime = mReciteManger.getIntervalTimeWay(); int time = tipTime.getIntervalTime(); boolean isSecond = tipTime == EIntervalTipTime.THIRTY_SECOND; - TimeUnit unit = isSecond? TimeUnit.SECONDS:TimeUnit.MINUTES; + TimeUnit unit = isSecond ? TimeUnit.SECONDS : TimeUnit.MINUTES; - if(mSubscription != null && !mSubscription.isUnsubscribed()){ + if (mSubscription != null && !mSubscription.isUnsubscribed()) { mSubscription.unsubscribe(); } - mSubscription = Observable.interval(time,unit) + mSubscription = Observable.interval(time, unit) .observeOn(AndroidSchedulers.mainThread()) .subscribe(mActionShowTip); - Logger.i(KEY_TAG,"开启背单词任务 间隔 "+tipTime.getIntervalTime()); + Logger.i(KEY_TAG, "开启背单词任务 间隔 " + tipTime.getIntervalTime()); } - public void removeTipCyclic(){ - if(mSubscription != null && !mSubscription.isUnsubscribed()){ + public void removeTipCyclic() { + if (mSubscription != null && !mSubscription.isUnsubscribed()) { mSubscription.unsubscribe(); mSubscription = null; - Logger.i(KEY_TAG,"移除背单词服务"); + Logger.i(KEY_TAG, "移除背单词服务"); } } @@ -158,23 +177,21 @@ public void addListener() { private void performClipboardCheck(String queryText) { //处理缓存 因为粘贴板的回调操作可能触发多次 - Logger.i("粘贴板的单词为 "+queryText); if (listQuery.contains(queryText)) { return; } listQuery.add(queryText); //只有用户在打开了 划词翻译的情况下 划词翻译才能正常工作 - if(!SpUtils.getOpenJITOrNot(getContext()))return; + if (!SpUtils.getOpenJITOrNot(getContext())) return; //如果当前界面是 咕咚翻译的主界面 那么也不对粘贴板做监听( Debug 时开启) - if(!BuildConfig.DEBUG){ - if(SpUtils.getAppFront(getContext()))return; + if (!BuildConfig.DEBUG) { + if (SpUtils.getAppFront(getContext())) return; } // 检查粘贴板的内容是不是单词 以及是不是为空 - if(!checkInput(queryText)){ - Logger.i("粘贴板为空"); + if (!checkInput(queryText)) { return; } //查询数据 @@ -187,40 +204,41 @@ public void onDestroy() { } - private Result getResult(){ - int index = getResultIndex(); - Logger.i("index is "+index); - if(index>=0){ - return results.get(index); - } else{ - return null; - } - } - - private int getResultIndex(){ - if(results.isEmpty()){ - return -1; + private int getResultIndex() { + int index = -1; + if (results.isEmpty()) { + return index; } - currentIndex = currentIndex+1; - if(currentIndex == results.size()-1){ - currentIndex = -1; - return results.size()-1; + /** + * 上次背单词时的最后一个单词 + */ + String lastQuery = mRecitePreference.getCurrentCyclicWord(); + if (!TextUtils.isEmpty(lastQuery)) { + Result result = new Result(); + result.setQuery(lastQuery); + int indexQuery = results.indexOf(result); + if (indexQuery >= 0) { + index = indexQuery; + } + } else { + index = 0; } - return currentIndex; + return index; } /** * 标记已背 + * * @param result */ public void markDone(Result result) { result.setMake_done_once(true); result.setMake_done_once_time(System.currentTimeMillis()); - Logger.i("size "+results.size()); - if(results.remove(result)){ + Logger.i("size " + results.size()); + if (results.remove(result)) { Logger.i("remove suc"); } - Logger.i("size "+results.size()); + Logger.i("size " + results.size()); mLiteOrm.update(result); } } \ No newline at end of file diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java index 54ee723..d13bedd 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/MainPresenter.java @@ -20,6 +20,7 @@ package name.gudong.translate.mvp.presenters; +import android.content.ActivityNotFoundException; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -28,11 +29,14 @@ import android.provider.Settings; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; +import android.widget.Toast; import com.litesuits.orm.LiteOrm; import com.litesuits.orm.db.assit.WhereBuilder; import com.orhanobut.logger.Logger; +import java.util.ArrayList; +import java.util.Calendar; import java.util.List; import java.util.concurrent.Callable; import java.util.regex.Matcher; @@ -52,7 +56,9 @@ import name.gudong.translate.mvp.model.type.ETranslateFrom; import name.gudong.translate.mvp.views.IMainView; import name.gudong.translate.ui.activitys.MainActivity; +import name.gudong.translate.util.AnswerUtil; import name.gudong.translate.util.DialogUtil; +import name.gudong.translate.util.LocalDicHelper; import name.gudong.translate.util.SpUtils; import name.gudong.translate.util.Utils; import rx.Observable; @@ -67,7 +73,19 @@ * Contact with gudong.name@gmail.com. */ public class MainPresenter extends BasePresenter { - private static final String KEY_RESULT = "RESULT"; + public static final String KEY_RESULT = "RESULT"; + public static final int KEY_REQUEST_CODE_FOR_NOTI = 100; + private static List staticTranslateWayList = new ArrayList<>(); + + static { + if (BuildConfig.IS_ADVANCE) { + staticTranslateWayList.add(ETranslateFrom.BAI_DU); + } + staticTranslateWayList.add(ETranslateFrom.YOU_DAO); + staticTranslateWayList.add(ETranslateFrom.JIN_SHAN); + staticTranslateWayList.add(ETranslateFrom.GOOGLE); + } + @Inject ClipboardManagerCompat mClipboardWatcher; @@ -78,17 +96,36 @@ public MainPresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestSe super(liteOrm, apiService, singleRequestService, context); } - public void checkIntentFromClickTipView(Intent intent){ - if(hasExtraResult(intent)){ + public void checkIntentFromClickTipView(Intent intent) { + if (hasExtraResult(intent)) { Result result = (Result) intent.getSerializableExtra(KEY_RESULT); - if(result != null){ + if (result != null) { mView.onInitSearchText(result.getQuery()); executeSearch(result.getQuery()); } } } - public boolean hasExtraResult(Intent intent){ + public void analysisLocalDic() { + makeObservable(new Callable>() { + @Override + public List call() throws Exception { + return LocalDicHelper.getLocalDic(mContext); + } + }).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1>() { + @Override + public void call(List strings) { + if (mView != null) { + mView.attachLocalDic(strings); + } + + } + }); + } + + public boolean hasExtraResult(Intent intent) { return intent.hasExtra(KEY_RESULT); } @@ -127,19 +164,30 @@ public void checkVersionAndShowChangeLog() { } } - public void trigDbUpdate(){ - Listresults = mLiteOrm.query(Result.class); - for (Result result:results) { - if(!result.isMake_done_once()){ + public void trigDbUpdate() { + List results = mLiteOrm.query(Result.class); + for (Result result : results) { + if (!result.isMake_done_once()) { result.setMake_done_once(false); mLiteOrm.update(result); } } } + private String mLastQuery = ""; + private ETranslateFrom mLastFrom = ETranslateFrom.JIN_SHAN; + public void executeSearch(String keywords) { + ETranslateFrom from = SpUtils.getTranslateEngineWay(getContext()); + //去掉重复 + if (mLastQuery.equals(keywords) && mLastFrom == from) { + return; + } + mLastQuery = keywords; + mLastFrom = from; + mView.onPrepareTranslate(); - Observable observable = mWarpApiService.translate(SpUtils.getTranslateEngineWay(getContext()), keywords); + Observable observable = mWarpApiService.translate(from, keywords); if (observable == null) { Logger.e("Observable is null"); return; @@ -166,6 +214,11 @@ public List call(AbsResult absResult) { if (result == null) return null; result.setCreate_time(System.currentTimeMillis()); result.setUpdate_time(System.currentTimeMillis()); + + recordHistoryWords(result); + trackTranslate(); + + if (mView == null) return null; mView.addTagForView(result); if (!TextUtils.isEmpty(result.getEnMp3())) { @@ -183,10 +236,11 @@ public List call(AbsResult absResult) { List temp = absResult.wrapExplains(); //增加音标显示 String phAm = absResult.getResult().getPhAm(); - if (!temp.isEmpty() && !TextUtils.isEmpty(phAm)){ - temp.add(0,"["+phAm+"]"); + if (!temp.isEmpty() && !TextUtils.isEmpty(phAm)) { + temp.add(0, "[" + phAm + "]"); return temp; } + return absResult.wrapTranslation(); } }) @@ -200,6 +254,7 @@ public Boolean call(List strings) { @Override public Observable call(List strings) { if (strings == null) { + trackTranslateFail("啥也没有翻译出来"); return Observable.error(new Exception(("啥也没有翻译出来!"))); } return Observable.from(strings); @@ -208,7 +263,9 @@ public Observable call(List strings) { .subscribe(new Subscriber() { @Override public void onCompleted() { - mView.onTranslateComplete(); + if (mView != null) { + mView.onTranslateComplete(); + } } @Override @@ -216,7 +273,10 @@ public void onError(Throwable e) { if (BuildConfig.DEBUG) { e.printStackTrace(); } - mView.onError(e); + if (mView != null) { + mView.onError(e); + } + trackTranslateFail(e.getMessage()); } @Override @@ -232,7 +292,7 @@ public void favoriteWord(Result result) { public void unFavoriteWord(Result result) { //,Result.COL_QUERY,new String[]{result.getQuery() - WhereBuilder builder = WhereBuilder.create(Result.class).andEquals(Result.COL_QUERY,result.getQuery()); + WhereBuilder builder = WhereBuilder.create(Result.class).andEquals(Result.COL_QUERY, result.getQuery()); mLiteOrm.delete(builder); } @@ -244,15 +304,26 @@ public void startListenClipboardService() { * 去评分 */ public void gotoMarket() { - Uri uri = Uri.parse("market://details?id=" + getContext().getPackageName()); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getContext().startActivity(intent); + try { + Uri uri = Uri.parse("market://details?id=" + getContext().getPackageName()); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getContext().startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(mContext, "没有找到合适的应用商店", Toast.LENGTH_SHORT).show(); + } } public void prepareTranslateWay() { ETranslateFrom from = SpUtils.getTranslateEngineWay(getContext()); - mView.initTranslateEngineSetting(from); + if (from == ETranslateFrom.BAI_DU) { + from = ETranslateFrom.YOU_DAO; + SpUtils.setTranslateEngine(getContext(), ETranslateFrom.YOU_DAO); + } + int index = staticTranslateWayList.indexOf(from); + index = index >= 0 ? index : 0; + mView.initTranslateSelect(index); + AnswerUtil.showMainView(from.getName()); } /** @@ -265,28 +336,28 @@ public Boolean call() throws Exception { return mFileManager.resetFileCache(getContext()); } }). - subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Action1() { - @Override - public void call(Boolean aBoolean) { - if(aBoolean){ - //Toast.makeText(getContext(), "清除缓存成功", Toast.LENGTH_SHORT).show(); - }else{ - //Toast.makeText(getContext(), "无缓存需要清除", Toast.LENGTH_SHORT).show(); - } - } - }); + subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Action1() { + @Override + public void call(Boolean aBoolean) { + if (aBoolean) { + //Toast.makeText(getContext(), "清除缓存成功", Toast.LENGTH_SHORT).show(); + } else { + //Toast.makeText(getContext(), "无缓存需要清除", Toast.LENGTH_SHORT).show(); + } + } + }); } - public void dayline(){ + public void dayline() { mSingleRequestService.dayline("http://open.iciba.com/dsapi/") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1() { @Override public void call(JinshanDayLineEntity jinshanDayLineEntity) { - if(jinshanDayLineEntity != null){ + if (jinshanDayLineEntity != null) { mView.fillDayline(jinshanDayLineEntity); } } @@ -299,24 +370,41 @@ public void call(Throwable throwable) { }); } - public static void jumpMainActivityFromClickTipView(Context context,Result result){ + public static void jumpMainActivityFromClickTipView(Context context, Result result) { Intent intent = new Intent(context, MainActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); - intent.putExtra(KEY_RESULT,result); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(KEY_RESULT, result); context.startActivity(intent); } /** * 触发 Android M 上的浮窗权限 */ - public void triggerDrawOverlaysPermission(){ - if(Utils.isAndroidM()){ - if(!Settings.canDrawOverlays(getContext())) { + public void triggerDrawOverlaysPermission() { + if (Utils.isAndroidM()) { + if (!Settings.canDrawOverlays(getContext())) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); getContext().startActivity(intent); } } } + + public void checkAndPlayEggs() { + Calendar c = Calendar.getInstance();// + int year = c.get(Calendar.YEAR); // 获取当前年份 + int month = c.get(Calendar.MONTH) + 1;// 获取当前月份 + int day = c.get(Calendar.DAY_OF_MONTH);// 获取当日期 + if (year == 2018 && month == 2) { + if (day >= 16 && day <= 21) { + AnswerUtil.showEggs(); + mView.playNewYearAnim(); + } + } + } + + public List getTranslateWaysList() { + return staticTranslateWayList; + } } diff --git a/app/src/main/java/name/gudong/translate/mvp/presenters/TipFloatPresenter.java b/app/src/main/java/name/gudong/translate/mvp/presenters/TipFloatPresenter.java index 340572a..645fbfb 100644 --- a/app/src/main/java/name/gudong/translate/mvp/presenters/TipFloatPresenter.java +++ b/app/src/main/java/name/gudong/translate/mvp/presenters/TipFloatPresenter.java @@ -37,7 +37,9 @@ import name.gudong.translate.mvp.model.SingleRequestService; import name.gudong.translate.mvp.model.WarpAipService; import name.gudong.translate.mvp.model.entity.translate.AbsResult; +import name.gudong.translate.mvp.model.entity.translate.HistoryResult; import name.gudong.translate.mvp.model.entity.translate.Result; +import name.gudong.translate.mvp.model.type.ETranslateFrom; import name.gudong.translate.mvp.views.ITipFloatView; import name.gudong.translate.util.SpUtils; import name.gudong.translate.util.StringUtils; @@ -56,19 +58,31 @@ public class TipFloatPresenter extends BasePresenter { @Inject public TipFloatPresenter(LiteOrm liteOrm, WarpAipService apiService, SingleRequestService singleRequestService, Context context) { - super(liteOrm, apiService, singleRequestService,context); + super(liteOrm, apiService, singleRequestService, context); } + private String mLastQuery = ""; + private ETranslateFrom mLastFrom = ETranslateFrom.JIN_SHAN; + public void search(final String keywords) { + ETranslateFrom from = SpUtils.getTranslateEngineWay(getContext()); + //去掉重复 + if(mLastQuery.equals(keywords) && mLastFrom == from){ + mView.onComplete(); + return; + } + mLastQuery = keywords; + mLastFrom = from; - public void search(final String content) { - if(!checkInput(content)){ + if (!checkInput(keywords)) { mView.onComplete(); return; } - mWarpApiService.translate(SpUtils.getTranslateEngineWay(getContext()), content) + mWarpApiService.translate(from, keywords) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .filter((result)->{return result.wrapErrorCode() == 0;}) + .filter((result) -> { + return result.wrapErrorCode() == 0; + }) .subscribe(new Subscriber() { @Override public void onCompleted() { @@ -78,41 +92,52 @@ public void onCompleted() { @Override public void onError(Throwable e) { - if(e instanceof SocketTimeoutException){ - mView.errorPoint("网络请求超时,请稍后重试。"); - }else{ - if(BuildConfig.DEBUG){ - mView.errorPoint("请求数据异常,您可以试试切换其他引擎。"+e.getMessage()); + if (mView == null) return; + if (e instanceof SocketTimeoutException) { + String msg = "网络请求超时,请稍后重试。"; + mView.errorPoint(msg); + trackTranslateFail(msg); + } else { + String msg = "网络请求超时,请稍后重试。"; + if (BuildConfig.DEBUG) { + msg = "请求数据异常,您可以试试切换其他引擎。" + e.getMessage(); e.printStackTrace(); - }else{ - mView.errorPoint("请求数据异常,您可以试试切换其他引擎。"); + } else { + msg = "请求数据异常(source:"+from.getName()+"),您可以试试切换其他引擎。"; } + mView.errorPoint(msg); + trackTranslateFail(msg); } } @Override public void onNext(AbsResult result) { + if (mView == null) return; + trackTranslate(); Result realResult = result.getResult(); realResult.setCreate_time(System.currentTimeMillis()); realResult.setUpdate_time(System.currentTimeMillis()); - mView.showResult(realResult,true); + mView.showResult(realResult, true); + recordHistoryWords(realResult); } }); } - public void initFavoriteStatus(Result result){ - Result localResult= isFavorite(result.getQuery()); - if(localResult!=null){ + + + public void initFavoriteStatus(Result result) { + Result localResult = isFavorite(result.getQuery()); + if (localResult != null) { mView.initWithFavorite(result); - }else{ + } else { mView.initWithNotFavorite(result); } } - public void clickFavorite(View view,Result result){ - Result localResult= isFavorite(result.getQuery()); - if (localResult!=null) { + public void clickFavorite(View view, Result result) { + Result localResult = isFavorite(result.getQuery()); + if (localResult != null) { int index = deleteResultFromDb(localResult); if (index > 0) { mView.initWithNotFavorite(result); @@ -120,7 +145,7 @@ public void clickFavorite(View view,Result result){ } else { Logger.i("删除失败"); } - }else{ + } else { long index = insertResultToDb(result); if (index > 0) { mView.initWithFavorite(result); @@ -131,47 +156,53 @@ public void clickFavorite(View view,Result result){ } } - public void jumpMainActivity(Result result){ - MainPresenter.jumpMainActivityFromClickTipView(getContext(),result); + public void jumpMainActivity(Result result) { + MainPresenter.jumpMainActivityFromClickTipView(getContext(), result); } - protected boolean checkInput(String input){ + protected boolean checkInput(String input) { // empty check if (TextUtils.isEmpty(input)) { Logger.e("剪贴板为空了"); + trackTranslateFail("剪贴板为空了"); return false; } - if(StringUtils.isChinese(input)){ - Logger.e(input+" 中包含中文字符"); + if (StringUtils.isValidEmailAddress(input)) { + Logger.e(input + " 是一个邮箱"); + trackTranslateFail(input + " 是一个邮箱"); return false; } - if(StringUtils.isValidEmailAddress(input)){ - Logger.e(input+" 是一个邮箱"); + if (StringUtils.isValidUrl(input)) { + Logger.e(input + " 是一个网址"); + trackTranslateFail(input + " 是一个网址"); return false; } - if(StringUtils.isValidUrl(input)){ - Logger.e(input+" 是一个网址"); + if (StringUtils.isValidNumeric(input)) { + Logger.e(input + " 是一串数字"); + trackTranslateFail(input + " 是一串数字"); return false; } - if(StringUtils.isValidNumeric(input)){ - Logger.e(input+" 是一串数字"); + // length check + if (BuildConfig.IS_ADVANCE) { + return true; + } + + if (StringUtils.isChinese(input)) { + Logger.e(input + " 中包含中文字符"); + trackTranslateFail(input + " 中包含中文字符"); return false; } - // length check if(StringUtils.isMoreThanOneWord(input)){ mView.errorPoint("咕咚翻译目前不支持划句或者划短语翻译\n多谢理解"); + trackTranslateFail("咕咚翻译目前不支持划句或者划短语翻译\n多谢理解"); return false; } return true; } - - public void onDestroy() { - super.onDestroy(); - } } \ No newline at end of file diff --git a/app/src/main/java/name/gudong/translate/mvp/views/IAboutView.java b/app/src/main/java/name/gudong/translate/mvp/views/IAboutView.java new file mode 100644 index 0000000..a5c61db --- /dev/null +++ b/app/src/main/java/name/gudong/translate/mvp/views/IAboutView.java @@ -0,0 +1,10 @@ +package name.gudong.translate.mvp.views; + +/** + * Created by GuDong on 2017/10/25 00:09. + * Contact with gudong.name@gmail.com. + */ + +public interface IAboutView extends IBaseView { + void update(); +} diff --git a/app/src/main/java/name/gudong/translate/mvp/views/IBookView.java b/app/src/main/java/name/gudong/translate/mvp/views/IBookView.java index acc1aae..bafd196 100644 --- a/app/src/main/java/name/gudong/translate/mvp/views/IBookView.java +++ b/app/src/main/java/name/gudong/translate/mvp/views/IBookView.java @@ -29,7 +29,7 @@ * Contact with gudong.name@gmail.com. */ public interface IBookView extends IBaseView { - void fillData(List transResultEntities); + void fillData(List transResultEntities, boolean isReciteMode ); void deleteWordSuccess(Result entity); @@ -47,4 +47,7 @@ public interface IBookView extends IBaseView { * 数据没有任何变化 */ void showTipDataHaveNoChange(); + + void showEmptyList(); + } diff --git a/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java b/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java index 06dc71b..9cdd078 100644 --- a/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java +++ b/app/src/main/java/name/gudong/translate/mvp/views/IMainView.java @@ -20,6 +20,8 @@ package name.gudong.translate.mvp.views; +import java.util.List; + import name.gudong.translate.mvp.model.entity.dayline.IDayLine; import name.gudong.translate.mvp.model.entity.translate.Result; import name.gudong.translate.mvp.model.type.ETranslateFrom; @@ -38,7 +40,7 @@ public interface IMainView extends IBaseView { void addExplainItem(String explain); - void initTranslateEngineSetting(ETranslateFrom way); + void initTranslateSelect(int select); void onTranslateComplete(); @@ -58,4 +60,8 @@ public interface IMainView extends IBaseView { void initWithNotFavorite(); void fillDayline(IDayLine entity); + + void attachLocalDic(List dic); + + void playNewYearAnim(); } diff --git a/app/src/main/java/name/gudong/translate/ui/LinkCardViewBinder.java b/app/src/main/java/name/gudong/translate/ui/LinkCardViewBinder.java new file mode 100644 index 0000000..c5b1006 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/ui/LinkCardViewBinder.java @@ -0,0 +1,36 @@ +package name.gudong.translate.ui; + +import android.os.Build; +import android.support.annotation.NonNull; +import android.text.Html; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; + +import me.drakeet.support.about.Card; +import me.drakeet.support.about.CardViewBinder; + +/** + * Created by GuDong on 2017/10/25 08:26. + * Contact with gudong.name@gmail.com. + */ + +public class LinkCardViewBinder extends CardViewBinder { + @Override + protected void onBindViewHolder(@NonNull ViewHolder holder, @NonNull Card card) { +// super.onBindViewHolder(holder, card); + String content = card.content.toString(); + if(content.equals("link_log")){ + String s1 = "

查看历史日志


链接"; + Spanned text = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + text = Html.fromHtml(s1, Html.FROM_HTML_MODE_COMPACT); + } else { + text = Html.fromHtml(s1); + } + holder.content.setText(text); + holder.content.setMovementMethod(LinkMovementMethod.getInstance()); + }else{ + super.onBindViewHolder(holder, card); + } + } +} diff --git a/app/src/main/java/name/gudong/translate/ui/NavigationManager.java b/app/src/main/java/name/gudong/translate/ui/NavigationManager.java index a6ff8b9..e77817a 100644 --- a/app/src/main/java/name/gudong/translate/ui/NavigationManager.java +++ b/app/src/main/java/name/gudong/translate/ui/NavigationManager.java @@ -8,6 +8,10 @@ import java.util.List; +import name.gudong.translate.mvp.model.entity.translate.Result; +import name.gudong.translate.mvp.presenters.MainPresenter; +import name.gudong.translate.ui.activitys.AboutActivity; +import name.gudong.translate.ui.activitys.MainActivity; import name.gudong.translate.ui.activitys.SettingActivity; /** @@ -15,19 +19,29 @@ * Contact with gudong.name@gmail.com. */ public class NavigationManager { - public static void gotoSendEmail(Context context){ + public static void gotoSendEmail(Context context) { Uri uri = Uri.parse("mailto:gudong.name@gmail.com"); final Intent intent = new Intent(Intent.ACTION_SENDTO, uri); PackageManager pm = context.getPackageManager(); List infos = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); - if (infos == null || infos.size() <= 0){ + if (infos == null || infos.size() <= 0) { return; } context.startActivity(intent); } - public static void gotoSetting(Context context){ + public static void gotoSetting(Context context) { Intent intent = new Intent(context, SettingActivity.class); context.startActivity(intent); } + + public static void gotoMainActivity(Context context, Result entity) { + Intent intent = new Intent(context, MainActivity.class); + intent.putExtra(MainPresenter.KEY_RESULT, entity); + context.startActivity(intent); + } + public static void gotoAboutActivity(Context context) { + Intent intent = new Intent(context, AboutActivity.class); + context.startActivity(intent); + } } diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/AboutActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/AboutActivity.java new file mode 100644 index 0000000..1ea7e06 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/ui/activitys/AboutActivity.java @@ -0,0 +1,59 @@ +package name.gudong.translate.ui.activitys; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.widget.ImageView; +import android.widget.TextView; + +import com.github.anzewei.parallaxbacklayout.ParallaxBack; + +import javax.inject.Inject; + +import me.drakeet.multitype.Items; +import me.drakeet.support.about.AbsAboutActivity; +import me.drakeet.support.about.provided.PicassoImageLoader; +import name.gudong.translate.BuildConfig; +import name.gudong.translate.GDApplication; +import name.gudong.translate.R; +import name.gudong.translate.injection.components.AppComponent; +import name.gudong.translate.injection.components.DaggerActivityComponent; +import name.gudong.translate.injection.modules.ActivityModule; +import name.gudong.translate.mvp.presenters.AboutPresenter; +import name.gudong.translate.mvp.views.IAboutView; + +@ParallaxBack +public class AboutActivity extends AbsAboutActivity implements IAboutView { + @Inject + protected AboutPresenter mPresenter; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setupActivityComponent(GDApplication.getAppComponent(),new ActivityModule(this)); + mPresenter.attachView(this); + setImageLoader(new PicassoImageLoader()); + } + + protected void setupActivityComponent(AppComponent appComponent, ActivityModule activityModule) { + DaggerActivityComponent.builder() + .appComponent(appComponent) + .activityModule(activityModule) + .build() + .inject(this); + } + + @Override + protected void onCreateHeader(@NonNull ImageView icon, @NonNull TextView slogan, @NonNull TextView version) { + icon.setImageResource(R.mipmap.ic_launcher); + slogan.setText(R.string.app_name); + version.setText("v" + BuildConfig.VERSION_NAME); + } + @Override + protected void onItemsCreated(@NonNull Items items) { + mPresenter.getLinkApps(items); + } + + @Override + public void update() { + getAdapter().notifyDataSetChanged(); + } +} \ No newline at end of file diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/AcknowledgementsActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/AcknowledgementsActivity.java index aa51a96..77451db 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/AcknowledgementsActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/AcknowledgementsActivity.java @@ -8,6 +8,7 @@ import android.util.Log; import android.view.View; +import com.github.anzewei.parallaxbacklayout.ParallaxBack; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -36,6 +37,7 @@ import rx.schedulers.Schedulers; import rx.subscriptions.CompositeSubscription; +@ParallaxBack public class AcknowledgementsActivity extends BaseActivity implements AcknowledgementAdapter.AcknowledgementItemClickListener { private static final String TAG = "Acknowledgements"; diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java index 50e91ff..e410b35 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/MainActivity.java @@ -21,6 +21,7 @@ package name.gudong.translate.ui.activitys; import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; @@ -34,24 +35,29 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.util.Log; +import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.Button; -import android.widget.EditText; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import com.airbnb.lottie.LottieAnimationView; import com.google.gson.JsonSyntaxException; import com.umeng.analytics.MobclickAgent; import java.net.UnknownHostException; +import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; @@ -61,7 +67,6 @@ import name.gudong.translate.injection.components.AppComponent; import name.gudong.translate.injection.components.DaggerActivityComponent; import name.gudong.translate.injection.modules.ActivityModule; -import name.gudong.translate.manager.AlarmManagers; import name.gudong.translate.mvp.model.entity.dayline.IDayLine; import name.gudong.translate.mvp.model.entity.translate.JinShanResult; import name.gudong.translate.mvp.model.entity.translate.Result; @@ -70,6 +75,7 @@ import name.gudong.translate.mvp.presenters.MainPresenter; import name.gudong.translate.mvp.views.IMainView; import name.gudong.translate.ui.NavigationManager; +import name.gudong.translate.util.AnswerUtil; import name.gudong.translate.util.DialogUtil; import name.gudong.translate.util.InputMethodUtils; import name.gudong.translate.util.SpUtils; @@ -79,7 +85,7 @@ public class MainActivity extends BaseActivity implements IMainView { private static final String TAG = "MainActivity"; @BindView(android.R.id.input) - EditText mInput; + AutoCompleteTextView mInput; @BindView(R.id.list_result) LinearLayout mList; @BindView(R.id.sp_translate_way) @@ -124,14 +130,27 @@ protected void onCreate(Bundle savedInstanceState) { initSpinner(); checkTranslateWay(); checkVersion(); - initConfig(); - setUpDayline(); + setUpDayline(false); checkIntent(); - checkOverPermission(); + if (Utils.checkDrawOverlaysPermissionGranted(this)) { + guideCheck(); + } else { + showGuidePermissionDialog(); + } } - private void setUpDayline() { + private void guideCheck() { + if (!SpUtils.hasShowGuide(this)) { + showFloatTranslateExplainDialog(); + } + } + + private void setUpDayline(boolean isOpenDayLine) { View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet_view); + if (!isOpenDayLine) { + bottomSheet.setVisibility(View.GONE); + return; + } //点击 和拖拽都可以打开bottom sheet bottomSheet.setOnClickListener(v -> onClickBottomSheet()); mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet); @@ -141,7 +160,6 @@ private void setUpDayline() { } - private void checkIntent() { mPresenter.checkIntentFromClickTipView(getIntent()); //每日一句 @@ -161,7 +179,9 @@ public void run() { public void onResume() { super.onResume(); //检查粘贴板和 intent - checkSomething(); + checkClipboard(); + initConfig(); + addTranslateWaySelectListener(); if (BuildConfig.DEBUG) { SpUtils.setAppFront(this, false); } else { @@ -169,27 +189,27 @@ public void onResume() { } } - private void checkOverPermission() { - if (Utils.isAndroidM()) { - if (!SpUtils.hasGrantDrawOverlays(this) && !Settings.canDrawOverlays(this)) { - new AlertDialog.Builder(this).setMessage("检测到你的设备默禁用了浮窗权限,为了保证你可以正常使用咕咚翻译的划词翻译功能,需要你授予浮窗权限。") - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - Uri.parse("package:" + getPackageName())); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } else { - SpUtils.setDrawOverlays(this, true); - } - } else { - SpUtils.setDrawOverlays(this, true); - } + /** + * 弹出引导用户打开悬浮权限的 dialog + */ + private void showGuidePermissionDialog() { + new AlertDialog.Builder(this).setMessage("检测到你的设备默禁用了浮窗权限,为了保证你可以正常使用咕咚翻译的划词翻译功能,需要你授予浮窗权限。") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + getPackageName())); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + guideCheck(); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + + private void showFloatTranslateExplainDialog() { + DialogUtil.showGuideFloatTranslate(this); } @Override @@ -203,16 +223,18 @@ private void checkTranslateWay() { } private void initConfig() { - //mPresenter.clearSoundCache(); + if (SpUtils.isAutoCompleteInputWords(this)) { + mPresenter.analysisLocalDic(); + } } private void checkVersion() { - if (BuildConfig.DEBUG) return; + //if (BuildConfig.DEBUG) return; mPresenter.checkVersionAndShowChangeLog(); } - private void checkSomething() { + private void checkClipboard() { if (!mPresenter.hasExtraResult(getIntent()) && SpUtils.isAutoPasteWords(this)) { //检查粘贴板有没有英文单词 如果有就查询一次 并且显示给用户 mPresenter.checkClipboard(); @@ -258,9 +280,15 @@ public boolean onOptionsItemSelected(MenuItem item) { WordsBookActivity.gotoWordsBook(this); MobclickAgent.onEvent(this, "open_book"); break; + case R.id.menu_hist: + WordsBookActivity.gotoWordsHist(this); + MobclickAgent.onEvent(this, "open_history"); + break; case R.id.menu_about: - DialogUtil.showAbout(this, formatAboutVersion()); +// DialogUtil.showAbout(this, formatAboutVersion()); + NavigationManager.gotoAboutActivity(this); MobclickAgent.onEvent(this, "menu_about"); + AnswerUtil.actionShowAbout(); closeKeyboard(); break; case R.id.menu_setting: @@ -275,6 +303,7 @@ public boolean onOptionsItemSelected(MenuItem item) { case R.id.menu_support: DialogUtil.showSupport(this); MobclickAgent.onEvent(this, "menu_support"); + AnswerUtil.actionSupport(); break; } return super.onOptionsItemSelected(item); @@ -282,7 +311,7 @@ public boolean onOptionsItemSelected(MenuItem item) { private void selectEngine(ETranslateFrom way) { - SpUtils.setTranslateEngine(this, way.name()); + SpUtils.setTranslateEngine(this, way); checkInputAndResearch(); } @@ -291,6 +320,7 @@ private void selectEngine(ETranslateFrom way) { * 主要是切换搜索引擎时会用到 */ private void checkInputAndResearch() { + String input = mInput.getText().toString().trim(); if (isEmptyWord(input, false)) return; //if(StringUtils.isMoreThanOneWord(input))return; @@ -301,6 +331,7 @@ private void addListener() { mInput.setOnKeyListener((v, keyCode, event) -> { if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { MobclickAgent.onEvent(this, "action_translate_by_keyboard"); + mInput.dismissDropDown(); translate(); return true; } @@ -326,24 +357,13 @@ public void afterTextChanged(Editable s) { mTvClear.setVisibility(mTemp.isEmpty() ? View.INVISIBLE : View.VISIBLE); } }); + } + private void addTranslateWaySelectListener() { mSpTranslateWay.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - switch (position) { - case 0: - selectEngine(ETranslateFrom.BAI_DU); - MobclickAgent.onEvent(getApplicationContext(), "way_baidu"); - break; - case 1: - selectEngine(ETranslateFrom.YOU_DAO); - MobclickAgent.onEvent(getApplicationContext(), "way_youdao"); - break; - case 2: - selectEngine(ETranslateFrom.JIN_SHAN); - MobclickAgent.onEvent(getApplicationContext(), "way_jinshan"); - break; - } + selectEngine((ETranslateFrom) mSpTranslateWay.getAdapter().getItem(position)); } @Override @@ -375,6 +395,7 @@ private boolean isEmptyWord(String input, boolean withEmptyPoint) { } private void translate() { + Log.i(TAG, "execute translate"); closeKeyboard(); final String input = mInput.getText().toString().trim(); if (checkInput(input)) { @@ -418,6 +439,7 @@ public void onError(Throwable e) { msg = getString(R.string.tip_unknown) + (BuildConfig.DEBUG ? " " + e.getMessage() : ""); e.printStackTrace(); } + mPresenter.trackTranslateFail(msg); mList.addView(ViewUtil.getWordsView(MainActivity.this, msg, android.R.color.holo_red_light, false)); mBtTranslate.setEnabled(true); mBtTranslate.setText(R.string.action_translate); @@ -429,8 +451,8 @@ public void addExplainItem(String explain) { } @Override - public void initTranslateEngineSetting(ETranslateFrom from) { - mSpTranslateWay.setSelection(from.getIndex()); + public void initTranslateSelect(int select) { + mSpTranslateWay.setSelection(select, true); } @OnClick(R.id.bt_translate) @@ -476,7 +498,7 @@ private void clearInputContent() { @OnClick(R.id.iv_favorite) public void onClickFavorite(final View view) { - MobclickAgent.onEvent(getApplicationContext(), "favorite_main"); + AnswerUtil.actionFavorite("main"); mPresenter.startFavoriteAnim(view, new BasePresenter.AnimationEndListener() { @Override public void onAnimationEnd(Animator animation) { @@ -495,18 +517,18 @@ public void onAnimationEnd(Animator animation) { } } }); + MobclickAgent.onEvent(getApplicationContext(), "favorite_main"); } @OnClick(R.id.iv_paste) public void onClickPaste(View view) { - MobclickAgent.onEvent(getApplicationContext(), "action_paste"); closeKeyboard(); Toast.makeText(MainActivity.this, "长按翻译结果可复制", Toast.LENGTH_SHORT).show(); + MobclickAgent.onEvent(getApplicationContext(), "action_paste"); } @OnClick(R.id.iv_sound) public void onClickSound(View view) { - MobclickAgent.onEvent(getApplicationContext(), "sound_main_activity"); Object obj = view.getTag(); if (obj != null && obj instanceof Result) { Result entity = (Result) obj; @@ -515,6 +537,8 @@ public void onClickSound(View view) { mPresenter.playSound(fileName, mp3Url); } mPresenter.startSoundAnim(view); + MobclickAgent.onEvent(getApplicationContext(), "sound_main_activity"); + AnswerUtil.actionSound("main"); } @Override @@ -557,6 +581,18 @@ public void fillDayline(IDayLine entity) { mIvSoundDayline.setTag(entity); } + @Override + public void attachLocalDic(List dic) { + ArrayAdapter wordAdapter = new ArrayAdapter<>(MainActivity.this, + android.R.layout.simple_list_item_1, + android.R.id.text1, + dic); + mInput.setAdapter(wordAdapter); + mInput.setThreshold(1); + mInput.setDropDownHeight(Utils.dp2px(this, 200)); + mInput.setOnItemClickListener((parent, view, position, id) -> translate()); + } + @OnClick(R.id.iv_sound_dayline) public void onClickDaylineSound(View view) { MobclickAgent.onEvent(getApplicationContext(), "sound_dayline_activity"); @@ -579,22 +615,26 @@ public void onTranslateComplete() { mIvFavorite.setEnabled(true); mIvSound.setEnabled(true); mIvPaste.setEnabled(true); + + mPresenter.checkAndPlayEggs(); } private void startListenService() { mPresenter.startListenClipboardService(); - AlarmManagers.register(this); } private void initSpinner() { - ArrayAdapter adapter = ArrayAdapter.createFromResource(this, - R.array.translate_way, R.layout.spinner_drop_list_title); - adapter.setDropDownViewResource(R.layout.spinner_drop_list_item); - mSpTranslateWay.setAdapter(adapter); + List translateWay = mPresenter.getTranslateWaysList(); + ArrayAdapter arrayAdapter = new ArrayAdapter<>(this, R.layout.spinner_drop_list_title, translateWay); + arrayAdapter.setDropDownViewResource(R.layout.spinner_drop_list_item); + mSpTranslateWay.setAdapter(arrayAdapter); } public void onClickBottomSheet() { + if (mBottomSheetBehavior == null) { + return; + } if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } else { @@ -613,6 +653,9 @@ public void onClickInput(View view) { * @return */ private boolean checkBottomSheetIsExpandedAndReset() { + if (mBottomSheetBehavior == null) { + return false; + } if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); return true; @@ -626,4 +669,40 @@ public void onBackPressed() { super.onBackPressed(); } } + + LottieAnimationView mAnimView; + + @Override + public void playNewYearAnim() { + if (mAnimView == null) { + int size = Utils.dp2px(this, 300); + mAnimView = new LottieAnimationView(this); + mAnimView.setAnimation("lottie/new_year_fire.json"); + FrameLayout root = (FrameLayout) getWindow().getDecorView(); + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size, size); + params.gravity = Gravity.CENTER; + root.addView(mAnimView, params); + } + mAnimView.setVisibility(View.VISIBLE); + mAnimView.addAnimatorListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + hideAnim(); + } + + @Override + public void onAnimationCancel(Animator animation) { + super.onAnimationCancel(animation); + hideAnim(); + } + }); + mAnimView.playAnimation(); + } + + private void hideAnim() { + mAnimView.setVisibility(View.GONE); + mAnimView.setProgress(0); + mAnimView.cancelAnimation(); + } } diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/ProcessTextActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/ProcessTextActivity.java index 7ac481d..24432de 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/ProcessTextActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/ProcessTextActivity.java @@ -8,24 +8,25 @@ import android.animation.Animator; import android.content.Intent; import android.os.Bundle; +import android.text.TextUtils; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; -import com.orhanobut.logger.Logger; import com.umeng.analytics.MobclickAgent; import javax.inject.Inject; +import name.gudong.translate.injection.components.AppComponent; +import name.gudong.translate.injection.components.DaggerActivityComponent; +import name.gudong.translate.injection.modules.ActivityModule; import name.gudong.translate.listener.view.TipView; import name.gudong.translate.listener.view.TipViewController; import name.gudong.translate.mvp.model.entity.translate.Result; import name.gudong.translate.mvp.presenters.BasePresenter; import name.gudong.translate.mvp.presenters.TipFloatPresenter; import name.gudong.translate.mvp.views.ITipFloatView; -import name.gudong.translate.injection.components.AppComponent; -import name.gudong.translate.injection.components.DaggerActivityComponent; -import name.gudong.translate.injection.modules.ActivityModule; +import name.gudong.translate.util.AnswerUtil; public class ProcessTextActivity extends BaseActivity implements ITipFloatView, TipView.ITipViewListener { @Inject @@ -52,11 +53,9 @@ private void checkText(Intent intent) { CharSequence text = intent.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT); boolean readonly = getIntent().getBooleanExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, false); - - Logger.i("result is " + text + " readonly is " + readonly); - // 检查粘贴板的内容是不是单词 以及是不是为空 - //mTvPopSrc.setText("result is " + text); - mPresenter.search(text.toString()); + if(!TextUtils.isEmpty(text)){ + mPresenter.search(text.toString()); + } } @Override @@ -95,7 +94,7 @@ public void initWithNotFavorite(Result result) { @Override public void onClickFavorite(View view, Result result) { - MobclickAgent.onEvent(this, "favorite_service"); + AnswerUtil.actionFavorite("androidMProcessEditor"); mPresenter.startFavoriteAnim(view, new BasePresenter.AnimationEndListener() { @Override public void onAnimationEnd(Animator animation) { @@ -106,7 +105,7 @@ public void onAnimationEnd(Animator animation) { @Override public void onClickPlaySound(View view, Result result) { - MobclickAgent.onEvent(this, "sound_service"); + AnswerUtil.actionSound("androidMProcessEditor"); mPresenter.playSound(result.getMp3FileName(),result.getEnMp3()); mPresenter.startSoundAnim(view); } diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java index 67c3b0a..67b4311 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/SettingActivity.java @@ -2,23 +2,29 @@ import android.content.DialogInterface; import android.os.Bundle; +import android.os.Handler; import android.preference.Preference; import android.preference.PreferenceFragment; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; +import android.util.Log; import android.view.MenuItem; import android.view.View; +import android.widget.SeekBar; +import com.github.anzewei.parallaxbacklayout.ParallaxBack; import com.umeng.analytics.MobclickAgent; import jonathanfinerty.once.Once; +import name.gudong.translate.BuildConfig; import name.gudong.translate.R; import name.gudong.translate.listener.ListenClipboardService; import name.gudong.translate.manager.ReciteModulePreference; import name.gudong.translate.mvp.model.type.EDurationTipTime; import name.gudong.translate.mvp.model.type.EIntervalTipTime; -import name.gudong.translate.util.Utils; +import name.gudong.translate.widget.ThumbSelectPreference; +@ParallaxBack public class SettingActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { @@ -47,6 +53,9 @@ private void setTitle(){ getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle("设置"); + if(BuildConfig.IS_ADVANCE){ + getSupportActionBar().setSubtitle("高级用户"); + } } @@ -56,8 +65,8 @@ public static class SettingsFragment extends PreferenceFragment implements Prefe private com.jenzz.materialpreference.Preference mDurationPreference; private com.jenzz.materialpreference.Preference mIntervalPreference; - private com.jenzz.materialpreference.SwitchPreference mShowIconInNotification; private com.jenzz.materialpreference.SwitchPreference mUseReciteOrNot; + private com.jenzz.materialpreference.PreferenceCategory mReciteWord; ReciteModulePreference mRecitePreference; @@ -74,19 +83,16 @@ public static class SettingsFragment extends PreferenceFragment implements Prefe public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mShowIconInNotification = (com.jenzz.materialpreference.SwitchPreference) findPreference("preference_show_icon_in_notification"); mUseReciteOrNot = (com.jenzz.materialpreference.SwitchPreference) findPreference("preference_use_recite_or_not"); + mReciteWord = (com.jenzz.materialpreference.PreferenceCategory) findPreference("category_recite_word"); mDurationPreference = (com.jenzz.materialpreference.Preference) findPreference("preference_show_time"); EDurationTipTime durationTime = mRecitePreference.getDurationTimeWay(); mDurationPreference.setSummary(getArrayValue(R.array.tip_time,durationTime.getIndex())); mDurationPreference.setOnPreferenceClickListener(this); - mShowIconInNotification.setOnPreferenceChangeListener(this); mUseReciteOrNot.setOnPreferenceChangeListener(this); - findPreference("preference_show_float_view_use_system").setEnabled(Utils.isSDKHigh5()); - mIntervalPreference = (com.jenzz.materialpreference.Preference) findPreference("preference_recite_time"); mIntervalPreference.setOnPreferenceClickListener(this); findPreference("preference_auto_play_sound").setOnPreferenceChangeListener(this); @@ -94,24 +100,17 @@ public void onViewCreated(View view, Bundle savedInstanceState) { mIntervalPreference.setSummary(getArrayValue(R.array.recipe_time,intervalTime.getIndex())); initUseReciteOrNotStatus(); + } private void initUseReciteOrNotStatus() { if (!Once.beenDone(KEY_TIP_OF_RECITE)) { new AlertDialog.Builder(getActivity()) .setTitle("新功能提示") - .setMessage("从 1.3.1 版本开始,咕咚翻译新增了定时提示生词的功能,。\n\n开启定时单词提醒后,系统会每隔五分钟(时间可以设置),随机弹出一个提示框,用于随机展示你收藏的生词,帮助你记住这些陌生单词。\n\n我相信再陌生的单词,如果可以不停的在你眼前出现,不一定那一次就记住了,当然这个功能是可以关闭的。\n\n灵感源于贝壳单词,感谢 @drakeet 同学的作品。") + .setMessage("从 1.5.0 版本开始,咕咚翻译新增了定时提示生词的功能,。\n\n开启定时单词提醒后,系统会每隔五分钟(时间可以设置),随机弹出一个提示框,用于随机展示你收藏的生词,帮助你记住这些陌生单词。\n\n我相信再陌生的单词,如果可以不停的在你眼前出现,不一定那一次就记住了,当然这个功能是可以关闭的。\n\n灵感源于贝壳单词。") .setCancelable(false) .setPositiveButton("知道了", ((dialog, which) -> { Once.markDone(KEY_TIP_OF_RECITE); - AppCompatActivity activity = (AppCompatActivity) getActivity(); - activity.findViewById(android.R.id.content).postDelayed(new Runnable() { - @Override - public void run() { - mUseReciteOrNot.setChecked(true); - } - },500); - })) .show().setCanceledOnTouchOutside(false); } @@ -133,14 +132,18 @@ public void onClick(DialogInterface dialog, int which) { MobclickAgent.onEvent(getActivity(),"menu_duration_time_2"); break; case 1: + selectDurationTime(EDurationTipTime.THREE_SECOND.name()); + MobclickAgent.onEvent(getActivity(),"menu_duration_time_3"); + break; + case 2: selectDurationTime(EDurationTipTime.FOUR_SECOND.name()); MobclickAgent.onEvent(getActivity(),"menu_duration_time_4"); break; - case 2: + case 3: selectDurationTime(EDurationTipTime.SIX_SECOND.name()); MobclickAgent.onEvent(getActivity(),"menu_duration_time_6"); break; - case 3: + case 4: selectDurationTime(EDurationTipTime.TEN_SECOND.name()); MobclickAgent.onEvent(getActivity(),"menu_duration_time_10"); break; @@ -216,13 +219,6 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { mRecitePreference.setReciteOpenOrNot((Boolean) newValue); shiftRecite(); break; - case "preference_show_icon_in_notification": - if((Boolean) newValue){ - Utils.showNormalNotification(getActivity()); - }else{ - Utils.cancelNotification(getActivity()); - } - break; case "preference_auto_play_sound": mRecitePreference.setPlaySoundAuto((Boolean) newValue); break; diff --git a/app/src/main/java/name/gudong/translate/ui/activitys/WordsBookActivity.java b/app/src/main/java/name/gudong/translate/ui/activitys/WordsBookActivity.java index 9e16b0a..ee6b554 100644 --- a/app/src/main/java/name/gudong/translate/ui/activitys/WordsBookActivity.java +++ b/app/src/main/java/name/gudong/translate/ui/activitys/WordsBookActivity.java @@ -36,6 +36,10 @@ import android.widget.TextView; import android.widget.Toast; +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.ContentViewEvent; +import com.github.anzewei.parallaxbacklayout.ParallaxBack; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -47,14 +51,21 @@ import name.gudong.translate.injection.components.AppComponent; import name.gudong.translate.injection.components.DaggerActivityComponent; import name.gudong.translate.injection.modules.ActivityModule; +import name.gudong.translate.mvp.model.entity.translate.HistoryResult; import name.gudong.translate.mvp.model.entity.translate.Result; import name.gudong.translate.mvp.presenters.BookPresenter; +import name.gudong.translate.mvp.presenters.MainPresenter; import name.gudong.translate.mvp.views.IBookView; import name.gudong.translate.ui.adapter.WordsListAdapter; +import name.gudong.translate.util.SpUtils; import name.gudong.translate.util.Utils; +import name.gudong.translate.widget.DividerItemDecoration; -public class WordsBookActivity extends BaseActivity implements WordsListAdapter.OnClick, IBookView { +import static name.gudong.translate.util.SpUtils.isWordBookReciteMode; +@ParallaxBack +public class WordsBookActivity extends BaseActivity implements IBookView { + private static final String KEY_HIST_LIST_FLAG = "isHistList"; @BindView(R.id.rv_words_list) RecyclerView mRvWordsList; @@ -63,45 +74,103 @@ public class WordsBookActivity extends BaseActivity implements Wo private List mResult = new ArrayList<>(); - WordsListAdapter mAdapter; + private boolean mIsHistList = false; - private Menu mMenu; + WordsListAdapter mAdapter; public static void gotoWordsBook(Context context) { Intent intent = new Intent(context, WordsBookActivity.class); context.startActivity(intent); } + public static void gotoWordsHist(Context context) { + Intent intent = new Intent(context, WordsBookActivity.class); + intent.putExtra(KEY_HIST_LIST_FLAG, true); + context.startActivity(intent); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_words_book); ButterKnife.bind(this); - initActionBar(true, "单词本"); + mIsHistList = getIntent().getBooleanExtra(KEY_HIST_LIST_FLAG, false); + if(mIsHistList){ + emptyTipText.setText(R.string.empty_hist); + }else{ + emptyTipText.setText(R.string.empty_tip); + } + initActionBar(true, mIsHistList ? "历史查询" : "单词本"); initListView(); initData(); + track(); + } + + private void track() { + Answers.getInstance().logContentView(new ContentViewEvent() + .putContentName(getTitle().toString()) + .putContentType(getTitle().toString()) + .putContentId(mIsHistList?"histList":"bookList")); } + @Override public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.book, menu); - mMenu = menu; + getMenuInflater().inflate(mIsHistList ? R.menu.hist : R.menu.book, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onPrepareOptionsMenu(Menu menu) { + if(mIsHistList){ + if(mAdapter.getItemCount() > 0){ + menu.findItem(R.id.menu_clear_hist).setEnabled(true); + }else{ + menu.findItem(R.id.menu_clear_hist).setEnabled(false); + } + return super.onPrepareOptionsMenu(menu); + } if (mAdapter.getItemCount() <= 0) { menu.findItem(R.id.menu_sort).setVisible(false); + menu.findItem(R.id.menu_recite_mode).setVisible(false); } else { menu.findItem(R.id.menu_sort).setVisible(true); + menu.findItem(R.id.menu_recite_mode).setVisible(true); + } + if(mAdapter.getItemCount() > 0){ + menu.findItem(R.id.menu_backup).setEnabled(true); + }else{ + menu.findItem(R.id.menu_backup).setEnabled(false); } + menu.findItem(R.id.menu_recite_mode).setChecked(isWordBookReciteMode(this)); + return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { + case R.id.menu_recite_mode: + if (!mPresenter.hasShowReciteModeIntroduce()) { + mPresenter.makeReciteDone(); + new AlertDialog.Builder(this) + .setMessage("开启背单词模式后,单词本的单词列表将隐藏单词释义,点击才可以查看。") + .setPositiveButton("知道了", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mRvWordsList.postDelayed(new Runnable() { + @Override + public void run() { + switchReciteMode(item); + } + }, 300); + } + }) + .show(); + } else { + switchReciteMode(item); + } + break; case R.id.menu_export: String exportText = mPresenter.getWordsJsonString(mAdapter.getData()); new AlertDialog.Builder(this) @@ -110,9 +179,10 @@ public boolean onOptionsItemSelected(MenuItem item) { .setPositiveButton("发送", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Utils.shareText(getBaseContext(), exportText); + Utils.shareText(WordsBookActivity.this, exportText); } }) + .setNegativeButton("取消", null) .setNeutralButton("复制", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -131,11 +201,11 @@ public void onClick(DialogInterface dialog, int which) { @Override public void onClick(DialogInterface dialog, int which) { String text = editText.getText().toString(); - if(TextUtils.isEmpty(text)){ + if (TextUtils.isEmpty(text)) { Toast.makeText(WordsBookActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show(); return; } - if(!Utils.isJSONFormat(text)){ + if (!Utils.isJSONFormat(text)) { Toast.makeText(WordsBookActivity.this, "不是 JSON 格式,请检查。", Toast.LENGTH_SHORT).show(); return; } @@ -154,6 +224,10 @@ public int compare(Result lhs, Result rhs) { }); mAdapter.update(mResult); break; + case R.id.sort_default: + item.setChecked(true); + mPresenter.getWords(); + break; case R.id.sort_index_desc: item.setChecked(true); Collections.sort(mResult, new Comparator() { @@ -164,19 +238,68 @@ public int compare(Result lhs, Result rhs) { }); mAdapter.update(mResult); break; + case R.id.menu_clear_hist: + new AlertDialog.Builder(this) + .setTitle("提示") + .setMessage("确定要清空所有的历史查询记录吗?") + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + mPresenter.clearHist(); + } + }) + .setNegativeButton("取消",null) + .show(); + break; } return super.onOptionsItemSelected(item); } + private void switchReciteMode(MenuItem item) { + item.setChecked(!item.isChecked()); + mAdapter.updateReciteMode(item.isChecked()); + SpUtils.setWordBookReciteMode(this, item.isChecked()); + } + private void initData() { - mPresenter.getWords(); + mPresenter.initStatus(mIsHistList); + mPresenter.getWords(mIsHistList); } private void initListView() { mAdapter = new WordsListAdapter(this); - mAdapter.setOnClickListener(this); + mAdapter.setPresenter(mPresenter); + mAdapter.setOnClickListener(new WordsListAdapter.IClickPopupMenuItem() { + @Override + public void onClickMenuItem(int itemId, Result entity) { + switch (itemId) { + case R.id.pop_delete: + new AlertDialog.Builder(WordsBookActivity.this) + .setMessage("确定要删除吗?") + .setPositiveButton("删除", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Result temp = entity; + if(mIsHistList){ + temp = HistoryResult.toResult(entity); + } + mPresenter.deleteWords(temp); + } + }) + .setNegativeButton("取消", null) + .show(); + break; + case R.id.pop_research: + MainPresenter.jumpMainActivityFromClickTipView(WordsBookActivity.this, entity); + finish(); + break; + } + + } + }); LinearLayoutManager mLayoutManager = new LinearLayoutManager(this); mRvWordsList.setLayoutManager(mLayoutManager); + mRvWordsList.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); mRvWordsList.setAdapter(mAdapter); } @@ -189,21 +312,23 @@ protected void setupActivityComponent(AppComponent appComponent, ActivityModule .inject(this); } - @Override - public void onClickItem(View view, Result entity) { - mPresenter.deleteWords(entity); - } @Override - public void fillData(List transResultEntities) { + public void fillData(List transResultEntities, boolean isReciteMode) { + if (transResultEntities == null) { + return; + } //如果查出来的结果为空,那么提示用户没有收藏的单词 - if (transResultEntities == null || transResultEntities.size() == 0) { + if (transResultEntities.size() == 0) { emptyTipText.setVisibility(View.VISIBLE); } else { emptyTipText.setVisibility(View.GONE); - mAdapter.update(transResultEntities); + mAdapter.update(transResultEntities, isReciteMode); mResult = transResultEntities; - + } + if(!mIsHistList){ + //提示开启背单词开关 + mPresenter.checkPointRecite(transResultEntities.size()); } } @@ -229,7 +354,7 @@ public void onError(Throwable error) { @Override public void restoreSuccess(int count) { mPresenter.getWords(); - showTip("成功恢复 "+count+ " 个单词。"); + showTip("成功恢复 " + count + " 个单词。"); } @Override @@ -237,6 +362,13 @@ public void showTipDataHaveNoChange() { showTip("数据没有任何变化"); } + @Override + public void showEmptyList() { + mAdapter.clear(); + emptyTipText.setVisibility(View.VISIBLE); + showTip("清除成功"); + } + /*** * show delete operation text * diff --git a/app/src/main/java/name/gudong/translate/ui/adapter/WordsListAdapter.java b/app/src/main/java/name/gudong/translate/ui/adapter/WordsListAdapter.java index 14dfdba..516ea21 100644 --- a/app/src/main/java/name/gudong/translate/ui/adapter/WordsListAdapter.java +++ b/app/src/main/java/name/gudong/translate/ui/adapter/WordsListAdapter.java @@ -21,52 +21,74 @@ package name.gudong.translate.ui.adapter; import android.content.Context; +import android.support.v7.view.menu.MenuPopupHelper; +import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import butterknife.ButterKnife; import name.gudong.translate.R; import name.gudong.translate.mvp.model.entity.translate.Result; +import name.gudong.translate.mvp.presenters.BasePresenter; import name.gudong.translate.util.ViewUtil; import rx.Observable; import rx.functions.Action0; import rx.functions.Action1; +import static name.gudong.translate.R.id.ll_pop_dst; + /** * Created by GuDong on 12/29/15 18:29. * Contact with gudong.name@gmail.com. */ public class WordsListAdapter extends RecyclerView.Adapter { private Context mContext; - private ListmList; + private List mList; - private OnClick mOnClickListener; + private IClickPopupMenuItem mOnClickListener; + private boolean isReciteMode = false; + private BasePresenter presenter; public WordsListAdapter(Context context) { mContext = context; mList = new ArrayList<>(); } - public void setOnClickListener(OnClick onClickListener) { + public void setPresenter(BasePresenter presenter){ + this.presenter=presenter; + } + public void setOnClickListener(IClickPopupMenuItem onClickListener) { mOnClickListener = onClickListener; } + public void clear(){ + mList.clear(); + notifyDataSetChanged(); + } + public void update(List list) { - mList = list; + update(list, false); + } + + public void update(List list, boolean isReciteMode) { + this.mList = list; + this.isReciteMode = isReciteMode; notifyDataSetChanged(); } - public void removeItem(Result entity){ + public void removeItem(Result entity) { mList.remove(entity); notifyDataSetChanged(); } @@ -80,9 +102,17 @@ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @Override public void onBindViewHolder(ViewHolder holder, int position) { final Result entity = mList.get(position); + + String mp3Url=entity.getEnMp3(); + if(TextUtils.isEmpty(mp3Url)){ + holder.ivSound.setVisibility(View.INVISIBLE); + }else { + holder.ivSound.setVisibility(View.VISIBLE); + } + holder.tvSrc.setText(entity.getQuery()); - if(!TextUtils.isEmpty(entity.getPhAm())){ - holder.tvPhonetic.setText("["+entity.getPhAm()+"]"); + if (!TextUtils.isEmpty(entity.getPhAm())) { + holder.tvPhonetic.setText("[" + entity.getPhAm() + "]"); } Observable.from(entity.getExplains()) .doOnSubscribe(new Action0() { @@ -94,20 +124,31 @@ public void call() { .subscribe(new Action1() { @Override public void call(String s) { - holder.llDst.addView(ViewUtil.getWordsView(mContext,s,R.color.gray_deep,false)); + holder.llDst.addView(ViewUtil.getWordsView(mContext, s, R.color.gray_deep, false)); } }); - holder.btAction.setText("删除"); - holder.btAction.setOnClickListener(v->{ - if(mOnClickListener!=null){ - mOnClickListener.onClickItem(v,entity); - } + + holder.ivMore.setOnClickListener(v -> { + showPopMenu(entity, v); }); + holder.llDst.setVisibility(isReciteMode ? View.GONE : View.VISIBLE); + holder.mRootView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + if (!holder.llDst.isShown()) { + holder.llDst.setVisibility(View.VISIBLE); + } + } + }); + holder.mRootWordLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String fileName = entity.getMp3FileName(); + String mp3Url = entity.getEnMp3(); + presenter.playSound(fileName, mp3Url); } }); } @@ -117,28 +158,78 @@ public int getItemCount() { return mList.size(); } - class ViewHolder extends RecyclerView.ViewHolder{ + /** + * @param isReciteMode 是不是背单词模式 + */ + public void updateReciteMode(boolean isReciteMode) { + this.isReciteMode = isReciteMode; + notifyDataSetChanged(); + } + + class ViewHolder extends RecyclerView.ViewHolder { private RelativeLayout mRootView; + private RelativeLayout mRootWordLayout; private TextView tvSrc; private TextView tvPhonetic; private LinearLayout llDst; - private Button btAction; + private ImageView ivMore; + private ImageView ivSound; + public ViewHolder(View itemView) { super(itemView); - mRootView = (RelativeLayout) itemView; - llDst = ButterKnife.findById(itemView,R.id.ll_pop_dst); - tvPhonetic = ButterKnife.findById(itemView,R.id.tv_pop_phonetic); - tvSrc = ButterKnife.findById(itemView,R.id.tv_pop_src); - btAction = ButterKnife.findById(itemView,R.id.bt_action); + mRootView = ButterKnife.findById(itemView, R.id.item_word_view); + mRootWordLayout = ButterKnife.findById(itemView, R.id.rl_words); + llDst = ButterKnife.findById(itemView, ll_pop_dst); + tvPhonetic = ButterKnife.findById(itemView, R.id.tv_pop_phonetic); + tvSrc = ButterKnife.findById(itemView, R.id.tv_pop_src); + ivMore = ButterKnife.findById(itemView, R.id.iv_over_flow); + ivSound=ButterKnife.findById(itemView,R.id.iv_sound); } } - public interface OnClick{ - void onClickItem(View view,Result entity); + public interface IClickPopupMenuItem { + void onClickMenuItem(int itemId, Result entity); } public List getData() { return mList; } + + + /** + * 显示弹出式菜单 + * + * @param entity + * @param ancho + */ + private void showPopMenu(final Result entity, View ancho) { + PopupMenu popupMenu = new PopupMenu(mContext, ancho); + popupMenu.getMenuInflater().inflate(R.menu.item_pop_menu, popupMenu.getMenu()); + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + if (mOnClickListener != null) { + mOnClickListener.onClickMenuItem(item.getItemId(), entity); + } + return false; + } + }); + + makePopForceShowIcon(popupMenu); + popupMenu.show(); + } + + //使用反射让popupMenu 显示菜单icon + private void makePopForceShowIcon(PopupMenu popupMenu) { + try { + Field mFieldPopup = popupMenu.getClass().getDeclaredField("mPopup"); + mFieldPopup.setAccessible(true); + MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu); + mPopup.setForceShowIcon(true); + } catch (Exception e) { + + } + } + } diff --git a/app/src/main/java/name/gudong/translate/util/AnswerUtil.java b/app/src/main/java/name/gudong/translate/util/AnswerUtil.java new file mode 100644 index 0000000..d6856b1 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/util/AnswerUtil.java @@ -0,0 +1,65 @@ +package name.gudong.translate.util; + +import android.os.Build; + +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.AnswersEvent; +import com.crashlytics.android.answers.ContentViewEvent; +import com.crashlytics.android.answers.CustomEvent; + +/** + * Created by mao on 2018/2/8. + */ + +public class AnswerUtil { + public static void trackClick(){} + + public static void showMainView(String translateType){ + ContentViewEvent event = new ContentViewEvent(); + event.putContentType(translateType); + Answers.getInstance().logContentView(event); + } + + public static void translateSuccess(){ + Answers.getInstance().logCustom(new CustomEvent("translateSuccess")); + } + + public static void actionShowAbout(){ + Answers.getInstance().logCustom(new CustomEvent("actionShowAbout")); + } + + /** + * 显示彩蛋 + */ + public static void showEggs(){ + Answers.getInstance().logCustom(new CustomEvent("showEggs")); + } + + public static void actionFavorite(String source){ + CustomEvent event = new CustomEvent("actionFavorite"); + event.putCustomAttribute("source",source); + Answers.getInstance().logCustom(event); + } + + public static void actionSound(String source){ + CustomEvent event = new CustomEvent("actionSound"); + event.putCustomAttribute("source",source); + Answers.getInstance().logCustom(event); + } + + public static void actionSupport(){ + Answers.getInstance().logCustom(new CustomEvent("actionSupport")); + } + + public static void actionSupportPay(){ + CustomEvent event = new CustomEvent("actionSupportPay"); + event.putCustomAttribute("device",Build.BRAND+"-"+Build.MODEL); + Answers.getInstance().logCustom(event); + } + + public static void translateFail(String msg){ + CustomEvent event = new CustomEvent("translateFail"); + event.putCustomAttribute("errorType",msg); + Answers.getInstance().logCustom(event); + } +} diff --git a/app/src/main/java/name/gudong/translate/util/DialogUtil.java b/app/src/main/java/name/gudong/translate/util/DialogUtil.java index a0e514b..ff129c9 100644 --- a/app/src/main/java/name/gudong/translate/util/DialogUtil.java +++ b/app/src/main/java/name/gudong/translate/util/DialogUtil.java @@ -11,6 +11,7 @@ import name.gudong.translate.R; import moe.feng.alipay.zerosdk.AlipayZeroSdk; +import name.gudong.translate.ui.activitys.MainActivity; import name.gudong.translate.widget.WebDialog; /** @@ -19,45 +20,54 @@ * Contact with gudong.name@gmail.com. */ public class DialogUtil { - public static void showAbout(AppCompatActivity activity,String title){ + public static void showAbout(AppCompatActivity activity, String title) { int accentColor = activity.getResources().getColor(R.color.colorAccent); - WebDialog.create(title, "about.html",accentColor) - .show(activity.getSupportFragmentManager(), "about"); + WebDialog.create(title, "about.html", accentColor) + .show(activity.getSupportFragmentManager(), "about"); } - public static void showAboutDonate(AppCompatActivity activity){ + public static void showAboutDonate(AppCompatActivity activity) { int accentColor = activity.getResources().getColor(R.color.colorAccent); - WebDialog.create( "关于捐赠", "about_donate.html",accentColor) - .show(activity.getSupportFragmentManager(), "about"); + WebDialog.create("关于捐赠", "about_donate.html", accentColor) + .show(activity.getSupportFragmentManager(), "about"); } - public static void showChangelog(AppCompatActivity activity){ + public static void showChangelog(AppCompatActivity activity) { int accentColor = activity.getResources().getColor(R.color.colorAccent); - WebDialog.create("更新日志", "changelog.html",accentColor) - .show(activity.getSupportFragmentManager(), "changelog");; + WebDialog.create("更新日志", "changelog.html", accentColor) + .show(activity.getSupportFragmentManager(), "changelog"); + ; } - public static void showSupport(AppCompatActivity activity){ + public static void showGuideFloatTranslate(AppCompatActivity activity) { + showCustomDialogWithTwoAction(activity, activity.getSupportFragmentManager(), + "什么是划词翻译", + "about_float_translate.html", + "introduce", + "已了解", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + SpUtils.setHasShowGuideFlag(activity, true); + } + }, + "查看介绍文章", + (dialog, which) -> { + Utils.openUrl(activity, "http://gudong.name/product/2016/02/26/gudong_translate.html"); + }); + + } + + public static void showSupport(AppCompatActivity activity) { showCustomDialogWithTwoAction(activity, activity.getSupportFragmentManager(), "支持开发者", "donate_ch.html", "donate", "关闭", ((dialog1, which1) -> MobclickAgent.onEvent(activity, "menu_support_close")), "打开支付宝转账页面", (dialog, which) -> { MobclickAgent.onEvent(activity, "menu_support_click"); -// String alipay = "com.eg.android.AlipayGphone"; -// //复制到粘贴板 -// ClipboardManager cmb = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); -// cmb.setPrimaryClip(ClipData.newPlainText(null, "gudong.name@gmail.com")); -// Toast.makeText(activity, activity.getString(R.string.copy_success), Toast.LENGTH_LONG).show(); - //打开支付宝 -// try { -// Intent intent = activity.getPackageManager().getLaunchIntentForPackage(alipay); -// activity.startActivity(intent); -// } catch (Exception e) { -// Toast.makeText(activity, activity.getString(R.string.support_fail), Toast.LENGTH_LONG).show(); -// } - if(AlipayZeroSdk.hasInstalledAlipayClient(activity)){ + AnswerUtil.actionSupportPay(); + if (AlipayZeroSdk.hasInstalledAlipayClient(activity)) { AlipayZeroSdk.startAlipayClient(activity, "aex07094cljuqa36ku7ml36"); - }else{ + } else { MobclickAgent.onEvent(activity, "menu_support_click_but_have_not_alipay"); Toast.makeText(activity, activity.getString(R.string.support_fail_because_not_install), Toast.LENGTH_LONG).show(); } @@ -70,15 +80,7 @@ public static void showCustomDialogWithTwoAction( String positiveText, DialogInterface.OnClickListener positiveListener, String neutralText, DialogInterface.OnClickListener neutralListener) { int accentColor = context.getResources().getColor(R.color.colorAccent); - WebDialog.create(dialogTitle, htmlFileName, accentColor,positiveText,positiveListener,neutralText,neutralListener) + WebDialog.create(dialogTitle, htmlFileName, accentColor, positiveText, positiveListener, neutralText, neutralListener) .show(fragmentManager, tag); } - - public static void showSingleMessage(AppCompatActivity activity,String message,String positive){ - new AlertDialog.Builder(activity) - .setTitle("提示") - .setMessage(message) - .setPositiveButton(positive,null) - .show(); - } } diff --git a/app/src/main/java/name/gudong/translate/util/HeadsUps.java b/app/src/main/java/name/gudong/translate/util/HeadsUps.java deleted file mode 100644 index 0f42ecb..0000000 --- a/app/src/main/java/name/gudong/translate/util/HeadsUps.java +++ /dev/null @@ -1,41 +0,0 @@ -package name.gudong.translate.util; - -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.BitmapFactory; -import android.os.Build; - -import com.mingle.headsUp.HeadsUp; -import com.mingle.headsUp.HeadsUpManager; - -public class HeadsUps { - - public static void show(Context context, Intent intent, String title, String content, int largeIcon, int smallIcon, int code) { - PendingIntent pendingIntent = PendingIntent.getActivity(context, 11, - intent, PendingIntent.FLAG_UPDATE_CURRENT); - - HeadsUpManager manage = HeadsUpManager.getInstant(context); - HeadsUp.Builder builder = new HeadsUp.Builder(context); - builder.setContentTitle(title) - .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS) - .setContentIntent(pendingIntent) - .setFullScreenIntent(pendingIntent, false) - .setAutoCancel(true) - .setContentText(content); - - if (Build.VERSION.SDK_INT >= 21) { - builder.setLargeIcon( - BitmapFactory.decodeResource(context.getResources(), largeIcon)) - .setSmallIcon(smallIcon); - } - else { - builder.setSmallIcon(largeIcon); - } - - HeadsUp headsUp = builder.buildHeadUp(); - headsUp.setSticky(true); - manage.notify(code, headsUp); - } -} \ No newline at end of file diff --git a/app/src/main/java/name/gudong/translate/util/LocalDicHelper.java b/app/src/main/java/name/gudong/translate/util/LocalDicHelper.java new file mode 100644 index 0000000..945c2be --- /dev/null +++ b/app/src/main/java/name/gudong/translate/util/LocalDicHelper.java @@ -0,0 +1,43 @@ +package name.gudong.translate.util; + +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import com.readystatesoftware.sqliteasset.SQLiteAssetHelper; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by 70kg on 2017/6/2 + * LocalDicHelper + */ +public class LocalDicHelper extends SQLiteAssetHelper { + public static final String DATABASE_NAME = "sample_oxford"; + private static final int DATABASE_VERSION = 1; + public static final String COL_WORD = "word"; + + public LocalDicHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + public static List getLocalDic(Context context) { + List list = new ArrayList<>(); + SQLiteDatabase reader = new LocalDicHelper(context).getReadableDatabase(); + reader.beginTransaction(); + try { + Cursor c = reader.query(LocalDicHelper.DATABASE_NAME, new String[]{COL_WORD}, null, null, null, null, null); + while (c.moveToNext()) { + list.add(c.getString(c.getColumnIndex(LocalDicHelper.COL_WORD))); + } + reader.setTransactionSuccessful(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + reader.endTransaction(); + reader.close(); + } + return list; + } +} diff --git a/app/src/main/java/name/gudong/translate/util/SpUtils.java b/app/src/main/java/name/gudong/translate/util/SpUtils.java index d5fcbfe..aec8d70 100644 --- a/app/src/main/java/name/gudong/translate/util/SpUtils.java +++ b/app/src/main/java/name/gudong/translate/util/SpUtils.java @@ -44,6 +44,7 @@ public static String getUrlByLocalSetting(){ } private static final String KEY_TRANSLATE_FROM = "TRANSLATE_FROM"; + private static final String KEY_WORDBOOK_RECITE_MODE = "WORDBOOK_RECITE_MODE"; //every tip's interval time public static final String KEY_INTERVAL_TIP_TIME = "INTERVAL_TIP_TIME"; @@ -60,14 +61,17 @@ public static String getUrlByLocalSetting(){ //is notify dayline private static final String KEY_PREFERENCE_AUTO_PASTE = "preference_auto_paste_words"; + private static final String KEY_PREFERENCE_AUTO_COMPLETE_INPUT = "preference_open_auto_complete_input"; + //App 是否在前台 private static final String KEY_FLAG_APP_FRONT = "FLAG_LISTENER_CLIPBOARD"; - //是否授予 Android M 浮窗权限 - private static final String KEY_DRAW_OVERLAYS_PERMISSION = "DRAW_OVERLAYS_PERMISSION"; + //是否已经显示过用户引导 + private static final String KEY_HAS_SHOW_GUIDE = "HAS_SHOW_GUIDE"; + - public static void setTranslateEngine(Context context, String version) { - putStringPreference(context, KEY_TRANSLATE_FROM, version); + public static void setTranslateEngine(Context context, ETranslateFrom way) { + putStringPreference(context, KEY_TRANSLATE_FROM, way.name()); } public static String getTranslateEngine(Context context) { @@ -87,14 +91,16 @@ public static boolean isShowIconInNotification(Context context){ return getBooleanPreference(context,KEY_PREFERENCE_SHOW_ICON_IN_NOTIFICATION,false); } - public static boolean isNotifyDayline(Context context){ - return getBooleanPreference(context,KEY_PREFERENCE_NOTIFY_DAYLINE,true); + return getBooleanPreference(context,KEY_PREFERENCE_NOTIFY_DAYLINE,false); } public static boolean isAutoPasteWords(Context context){ return getBooleanPreference(context,KEY_PREFERENCE_AUTO_PASTE,false); } + public static boolean isAutoCompleteInputWords(Context context){ + return getBooleanPreference(context,KEY_PREFERENCE_AUTO_COMPLETE_INPUT,false); + } public static boolean getOpenJITOrNot(Context context){ return getBooleanPreference(context,KEY_OPEN_JIT,true); @@ -109,15 +115,23 @@ public static boolean getAppFront(Context context){ return getBooleanPreference(context, KEY_FLAG_APP_FRONT,false); } - //设置是否匹配权限 - public static void setDrawOverlays(Context context,boolean isOpen){ - putBooleanPreference(context, KEY_DRAW_OVERLAYS_PERMISSION,isOpen); + public static boolean hasShowGuide(Context context){ + return getBooleanPreference(context, KEY_HAS_SHOW_GUIDE,false); } - public static boolean hasGrantDrawOverlays(Context context){ - return getBooleanPreference(context, KEY_DRAW_OVERLAYS_PERMISSION,false); + public static void setHasShowGuideFlag(Context context,boolean isShow){ + putBooleanPreference(context,KEY_HAS_SHOW_GUIDE,isShow); } + public static void setWordBookReciteMode(Context context,boolean isReciteMode){ + putBooleanPreference(context,KEY_WORDBOOK_RECITE_MODE,isReciteMode); + } + + public static boolean isWordBookReciteMode(Context context){ + return getBooleanPreference(context,KEY_WORDBOOK_RECITE_MODE,false); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////////// // ------------------- SharePreference Util Begin ------------------- // diff --git a/app/src/main/java/name/gudong/translate/util/Utils.java b/app/src/main/java/name/gudong/translate/util/Utils.java index 6606f89..4e1c712 100644 --- a/app/src/main/java/name/gudong/translate/util/Utils.java +++ b/app/src/main/java/name/gudong/translate/util/Utils.java @@ -6,7 +6,9 @@ import android.content.Context; import android.content.Intent; import android.graphics.Color; +import android.net.Uri; import android.os.Build; +import android.provider.Settings; import android.support.v4.app.NotificationCompat; import org.json.JSONArray; @@ -92,25 +94,33 @@ public static String getVersionName(Context context) { } } - public static int[] getCurrentTime(){ + public static void openUrl(Context context, String url) { + Uri uri = Uri.parse(url); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + context.startActivity(intent); + } + + public static int[] getCurrentTime() { Calendar now = Calendar.getInstance(); now.setTimeInMillis(System.currentTimeMillis()); - int[]time = new int[3]; + int[] time = new int[3]; time[0] = now.get(Calendar.HOUR_OF_DAY); time[1] = now.get(Calendar.MINUTE); time[2] = now.get(Calendar.SECOND); return time; } - public static void shareText(Context context, String text){ + public static void shareText(Context context, String text) { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_TEXT,text); + sendIntent.putExtra(Intent.EXTRA_TEXT, text); sendIntent.setType("text/plain"); context.startActivity(Intent.createChooser(sendIntent, "发送")); } + /** * check test string is json format or not + * * @param test content * @return true if it is format by json else return false */ @@ -126,4 +136,18 @@ public static boolean isJSONFormat(String test) { } return true; } + + public static int dp2px(Context context, float dpValue) { + final float scale = context.getResources().getDisplayMetrics().density; + return (int) (dpValue * scale + 0.5f); + } + + /** + * @param context to get preference + * @return true on granted, false on fail + */ + public static boolean checkDrawOverlaysPermissionGranted(Context context) { + //The result of `Settings.canDrawOverlays(context)` should not be saved, because you never know when your user would modify it + return !Utils.isAndroidM() || Settings.canDrawOverlays(context); + } } diff --git a/app/src/main/java/name/gudong/translate/util/ViewUtil.java b/app/src/main/java/name/gudong/translate/util/ViewUtil.java index 78987bd..fcaceda 100644 --- a/app/src/main/java/name/gudong/translate/util/ViewUtil.java +++ b/app/src/main/java/name/gudong/translate/util/ViewUtil.java @@ -49,7 +49,7 @@ public static View getWordsView(Context context,String word,@ColorRes int color, TextView tv = new TextView(context); tv.setTextColor(ContextCompat.getColor(context, color)); tv.setPadding(0,6,0,6); - tv.setTextSize(16); + tv.setTextSize(14); tv.setTextIsSelectable(isTextSelectable); tv.setGravity(Gravity.LEFT); tv.setText(word); diff --git a/app/src/main/java/name/gudong/translate/widget/DividerItemDecoration.java b/app/src/main/java/name/gudong/translate/widget/DividerItemDecoration.java new file mode 100644 index 0000000..6bb7900 --- /dev/null +++ b/app/src/main/java/name/gudong/translate/widget/DividerItemDecoration.java @@ -0,0 +1,64 @@ +package name.gudong.translate.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +public class DividerItemDecoration extends RecyclerView.ItemDecoration { + private static final int[]ATTRS = new int[]{android.R.attr.listDivider}; + public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; + public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; + private Drawable mDivider; + private int mOrientation; + + public DividerItemDecoration(Context context, int orientation) { + final TypedArray array = context.obtainStyledAttributes(ATTRS); + mDivider = array.getDrawable(0); + array.recycle(); +// mDivider = ContextCompat.getDrawable(context, R.drawable.item_divider_black); + setOrientation(orientation); + } + + private void setOrientation(int orientation) { + if(orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST){ + throw new IllegalArgumentException("invalid orientation"); + } + mOrientation = orientation; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + super.onDraw(c, parent, state); + if(mOrientation == VERTICAL_LIST){ + drawVertical(c, parent); + } + } + + private void drawVertical(Canvas c, RecyclerView parent){ + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth()-parent.getPaddingRight(); + + int childCount = parent.getChildCount(); + for(int i = 0;i - + \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png deleted file mode 100644 index da56077..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_info_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png deleted file mode 100644 index e200012..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_notifications_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png b/app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png deleted file mode 100644 index a5ebdbd..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_sync_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png deleted file mode 100644 index 5ef3dc0..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_info_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png deleted file mode 100644 index b36475d..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_notifications_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png b/app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png deleted file mode 100644 index 9685e8e..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_sync_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png deleted file mode 100644 index 46ed12a..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_info_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png deleted file mode 100644 index 7de8581..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_notifications_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png b/app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png deleted file mode 100644 index 860a5db..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_sync_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png deleted file mode 100644 index a81eeb9..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_info_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png deleted file mode 100644 index ab8a9c4..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_notifications_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png deleted file mode 100644 index f799008..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_sync_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png deleted file mode 100644 index c8f86b9..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_info_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png deleted file mode 100644 index 86f89d7..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_notifications_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png deleted file mode 100644 index b9f56f3..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_sync_black_24dp.png and /dev/null differ diff --git a/app/src/main/res/drawable/header.png b/app/src/main/res/drawable/header.png new file mode 100644 index 0000000..63ecf96 Binary files /dev/null and b/app/src/main/res/drawable/header.png differ diff --git a/app/src/main/res/drawable/ic_delete_black_24dp.xml b/app/src/main/res/drawable/ic_delete_black_24dp.xml new file mode 100644 index 0000000..39e64d6 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_more_vert_black_24dp.xml b/app/src/main/res/drawable/ic_more_vert_black_24dp.xml new file mode 100644 index 0000000..5176d8a --- /dev/null +++ b/app/src/main/res/drawable/ic_more_vert_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_youtube_searched_for_black_24dp.xml b/app/src/main/res/drawable/ic_youtube_searched_for_black_24dp.xml new file mode 100644 index 0000000..ff5b0b0 --- /dev/null +++ b/app/src/main/res/drawable/ic_youtube_searched_for_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/profile_circle_for_donate.png b/app/src/main/res/drawable/profile_circle_for_donate.png new file mode 100644 index 0000000..88c3ed8 Binary files /dev/null and b/app/src/main/res/drawable/profile_circle_for_donate.png differ diff --git a/app/src/main/res/drawable/selector_action_search.xml b/app/src/main/res/drawable/selector_action_search.xml index 0641234..b11e1bb 100644 --- a/app/src/main/res/drawable/selector_action_search.xml +++ b/app/src/main/res/drawable/selector_action_search.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_over_flow.xml b/app/src/main/res/drawable/selector_over_flow.xml new file mode 100644 index 0000000..0916868 --- /dev/null +++ b/app/src/main/res/drawable/selector_over_flow.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/seven_kg.jpeg b/app/src/main/res/drawable/seven_kg.jpeg new file mode 100644 index 0000000..764c073 Binary files /dev/null and b/app/src/main/res/drawable/seven_kg.jpeg differ diff --git a/app/src/main/res/drawable/shape_circle_grey.xml b/app/src/main/res/drawable/shape_circle_grey.xml new file mode 100644 index 0000000..cb4d9cb --- /dev/null +++ b/app/src/main/res/drawable/shape_circle_grey.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/zt.jpeg b/app/src/main/res/drawable/zt.jpeg new file mode 100644 index 0000000..f9d9403 Binary files /dev/null and b/app/src/main/res/drawable/zt.jpeg differ diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8687876..2ddc203 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -28,6 +28,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" + android:textSize="@dimen/ff.textSize.text" + android:textColor="@color/ff.textColor.shadowTitle" android:text="@string/point_input_key" /> - @@ -101,7 +104,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="翻译结果" - android:textColor="#999999" /> + android:textSize="@dimen/ff.textSize.text" + android:textColor="@color/ff.textColor.shadowTitle" /> + android:animateLayoutChanges="true" + android:paddingTop="@dimen/md_content_padding_top" + android:paddingBottom="@dimen/md_content_padding_top" + android:paddingLeft="16dp" + android:background="?attr/selectableItemBackground"> - -