├── .gitignore ├── README.md ├── WechatLuckyMoney ├── .gitignore ├── .idea │ ├── assetWizardSettings.xml │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── misc.xml │ ├── modules.xml │ └── runConfigurations.xml ├── apk │ └── release │ │ ├── v1.0_release.apk │ │ └── v2.0_release.apk ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── max │ │ │ └── wechatluckymoney │ │ │ └── ApplicationTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-web.png │ │ ├── java │ │ │ └── com │ │ │ │ └── max │ │ │ │ └── wechatluckymoney │ │ │ │ ├── activitys │ │ │ │ ├── LoadingActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── SettingActivity.java │ │ │ │ └── WebViewActivity.java │ │ │ │ ├── app │ │ │ │ ├── App.java │ │ │ │ └── Constants.java │ │ │ │ ├── base │ │ │ │ └── BaseActivity.java │ │ │ │ ├── fragments │ │ │ │ └── GeneralSettingsFragment.java │ │ │ │ ├── services │ │ │ │ ├── HandlerHelper.java │ │ │ │ ├── LuckyMoneyService.java │ │ │ │ └── handler │ │ │ │ │ ├── AccessibilityHandler.java │ │ │ │ │ ├── AccessibilityHandlerListener.java │ │ │ │ │ ├── base │ │ │ │ │ ├── ChatDetailsHandler.java │ │ │ │ │ ├── HomeChatHandler.java │ │ │ │ │ ├── RedPacketGetHandler.java │ │ │ │ │ └── RedPacketGetRecordHandler.java │ │ │ │ │ ├── seven_zero_zero │ │ │ │ │ ├── SzzChatDetailsHandler.java │ │ │ │ │ ├── SzzHomeChatHandler.java │ │ │ │ │ ├── SzzRedPacketGetHandler.java │ │ │ │ │ └── SzzRedPacketGetRecordHandler.java │ │ │ │ │ └── six_six_three │ │ │ │ │ ├── SstChatDetailsHandler.java │ │ │ │ │ ├── SstHomeChatHandler.java │ │ │ │ │ ├── SstRedPacketGetHandler.java │ │ │ │ │ └── SstRedPacketGetRecordHandler.java │ │ │ │ ├── support │ │ │ │ ├── FloatingHelper.java │ │ │ │ ├── OpenRedPacketDelayTask.java │ │ │ │ └── enums │ │ │ │ │ └── WidgetType.java │ │ │ │ ├── utils │ │ │ │ ├── AccessibilityNodeUtils.java │ │ │ │ ├── AppUtils.java │ │ │ │ ├── DebugUtils.java │ │ │ │ ├── L.java │ │ │ │ ├── ScreenUtils.java │ │ │ │ └── Utils.java │ │ │ │ └── view │ │ │ │ ├── FloatingView.java │ │ │ │ └── dialog │ │ │ │ └── SeekBarPreference.java │ │ └── res │ │ │ ├── drawable │ │ │ ├── bg_circle_switch_off.xml │ │ │ ├── bg_circle_switch_on.xml │ │ │ ├── icon_max.jpg │ │ │ └── progress_web.xml │ │ │ ├── layout │ │ │ ├── activity_loading.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_preferences.xml │ │ │ ├── activity_webview.xml │ │ │ ├── layout_floating.xml │ │ │ ├── preference_category.xml │ │ │ ├── preference_checkbox.xml │ │ │ └── preference_seekbar.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_browser.png │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── bg_snow.png │ │ │ ├── ic_back.png │ │ │ ├── ic_community.png │ │ │ ├── ic_github.png │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ ├── ic_launcher_round.png │ │ │ ├── ic_settings.png │ │ │ ├── ic_start.png │ │ │ ├── ic_start_floating.png │ │ │ ├── ic_start_floating_2.png │ │ │ └── ic_stop.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_setting.png │ │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ ├── general_preferences.xml │ │ │ ├── lucky_money_service_config.xml │ │ │ └── provider_paths.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── max │ │ └── wechatluckymoney │ │ └── ExampleUnitTest.java ├── build.gradle ├── build_system │ └── LuckyMoney.jks ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── loadingIndicator │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── wang │ │ │ └── avi │ │ │ └── ApplicationTest.java │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ └── com │ │ │ └── wang │ │ │ └── avi │ │ │ ├── AVLoadingIndicatorView.java │ │ │ ├── Indicator.java │ │ │ └── indicators │ │ │ ├── BallBeatIndicator.java │ │ │ ├── BallClipRotateIndicator.java │ │ │ ├── BallClipRotateMultipleIndicator.java │ │ │ ├── BallClipRotatePulseIndicator.java │ │ │ ├── BallGridBeatIndicator.java │ │ │ ├── BallGridPulseIndicator.java │ │ │ ├── BallPulseIndicator.java │ │ │ ├── BallPulseRiseIndicator.java │ │ │ ├── BallPulseSyncIndicator.java │ │ │ ├── BallRotateIndicator.java │ │ │ ├── BallScaleIndicator.java │ │ │ ├── BallScaleMultipleIndicator.java │ │ │ ├── BallScaleRippleIndicator.java │ │ │ ├── BallScaleRippleMultipleIndicator.java │ │ │ ├── BallSpinFadeLoaderIndicator.java │ │ │ ├── BallTrianglePathIndicator.java │ │ │ ├── BallZigZagDeflectIndicator.java │ │ │ ├── BallZigZagIndicator.java │ │ │ ├── CubeTransitionIndicator.java │ │ │ ├── LineScaleIndicator.java │ │ │ ├── LineScalePartyIndicator.java │ │ │ ├── LineScalePulseOutIndicator.java │ │ │ ├── LineScalePulseOutRapidIndicator.java │ │ │ ├── LineSpinFadeLoaderIndicator.java │ │ │ ├── PacmanIndicator.java │ │ │ ├── SemiCircleSpinIndicator.java │ │ │ ├── SquareSpinIndicator.java │ │ │ └── TriangleSkewSpinIndicator.java │ │ └── res │ │ └── values │ │ ├── attrs.xml │ │ ├── strings.xml │ │ └── style.xml └── settings.gradle └── resources ├── apk └── release │ ├── v1.0_release.apk │ └── v2.0_release.apk └── image └── demo.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | WechatLuckyMoney/.idea/codeStyles/Project.xml 24 | WechatLuckyMoney/.idea/caches/build_file_checksums.ser 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 微信红包 3 | 帮助你更快速方便的抢红包 4 | 5 | ![image](https://github.com/xxxls/resources/raw/master/WechatLuckyMoney/image/demo.gif) 6 |   7 | 8 | ## 下载 9 | 10 | * [v1.0_release.APK](https://github.com/xxxls/resources/raw/master/WechatLuckyMoney/apk/v1.0_release.apk)(适配微信6.6.3). 11 | 12 | * [v2.0_release.APK](https://github.com/xxxls/WechatLuckyMoney/releases/download/v2.0-GA/v2.0_release.apk)(适配微信7.0.0). 13 | 14 |   15 | 16 | 17 | ## 特性 18 | 19 | * 检测聊天列表、聊天页面 红包并自动打开 20 | 21 | * 自定义过滤红包,延时领取等功能 22 | 23 | * 悬浮开关,方便停用开启插件 24 | 25 | * 轻量安全、无需Root等权限,代码公开 26 | 27 |   28 | 29 | ## 使用教程 30 | 31 | * 检查手机系统是否 4.3及以上版本 32 | 33 | * 打开APP,点击开启按钮 34 | 35 | * 根据提示,进入系统辅助功能页面,授权于本APP 36 | 37 | * 进入微信 聊天列表、或聊天详情页面 38 | 39 | * 无需其他操作,坐等红包 40 | 41 |   42 | 43 | ## 更新日志 44 | 45 | #### [v1.0](https://github.com/xxxls/resources/raw/master/WechatLuckyMoney/apk/v1.0_release.apk)(2018-2-12) 46 | > ###### 监视首页列表、聊天详情页 发现红包自动领取 47 | > ###### 悬浮操作按钮 快速启动或暂停 48 | > ###### 适配微信6.6.3版本 49 | 50 |   51 | 52 | #### [v2.0](https://github.com/xxxls/WechatLuckyMoney/releases/download/v2.0-GA/v2.0_release.apk)(2019-1-12) 53 | > ###### 新加是否拆开自己红包功能 54 | > ###### 新加延时拆红包功能 55 | > ###### 新加根据红包文字忽略领取功能 56 | > ###### 新加根据聊天对象忽略领取功能 57 | > ###### 新加是否持续监视首页列表功能 58 | > ###### 适配微信7.0.0版本,继续兼容6.6.3版本 59 | 60 |   61 | 62 | ## 版权及免责声明 63 | 64 | * 本项目参考借鉴 [geeeeeeeeek/WeChatLuckyMoney](https://github.com/geeeeeeeeek/WeChatLuckyMoney) . 65 | 66 | * 插件可能会在一定程度上改变微信的交互方式。使用本项目中包含的代码及其生成物时,使用者自行承担随之而来的各种风险,包括但不限于“禁用红包功能”、“微信封号”。 67 | 68 |   69 | 70 | ## 其他 71 | 72 | * 微信每次版本发布都会造成兼容性问题,可能无法正常使用本插件。 73 | 74 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/assetWizardSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 56 | 57 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 22 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /WechatLuckyMoney/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /WechatLuckyMoney/apk/release/v1.0_release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/apk/release/v1.0_release.apk -------------------------------------------------------------------------------- /WechatLuckyMoney/apk/release/v2.0_release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/apk/release/v2.0_release.apk -------------------------------------------------------------------------------- /WechatLuckyMoney/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | 4 | 5 | android { 6 | 7 | compileSdkVersion rootProject.ext.compileSdkVersion 8 | buildToolsVersion '28.0.3' 9 | 10 | defaultConfig { 11 | applicationId "com.max.wechatluckymoney" 12 | minSdkVersion rootProject.ext.minSdkVersion 13 | targetSdkVersion rootProject.ext.targetSdkVersion 14 | flavorDimensions rootProject.ext.flavorDimensions 15 | versionCode 2 16 | versionName "2.0" 17 | 18 | ndk { 19 | //设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so) 20 | abiFilters "armeabi", "armeabi-v7a", "x86" 21 | // abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64" 22 | } 23 | } 24 | 25 | dataBinding { 26 | enabled true 27 | } 28 | 29 | compileOptions { 30 | sourceCompatibility JavaVersion.VERSION_1_8 31 | targetCompatibility JavaVersion.VERSION_1_8 32 | } 33 | 34 | 35 | signingConfigs { 36 | config { 37 | storePassword "LuckyMoney" 38 | keyAlias "Money" 39 | keyPassword "LuckyMoney" 40 | storeFile file('../build_system/LuckyMoney.jks') 41 | } 42 | } 43 | 44 | buildTypes { 45 | release { 46 | minifyEnabled true 47 | shrinkResources true 48 | zipAlignEnabled true 49 | buildConfigField "boolean", "LOG_DEBUG", "false" 50 | debuggable false 51 | jniDebuggable false 52 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 53 | signingConfig signingConfigs.config 54 | } 55 | debug { 56 | minifyEnabled false 57 | shrinkResources false 58 | zipAlignEnabled false 59 | versionNameSuffix "_debug" 60 | debuggable true 61 | jniDebuggable true 62 | buildConfigField "boolean", "LOG_DEBUG", "true" 63 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 64 | signingConfig signingConfigs.config 65 | } 66 | 67 | applicationVariants.all { variant -> 68 | variant.outputs.all { output -> // each 改为 all 69 | def outputFile = output.outputFile 70 | if (outputFile != null && outputFile.name.endsWith('.apk')) { 71 | // apk_渠道名-版本号-版本名称-编译时间.apk // 72 | def fileName = "lucky_money_${defaultConfig.versionCode}_V${defaultConfig.versionName}_${releaseTime()}_${variant.buildType.name}.apk" 73 | outputFileName = fileName; 74 | } 75 | } 76 | } 77 | } 78 | 79 | } 80 | 81 | dependencies { 82 | implementation fileTree(include: ['*.jar'], dir: 'libs') 83 | testImplementation "junit:junit:$rootProject.ext.junitVersion" 84 | //LOG日志 85 | implementation 'com.orhanobut:logger:2.1.1' 86 | implementation "com.android.support:support-v4:$rootProject.ext.supportLibraryVersion" 87 | implementation "com.android.support:appcompat-v7:$rootProject.ext.supportLibraryVersion" 88 | // ButterKnife注解库:https://github.com/JakeWharton/butterknife 89 | implementation "com.jakewharton:butterknife:$rootProject.ext.butterknifeVersion" 90 | annotationProcessor "com.jakewharton:butterknife-compiler:$rootProject.ext.butterknifeVersion" 91 | //loading https://github.com/81813780/AVLoadingIndicatorView 92 | implementation project(':loadingIndicator') 93 | 94 | // 权限请求框架:https://github.com/getActivity/XXPermissions 95 | api 'com.hjq:xxpermissions:5.2' 96 | 97 | 98 | implementation 'com.tencent.bugly:crashreport_upgrade:latest.release' 99 | //其中latest.release指代最新版本号,也可以指定明确的版本号,例如1.0.1 100 | implementation 'com.tencent.bugly:nativecrashreport:latest.release' 101 | //其中latest.release指代最新版本号,也可以指定明确的版本号,例如2.2.0 102 | } 103 | 104 | def releaseTime() { 105 | return new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+08:00")) 106 | } 107 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\Software\AndroidSDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | #权限 19 | -dontwarn com.hjq.permissions.** 20 | 21 | #加载view 22 | -keep class com.wang.avi.** { *; } 23 | -keep class com.wang.avi.indicators.** { *; } 24 | 25 | #bugly 26 | -dontwarn com.tencent.bugly.** 27 | -keep public class com.tencent.bugly.**{*;} 28 | -keep class android.support.**{*;} -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/androidTest/java/com/max/wechatluckymoney/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase 10 | { 11 | public ApplicationTest() 12 | { 13 | super(Application.class); 14 | } 15 | } -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 47 | 48 | 49 | 50 | 54 | 55 | 60 | 63 | 64 | 65 | 68 | 69 | 70 | 71 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/activitys/LoadingActivity.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.activitys; 2 | 3 | 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.os.Handler; 8 | import android.os.HandlerThread; 9 | import android.support.annotation.Nullable; 10 | import android.support.v7.app.AppCompatActivity; 11 | import android.widget.Toast; 12 | 13 | import com.max.wechatluckymoney.R; 14 | 15 | /** 16 | * Created by Max on 2018/2/10. 17 | * 加载进度 18 | */ 19 | 20 | public class LoadingActivity extends AppCompatActivity 21 | { 22 | 23 | public static Intent getInstance(Context context) 24 | { 25 | return new Intent(context, LoadingActivity.class); 26 | } 27 | 28 | @Override 29 | protected void onCreate(@Nullable Bundle savedInstanceState) 30 | { 31 | super.onCreate(savedInstanceState); 32 | setContentView(R.layout.activity_loading); 33 | 34 | new Handler().postDelayed(() -> finish(), 100); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/activitys/SettingActivity.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.activitys; 2 | 3 | import android.app.FragmentManager; 4 | import android.app.FragmentTransaction; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.provider.Settings; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | import com.max.wechatluckymoney.R; 12 | import com.max.wechatluckymoney.base.BaseActivity; 13 | import com.max.wechatluckymoney.fragments.GeneralSettingsFragment; 14 | 15 | /** 16 | * Created by max on 2018/2/9. 17 | * 设置 18 | */ 19 | public class SettingActivity extends BaseActivity 20 | { 21 | 22 | public static Intent getInstance(Context context) 23 | { 24 | Intent intent = new Intent(context, SettingActivity.class); 25 | return intent; 26 | } 27 | 28 | @Override 29 | protected void onInitialize() 30 | { 31 | initView(); 32 | } 33 | 34 | @Override 35 | protected int getLayoutResId() 36 | { 37 | return R.layout.activity_preferences; 38 | } 39 | 40 | private void initView() 41 | { 42 | 43 | TextView textView = (TextView) findViewById(R.id.settings_bar); 44 | textView.setText(R.string.preference); 45 | 46 | FragmentManager fragmentManager = getFragmentManager(); 47 | FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 48 | 49 | fragmentTransaction.replace(R.id.preferences_fragment, GeneralSettingsFragment.getInstance()); 50 | fragmentTransaction.commit(); 51 | } 52 | 53 | 54 | public void jumpAccessibilityPage(View view) 55 | { 56 | Intent mAccessibleIntent = 57 | new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); 58 | startActivity(mAccessibleIntent); 59 | } 60 | 61 | public void performBack(View view) { 62 | super.onBackPressed(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/app/App.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.app; 2 | 3 | import android.app.Application; 4 | 5 | import com.max.wechatluckymoney.utils.DebugUtils; 6 | import com.max.wechatluckymoney.utils.Utils; 7 | import com.tencent.bugly.Bugly; 8 | import com.tencent.bugly.crashreport.CrashReport; 9 | 10 | /** 11 | * Created by Max on 2019/1/5. 12 | */ 13 | public class App extends Application { 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | 18 | //是否debug 初始化 19 | DebugUtils.syncIsDebug(this); 20 | 21 | Bugly.init(getApplicationContext(), "4e99088771", false); 22 | Bugly.setAppChannel(this, "wechat_version" + Utils.getWeChatVersion(this)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/app/Constants.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.app; 2 | 3 | 4 | /** 5 | * Created by max on 2018/2/09. 6 | */ 7 | public interface Constants 8 | { 9 | 10 | /** 11 | * 开关 12 | */ 13 | String KEY_SWITCH = "key_service_switch"; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/base/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.base; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.os.Bundle; 6 | import android.support.annotation.ColorRes; 7 | import android.support.annotation.LayoutRes; 8 | import android.support.annotation.Nullable; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.view.Window; 13 | import android.view.WindowManager; 14 | 15 | import com.max.wechatluckymoney.R; 16 | 17 | import butterknife.ButterKnife; 18 | import butterknife.Unbinder; 19 | 20 | /** 21 | * Created by max on 2018/2/9. 22 | */ 23 | public abstract class BaseActivity extends AppCompatActivity 24 | { 25 | private Unbinder mUnbinder; 26 | 27 | @Override 28 | protected void onCreate(@Nullable Bundle savedInstanceState) 29 | { 30 | super.onCreate(savedInstanceState); 31 | try 32 | { 33 | setContentView(getLayoutResId()); 34 | setStatusBarColor(R.color.colorPrimaryDark); 35 | onInitialize(); 36 | } catch (Exception e) 37 | { 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | @Override 43 | public void setContentView(@LayoutRes int layoutResID) 44 | { 45 | super.setContentView(layoutResID); 46 | mUnbinder = ButterKnife.bind(this); 47 | } 48 | 49 | @Override 50 | public void setContentView(View view) 51 | { 52 | super.setContentView(view); 53 | mUnbinder = ButterKnife.bind(this); 54 | } 55 | 56 | @Override 57 | public void setContentView(View view, ViewGroup.LayoutParams params) 58 | { 59 | super.setContentView(view, params); 60 | mUnbinder = ButterKnife.bind(this); 61 | } 62 | 63 | @Override 64 | protected void onDestroy() 65 | { 66 | if (mUnbinder != null) mUnbinder.unbind(); 67 | super.onDestroy(); 68 | } 69 | 70 | 71 | /** 72 | * 初始化 73 | */ 74 | protected abstract void onInitialize(); 75 | 76 | /** 77 | * 布局资源ID 78 | * 79 | * @return 80 | */ 81 | protected abstract int getLayoutResId(); 82 | 83 | 84 | /** 85 | * 设置 状态栏 颜色 86 | * @param colorResId 87 | */ 88 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 89 | protected void setStatusBarColor(@ColorRes int colorResId) 90 | { 91 | if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) 92 | { 93 | return; 94 | } 95 | 96 | Window window = this.getWindow(); 97 | 98 | window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 99 | 100 | window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); 101 | 102 | window.setStatusBarColor(getResources().getColor(colorResId)); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/fragments/GeneralSettingsFragment.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.fragments; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceFragment; 7 | import android.preference.PreferenceManager; 8 | import android.widget.Toast; 9 | 10 | import com.max.wechatluckymoney.R; 11 | import com.max.wechatluckymoney.activitys.WebViewActivity; 12 | import com.max.wechatluckymoney.services.HandlerHelper; 13 | import com.max.wechatluckymoney.utils.Utils; 14 | 15 | /** 16 | * Created by Max on 2018/2/10. 17 | * 设置 18 | */ 19 | public class GeneralSettingsFragment extends PreferenceFragment { 20 | 21 | public static GeneralSettingsFragment getInstance() { 22 | GeneralSettingsFragment fragment = new GeneralSettingsFragment(); 23 | return fragment; 24 | } 25 | 26 | @Override 27 | public void onCreate(Bundle savedInstanceState) { 28 | super.onCreate(savedInstanceState); 29 | addPreferencesFromResource(R.xml.general_preferences); 30 | initEvent(); 31 | } 32 | 33 | private void initEvent() { 34 | // Open issue 35 | Preference issuePref = findPreference("pref_etc_issue"); 36 | issuePref.setOnPreferenceClickListener(preference -> { 37 | 38 | Intent intent = WebViewActivity.getInstance(getActivity(), getString(R.string.str_github_issues), 39 | getString(R.string.url_github_issues)); 40 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 41 | startActivity(intent); 42 | return false; 43 | }); 44 | 45 | 46 | Preference excludeWordsPref = findPreference("pref_watch_exclude_words"); 47 | String summary = getResources().getString(R.string.pref_watch_exclude_words_summary); 48 | String value = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("pref_watch_exclude_words", ""); 49 | if (value.length() > 0) excludeWordsPref.setSummary(summary + ":" + value); 50 | 51 | excludeWordsPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 52 | @Override 53 | public boolean onPreferenceChange(Preference preference, Object o) { 54 | String summary = getResources().getString(R.string.pref_watch_exclude_words_summary); 55 | if (o != null && o.toString().length() > 0) { 56 | preference.setSummary(summary + ":" + o.toString()); 57 | } else { 58 | preference.setSummary(summary); 59 | } 60 | return true; 61 | } 62 | }); 63 | 64 | 65 | Preference excludeWordsPrefChat = findPreference("pref_watch_exclude_words_chat"); 66 | String summaryChat = getResources().getString(R.string.pref_watch_exclude_words_summary); 67 | String valueChat = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("pref_watch_exclude_words_chat", ""); 68 | if (valueChat.length() > 0) excludeWordsPrefChat.setSummary(summaryChat + ":" + valueChat); 69 | 70 | excludeWordsPrefChat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { 71 | @Override 72 | public boolean onPreferenceChange(Preference preference, Object o) { 73 | String summary = getResources().getString(R.string.pref_watch_exclude_words_summary); 74 | if (o != null && o.toString().length() > 0) { 75 | preference.setSummary(summary + ":" + o.toString()); 76 | } else { 77 | preference.setSummary(summary); 78 | } 79 | return true; 80 | } 81 | }); 82 | 83 | 84 | Preference compatibilityPref = findPreference("pref_etc_compatibility"); 85 | String[] arr = HandlerHelper.getAdapterVersion(); 86 | String wechatVersion = Utils.getWeChatVersion(getActivity()); 87 | if (Utils.isArrContains(arr, Utils.getWeChatVersion(getActivity()))) { 88 | compatibilityPref.setSummary("当前微信" + wechatVersion + "版本已适配,但部分手机可能无法正常运转^_^\\\""); 89 | } else { 90 | compatibilityPref.setSummary("未适配当前微信" + wechatVersion + "版本,敬请期待^_^\\\""); 91 | } 92 | 93 | compatibilityPref.setOnPreferenceClickListener(preference -> { 94 | if (Utils.isArrContains(arr, Utils.getWeChatVersion(getActivity()))) { 95 | Toast.makeText(getActivity(), "当前微信版本已适配", Toast.LENGTH_LONG).show(); 96 | } else { 97 | Toast.makeText(getActivity(), "未适配当前微信版本,敬请期待~", Toast.LENGTH_LONG).show(); 98 | } 99 | return false; 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/HandlerHelper.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services; 2 | 3 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 4 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 5 | import com.max.wechatluckymoney.services.handler.seven_zero_zero.SzzChatDetailsHandler; 6 | import com.max.wechatluckymoney.services.handler.seven_zero_zero.SzzHomeChatHandler; 7 | import com.max.wechatluckymoney.services.handler.seven_zero_zero.SzzRedPacketGetRecordHandler; 8 | import com.max.wechatluckymoney.services.handler.seven_zero_zero.SzzRedPacketGetHandler; 9 | import com.max.wechatluckymoney.services.handler.six_six_three.SstChatDetailsHandler; 10 | import com.max.wechatluckymoney.services.handler.six_six_three.SstHomeChatHandler; 11 | import com.max.wechatluckymoney.services.handler.six_six_three.SstRedPacketGetRecordHandler; 12 | import com.max.wechatluckymoney.services.handler.six_six_three.SstRedPacketGetHandler; 13 | 14 | import java.util.ArrayList; 15 | 16 | /** 17 | * 处理帮助类 18 | * Created by Max on 2019/1/5. 19 | */ 20 | public class HandlerHelper { 21 | 22 | private AccessibilityHandlerListener mListener; 23 | 24 | public HandlerHelper(AccessibilityHandlerListener listener) { 25 | this.mListener = listener; 26 | } 27 | 28 | 29 | /** 30 | * 获取已经适配版本 31 | * 32 | * @return 33 | */ 34 | public static String[] getAdapterVersion() { 35 | return new String[]{"6.6.3", "7.0.0"}; 36 | } 37 | 38 | /** 39 | * @param version 40 | * @return 41 | */ 42 | public ArrayList getHandlers(String version) { 43 | switch (version) { 44 | case "6.6.3": 45 | return getHandlersBySixSixThree(); 46 | case "7.0.0": 47 | default: 48 | return getHandlersBySevenZeroZero(); 49 | } 50 | } 51 | 52 | 53 | /** 54 | * 6.6.3 55 | * 56 | * @return 57 | */ 58 | private ArrayList getHandlersBySixSixThree() { 59 | ArrayList handlers = new ArrayList<>(); 60 | handlers.add(new SstHomeChatHandler(mListener)); 61 | handlers.add(new SstChatDetailsHandler(mListener)); 62 | handlers.add(new SstRedPacketGetHandler(mListener)); 63 | handlers.add(new SstRedPacketGetRecordHandler(mListener)); 64 | return handlers; 65 | } 66 | 67 | 68 | /** 69 | * 7.0.0 70 | * 71 | * @return 72 | */ 73 | private ArrayList getHandlersBySevenZeroZero() { 74 | ArrayList handlers = new ArrayList<>(); 75 | handlers.add(new SzzHomeChatHandler(mListener)); 76 | handlers.add(new SzzChatDetailsHandler(mListener)); 77 | handlers.add(new SzzRedPacketGetHandler(mListener)); 78 | handlers.add(new SzzRedPacketGetRecordHandler(mListener)); 79 | return handlers; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/AccessibilityHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler; 2 | 3 | import android.accessibilityservice.AccessibilityService; 4 | import android.content.SharedPreferences; 5 | import android.os.Handler; 6 | import android.support.annotation.NonNull; 7 | import android.view.accessibility.AccessibilityEvent; 8 | import android.view.accessibility.AccessibilityNodeInfo; 9 | import android.widget.Toast; 10 | 11 | import com.max.wechatluckymoney.utils.L; 12 | 13 | /** 14 | * Created by max on 2018/2/9. 15 | * 辅助服务 16 | */ 17 | public abstract class AccessibilityHandler implements SharedPreferences.OnSharedPreferenceChangeListener 18 | { 19 | 20 | protected final String TAG = this.getClass().getSimpleName(); 21 | 22 | protected AccessibilityHandlerListener mListener; 23 | 24 | protected Handler mHandler; 25 | 26 | private Runnable mBackRunnable = () -> getService().performGlobalAction(getService().GLOBAL_ACTION_BACK); 27 | 28 | public AccessibilityHandler(@NonNull AccessibilityHandlerListener listener) 29 | { 30 | this.mListener = listener; 31 | this.mHandler = new Handler(); 32 | } 33 | 34 | /** 35 | * 处理类 36 | * 37 | * @return 38 | */ 39 | protected abstract boolean onHandler(); 40 | 41 | /** 42 | * 获取要拦截处理的Activity 43 | * 44 | * @return 45 | */ 46 | protected abstract String getInterceptActivityName(); 47 | 48 | /** 49 | * 处理 50 | * 51 | * @return 52 | */ 53 | public boolean onExecute() 54 | { 55 | if (getCurActivity().contains(getInterceptActivityName())) 56 | { 57 | return onHandler(); 58 | } 59 | return false; 60 | } 61 | 62 | private AccessibilityHandlerListener getListener() 63 | { 64 | return mListener; 65 | } 66 | 67 | /** 68 | * 获取 Service 69 | * 70 | * @return 71 | */ 72 | protected AccessibilityService getService() 73 | { 74 | return getListener().getAccessibilityService(); 75 | } 76 | 77 | /** 78 | * 获取当前 事件 79 | * 80 | * @return 81 | */ 82 | protected AccessibilityEvent getEvent() 83 | { 84 | return getListener().getAccessibilityEvent(); 85 | } 86 | 87 | protected SharedPreferences getSharedPreferences() 88 | { 89 | return getListener().getSharedPreferences(); 90 | } 91 | 92 | /** 93 | * 获取 当前事件 Node 94 | * 95 | * @return 96 | */ 97 | protected AccessibilityNodeInfo getRootNode() 98 | { 99 | return getEvent().getSource(); 100 | } 101 | 102 | /** 103 | * 设置当前 事件 类名称 104 | */ 105 | protected String getClassName() 106 | { 107 | if (getEvent().getClassName() == null) 108 | { 109 | return ""; 110 | } 111 | return getEvent().getClassName().toString(); 112 | } 113 | 114 | /** 115 | * 当前页面 116 | * 117 | * @return 118 | */ 119 | protected String getCurActivity() 120 | { 121 | return mListener.getCurActivityClassName() == null ? "" : mListener.getCurActivityClassName(); 122 | } 123 | 124 | 125 | /** 126 | * 开始一个延时任务 127 | * 128 | * @param runnable 129 | * @param time 130 | */ 131 | protected void startDelayedTask(Runnable runnable, long time) 132 | { 133 | mHandler.postDelayed(runnable, time); 134 | } 135 | 136 | /** 137 | * 延时返回 138 | */ 139 | protected void postDelayedBack() 140 | { 141 | startDelayedTask(mBackRunnable, 300); 142 | } 143 | 144 | protected void toast(CharSequence sequence) 145 | { 146 | Toast.makeText(getService(), sequence, Toast.LENGTH_SHORT).show(); 147 | } 148 | 149 | 150 | /** 151 | * 触发点击 152 | * 153 | * @param nodeInfo 154 | */ 155 | protected void performClick(AccessibilityNodeInfo nodeInfo) 156 | { 157 | if (nodeInfo != null) 158 | { 159 | nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); 160 | } 161 | } 162 | 163 | 164 | @Override 165 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) 166 | { 167 | 168 | } 169 | 170 | protected void log(String message) 171 | { 172 | L.e(TAG, message); 173 | } 174 | 175 | 176 | } 177 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/AccessibilityHandlerListener.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler; 2 | 3 | import android.accessibilityservice.AccessibilityService; 4 | import android.content.SharedPreferences; 5 | import android.view.accessibility.AccessibilityEvent; 6 | 7 | /** 8 | * Created by max on 2018/2/9. 9 | */ 10 | public interface AccessibilityHandlerListener { 11 | 12 | /** 13 | * 获取 service 14 | * 15 | * @return 16 | */ 17 | AccessibilityService getAccessibilityService(); 18 | 19 | /** 20 | * 获取 event 21 | * 22 | * @return 23 | */ 24 | AccessibilityEvent getAccessibilityEvent(); 25 | 26 | /** 27 | * 获取SharedPreferences 28 | * 29 | * @return 30 | */ 31 | SharedPreferences getSharedPreferences(); 32 | 33 | 34 | /** 35 | * 当前页面 类名 36 | * 37 | * @return 38 | */ 39 | String getCurActivityClassName(); 40 | } 41 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/base/HomeChatHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.base; 2 | 3 | import android.content.SharedPreferences; 4 | import android.support.annotation.NonNull; 5 | 6 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 7 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 8 | import com.max.wechatluckymoney.utils.Utils; 9 | 10 | /** 11 | * 首页聊天界面 12 | * Created by Max on 2019/1/7. 13 | */ 14 | public abstract class HomeChatHandler extends AccessibilityHandler { 15 | 16 | /** 17 | * 是否监视聊天列表 18 | */ 19 | private Boolean mSwitchChatList; 20 | 21 | /** 22 | * 排除词 不打开这些人 或群发的红包 23 | */ 24 | private String[] mChatExcludeWords; 25 | 26 | protected static final String WX_TEXT_LUCKY_MONEY = "[微信红包]"; 27 | 28 | public HomeChatHandler(@NonNull AccessibilityHandlerListener listener) { 29 | super(listener); 30 | } 31 | 32 | /** 33 | * 是否监视聊天列表 34 | * 35 | * @return 36 | */ 37 | protected boolean isChatListSwitch() { 38 | if (mSwitchChatList == null) { 39 | mSwitchChatList = getSharedPreferences().getBoolean("pref_watch_list", true); 40 | } 41 | return mSwitchChatList; 42 | } 43 | 44 | /** 45 | * 获取排除词 包含这些文本的 红包不领 46 | * 47 | * @return 48 | */ 49 | private String[] getChatExcludeWords() { 50 | if (mChatExcludeWords == null) { 51 | mChatExcludeWords = getSharedPreferences().getString("pref_watch_exclude_words_chat", "").split(" "); 52 | } 53 | return mChatExcludeWords; 54 | } 55 | 56 | /** 57 | * 是否排除这个红包 根据聊天对象名 58 | * 59 | * @param chatName 聊天对象 60 | * @return 61 | */ 62 | protected boolean isExcludeByChatName(String chatName) { 63 | return Utils.isArrContains(getChatExcludeWords(), chatName); 64 | } 65 | 66 | @Override 67 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { 68 | super.onSharedPreferenceChanged(sharedPreferences, s); 69 | mSwitchChatList = getSharedPreferences().getBoolean("pref_watch_list", true); 70 | mChatExcludeWords = getSharedPreferences().getString("pref_watch_exclude_words_chat", "").split(" "); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/base/RedPacketGetHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.base; 2 | 3 | import android.content.SharedPreferences; 4 | import android.support.annotation.NonNull; 5 | 6 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 7 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 8 | import com.max.wechatluckymoney.utils.Utils; 9 | 10 | /** 11 | * 红包领取 (红包弹窗) 12 | * Created by Max on 2019/1/7. 13 | */ 14 | public abstract class RedPacketGetHandler extends AccessibilityHandler { 15 | 16 | protected static final String WX_TEXT_SLOW = "手慢了"; 17 | protected static final String WX_TEXT_OUT_OF_DATE = "已超过24小时"; 18 | 19 | /** 20 | * 自动打开红包 21 | */ 22 | private Boolean mIsAutoOpenRedPacket; 23 | 24 | /** 25 | * 排除词 不打开这些文字的红包 26 | */ 27 | private String[] mRedPacketExcludeWords; 28 | 29 | /** 30 | * 是否 自动拆红包 31 | * @return 32 | */ 33 | protected Boolean isAutoOpen() { 34 | if (mIsAutoOpenRedPacket == null) { 35 | mIsAutoOpenRedPacket = getSharedPreferences().getBoolean("pref_auto_open", true); 36 | } 37 | return mIsAutoOpenRedPacket; 38 | } 39 | 40 | public RedPacketGetHandler(@NonNull AccessibilityHandlerListener listener) { 41 | super(listener); 42 | } 43 | 44 | /** 45 | * 获取排除词 包含这些文本的 红包不领 46 | * 47 | * @return 48 | */ 49 | private String[] getRedPacketExcludeWords() { 50 | if (mRedPacketExcludeWords == null) { 51 | mRedPacketExcludeWords = getSharedPreferences().getString("pref_watch_exclude_words", "").split(" "); 52 | } 53 | return mRedPacketExcludeWords; 54 | } 55 | 56 | /** 57 | * 是否排除这个红包 根据红包名称 58 | * 59 | * @param redPacketText 红包文本 60 | * @return 61 | */ 62 | protected boolean isExcludeByRedPacketText(String redPacketText) { 63 | return Utils.isArrContains(getRedPacketExcludeWords(), redPacketText); 64 | } 65 | 66 | 67 | @Override 68 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) { 69 | super.onSharedPreferenceChanged(sharedPreferences, s); 70 | mIsAutoOpenRedPacket = getSharedPreferences().getBoolean("pref_auto_open", true); 71 | mRedPacketExcludeWords = getSharedPreferences().getString("pref_watch_exclude_words", "").split(" "); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/base/RedPacketGetRecordHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.base; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 6 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 7 | 8 | /** 9 | * 红包领取记录 10 | * Created by Max on 2019/1/7. 11 | */ 12 | public abstract class RedPacketGetRecordHandler extends AccessibilityHandler { 13 | public RedPacketGetRecordHandler(@NonNull AccessibilityHandlerListener listener) { 14 | super(listener); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/seven_zero_zero/SzzChatDetailsHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.seven_zero_zero; 2 | 3 | import android.graphics.Rect; 4 | import android.text.TextUtils; 5 | import android.view.accessibility.AccessibilityNodeInfo; 6 | import android.widget.Toast; 7 | 8 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 9 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 10 | import com.max.wechatluckymoney.services.handler.base.ChatDetailsHandler; 11 | import com.max.wechatluckymoney.utils.AccessibilityNodeUtils; 12 | import com.max.wechatluckymoney.utils.Utils; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * Created by max on 2019/1/7. 18 | * 聊天界面 处理类 19 | */ 20 | public class SzzChatDetailsHandler extends ChatDetailsHandler { 21 | 22 | 23 | /** 24 | * 聊天对象 名称 25 | */ 26 | private static final String WX_ID_NAME = "com.tencent.mm:id/jw"; 27 | 28 | /** 29 | * 微信红包 Item 30 | */ 31 | private static final String WX_ID_LUCKYMONEY_ITEM = "com.tencent.mm:id/ao4"; 32 | 33 | /** 34 | * 微信红包 无法领取的文本 (已过期,已领取,被领取 等提示文本) 35 | */ 36 | private static final String WX_ID_LUCKYMONEY_BAN_TEXT = "com.tencent.mm:id/ape"; 37 | 38 | /** 39 | * 微信红包文本 (用户发红包设置的文本) 40 | */ 41 | private static final String WX_ID_LUCKYMONEY_TEXT = "com.tencent.mm:id/apd"; 42 | 43 | 44 | /** 45 | * 聊天对象名 或 群聊名 46 | */ 47 | private String mChatName; 48 | 49 | /** 50 | * 是否有可领取的 51 | */ 52 | private boolean mIsHasCanNode; 53 | 54 | private boolean mIsBackrunnableComplete = true; 55 | 56 | private Runnable mBackrunnable = () -> { 57 | mIsBackrunnableComplete = true; 58 | }; 59 | 60 | public SzzChatDetailsHandler(AccessibilityHandlerListener listener) { 61 | super(listener); 62 | } 63 | 64 | @Override 65 | public boolean onHandler() { 66 | mIsHasCanNode = false; 67 | 68 | AccessibilityNodeInfo chatNameNode = AccessibilityNodeUtils.getFirstNodeById(getRootNode(), WX_ID_NAME); 69 | if (chatNameNode != null && !TextUtils.isEmpty(chatNameNode.getText())) { 70 | mChatName = chatNameNode.getText().toString(); 71 | } 72 | 73 | if (isExcludeByChatName(mChatName)) { 74 | return true; 75 | } 76 | 77 | List nodes = AccessibilityNodeUtils.findNodeListById(getRootNode(), WX_ID_LUCKYMONEY_ITEM); 78 | 79 | if (!Utils.listIsEmpty(nodes)) { 80 | for (int i = nodes.size() - 1; i >= 0; i--) { 81 | AccessibilityNodeInfo itemNode = nodes.get(i); 82 | 83 | AccessibilityNodeInfo redPacketTextNode = AccessibilityNodeUtils.getFirstNodeById(itemNode, WX_ID_LUCKYMONEY_TEXT); 84 | if (redPacketTextNode != null) { 85 | 86 | AccessibilityNodeInfo banNode = AccessibilityNodeUtils.getFirstNodeById(itemNode, WX_ID_LUCKYMONEY_BAN_TEXT); 87 | if (banNode == null) { 88 | 89 | if (isExcludeByRedPacketText(redPacketTextNode.getText() != null ? redPacketTextNode.getText().toString() : "")) { 90 | continue; 91 | } 92 | 93 | Rect rectScreen = new Rect(); 94 | itemNode.getBoundsInScreen(rectScreen); 95 | //是我的红包? 96 | boolean isMyRedPacket = isMyRedPacket(rectScreen); 97 | 98 | if (isMyRedPacket) { 99 | //是我的红包 100 | if (!isOpenMyRedPaclet() || !isGroupChat(mChatName)) { 101 | //设置说 不可以领 或者是 不是群聊发的红包 102 | continue; 103 | } 104 | } 105 | 106 | log("准备打开红包 "); 107 | if (getDelayTime() > 0) { 108 | addDelayTask(itemNode); 109 | } else { 110 | log("立即打开红包 "); 111 | performClick(itemNode); 112 | } 113 | mIsHasCanNode = true; 114 | } 115 | } 116 | } 117 | 118 | if (!mIsHasCanNode && isBackHomeList()) { 119 | if (mIsBackrunnableComplete) { 120 | mIsBackrunnableComplete = false; 121 | getService().performGlobalAction(getService().GLOBAL_ACTION_BACK); 122 | startDelayedTask(mBackrunnable, 200); 123 | } 124 | } 125 | return true; 126 | } 127 | return false; 128 | } 129 | 130 | @Override 131 | protected String getInterceptActivityName() { 132 | return "LauncherUI"; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/seven_zero_zero/SzzHomeChatHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.seven_zero_zero; 2 | 3 | import android.view.accessibility.AccessibilityNodeInfo; 4 | 5 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 6 | import com.max.wechatluckymoney.services.handler.base.HomeChatHandler; 7 | import com.max.wechatluckymoney.utils.AccessibilityNodeUtils; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by max on 2019/1/7. 13 | * 聊天列表 处理类 14 | */ 15 | public class SzzHomeChatHandler extends HomeChatHandler { 16 | 17 | 18 | /** 19 | * 聊天列表 Item 20 | */ 21 | private static final String WX_ID_CHAT_ITEM = "com.tencent.mm:id/b4m"; 22 | 23 | /** 24 | * 聊天列表 的 聊天对象 25 | */ 26 | private static final String WX_ID_CHAT_ITEM_NAME = "com.tencent.mm:id/b4o"; 27 | 28 | /** 29 | * 聊天列表 的 消息内容ID 30 | */ 31 | private static final String WX_ID_CHAT_ITEM_CONTENT = "com.tencent.mm:id/b4q"; 32 | 33 | public SzzHomeChatHandler(AccessibilityHandlerListener listener) { 34 | super(listener); 35 | } 36 | 37 | @Override 38 | public boolean onHandler() { 39 | 40 | if (!isChatListSwitch()) { 41 | return false; 42 | } 43 | 44 | List itemNodes = AccessibilityNodeUtils.findNodeListById(getRootNode(), WX_ID_CHAT_ITEM); 45 | 46 | if (itemNodes != null) { 47 | for (AccessibilityNodeInfo nodeInfo : itemNodes) { 48 | 49 | AccessibilityNodeInfo chatContentNode = AccessibilityNodeUtils.getFirstNodeById(nodeInfo, WX_ID_CHAT_ITEM_CONTENT); 50 | if (chatContentNode != null && chatContentNode.getText() != null) { 51 | if (chatContentNode.getText().toString().contains(WX_TEXT_LUCKY_MONEY)) { 52 | 53 | AccessibilityNodeInfo chatNameNode = AccessibilityNodeUtils.getFirstNodeById(nodeInfo, WX_ID_CHAT_ITEM_NAME); 54 | if (chatNameNode != null && chatNameNode.getText() != null) { 55 | if (isExcludeByChatName(chatNameNode.getText().toString())) { 56 | continue; 57 | } 58 | } 59 | 60 | toast("发现红包"); 61 | performClick(nodeInfo); 62 | return true; 63 | } 64 | } 65 | } 66 | } 67 | return false; 68 | } 69 | 70 | @Override 71 | protected String getInterceptActivityName() { 72 | return "LauncherUI"; 73 | } 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/seven_zero_zero/SzzRedPacketGetHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.seven_zero_zero; 2 | 3 | import android.view.accessibility.AccessibilityNodeInfo; 4 | 5 | import com.max.wechatluckymoney.activitys.LoadingActivity; 6 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 7 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 8 | import com.max.wechatluckymoney.services.handler.base.RedPacketGetHandler; 9 | import com.max.wechatluckymoney.utils.AccessibilityNodeUtils; 10 | 11 | /** 12 | * Created by max on 2019/1/7. 13 | * 领取红包详情 处理类 14 | */ 15 | public class SzzRedPacketGetHandler extends RedPacketGetHandler { 16 | 17 | /** 18 | * 打开红包按钮 19 | */ 20 | private static final String WX_ID_OPEN = "com.tencent.mm:id/cv0"; 21 | 22 | /** 23 | * 红包 名称 24 | */ 25 | private static final String WX_ID_NAME = "com.tencent.mm:id/cuz"; 26 | 27 | 28 | public SzzRedPacketGetHandler(AccessibilityHandlerListener listener) { 29 | super(listener); 30 | } 31 | 32 | @Override 33 | public boolean onHandler() { 34 | 35 | //红包弹窗页面 36 | if (AccessibilityNodeUtils.hasOneNodeByTexts(getRootNode(), WX_TEXT_SLOW, WX_TEXT_OUT_OF_DATE)) { 37 | //已经领完了 或者过期 38 | log("-> 已经领完了 或者过期"); 39 | postDelayedBack(); 40 | return true; 41 | } else { 42 | 43 | AccessibilityNodeInfo openNode = AccessibilityNodeUtils.getFirstNodeById(getRootNode(), WX_ID_OPEN); 44 | 45 | if (openNode != null) { 46 | //还没有领 47 | log("-> 还没有领"); 48 | if (isAutoOpen()) { 49 | 50 | AccessibilityNodeInfo nameNode = AccessibilityNodeUtils.getFirstNodeById(getRootNode(), WX_ID_NAME); 51 | if (nameNode != null && nameNode.getText() != null) { 52 | if (isExcludeByRedPacketText(nameNode.getText().toString())) { 53 | return true; 54 | } 55 | } 56 | 57 | toast("领红包啦"); 58 | performClick(openNode); 59 | } 60 | 61 | return true; 62 | } 63 | } 64 | 65 | //红包页面 生命周期的改变 才能正常获取有用信息 66 | //暂时这样解决 微信对 红包页面做的特殊处理 67 | getService().startActivity(LoadingActivity.getInstance(getService())); 68 | return false; 69 | } 70 | 71 | @Override 72 | protected String getInterceptActivityName() { 73 | return "LuckyMoneyNotHookReceiveUI"; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/seven_zero_zero/SzzRedPacketGetRecordHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.seven_zero_zero; 2 | 3 | 4 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 5 | import com.max.wechatluckymoney.services.handler.six_six_three.SstRedPacketGetRecordHandler; 6 | 7 | /** 8 | * Created by max on 2019/1/7. 9 | * 红包领取记录 10 | */ 11 | public class SzzRedPacketGetRecordHandler extends SstRedPacketGetRecordHandler { 12 | 13 | public SzzRedPacketGetRecordHandler(AccessibilityHandlerListener listener) { 14 | super(listener); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/six_six_three/SstChatDetailsHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.six_six_three; 2 | 3 | import android.graphics.Rect; 4 | import android.view.accessibility.AccessibilityNodeInfo; 5 | 6 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 7 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 8 | import com.max.wechatluckymoney.services.handler.base.ChatDetailsHandler; 9 | import com.max.wechatluckymoney.utils.AccessibilityNodeUtils; 10 | 11 | /** 12 | * Created by max on 2018/2/9. 13 | * 聊天界面 处理类 14 | */ 15 | public class SstChatDetailsHandler extends ChatDetailsHandler 16 | { 17 | //聊天界面className 18 | private static final String WECHAT_ACTIVITY_CHAT_DEATILS = "LauncherUI"; 19 | 20 | //listview 21 | private static final String WECHAT_VIEW_LISTVIEW = "ListView"; 22 | 23 | private static final String WECHAT_TEXT_GET_LM = "领取红包"; 24 | 25 | public SstChatDetailsHandler(AccessibilityHandlerListener listener) 26 | { 27 | super(listener); 28 | } 29 | 30 | 31 | @Override 32 | public boolean onHandler() 33 | { 34 | String name = getClassName(); 35 | 36 | if (name.contains(WECHAT_ACTIVITY_CHAT_DEATILS) || name.contains(WECHAT_VIEW_LISTVIEW)) 37 | { 38 | AccessibilityNodeInfo node = AccessibilityNodeUtils.getTheLastNodeByTexts(getRootNode(), WECHAT_TEXT_GET_LM); 39 | 40 | if (node != null) 41 | { 42 | if (node.getParent() != null) 43 | { 44 | 45 | Rect rectScreen = new Rect(); 46 | node.getParent().getBoundsInScreen(rectScreen); 47 | //是我的红包? 48 | boolean isMyRedPacket = isMyRedPacket(rectScreen); 49 | 50 | if (isMyRedPacket) 51 | { 52 | return false; 53 | } 54 | performClick(node.getParent()); 55 | } 56 | return true; 57 | } 58 | } 59 | return false; 60 | } 61 | 62 | @Override 63 | protected String getInterceptActivityName() 64 | { 65 | return "LauncherUI"; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/six_six_three/SstHomeChatHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.six_six_three; 2 | 3 | import android.view.accessibility.AccessibilityNodeInfo; 4 | 5 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 6 | import com.max.wechatluckymoney.services.handler.base.HomeChatHandler; 7 | import com.max.wechatluckymoney.utils.AccessibilityNodeUtils; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Created by max on 2018/2/10. 13 | * 聊天列表 处理类 14 | */ 15 | public class SstHomeChatHandler extends HomeChatHandler { 16 | //聊天列表 的 消息内容ID 17 | private static final String WECHAT_ID_LUCKY_MONEY = "com.tencent.mm:id/apv"; 18 | //聊天列表 的 消息内容ID 新版本 19 | private static final String WECHAT_ID_LUCKY_MONEY_NEW = "com.tencent.mm:id/apt"; 20 | 21 | public SstHomeChatHandler(AccessibilityHandlerListener listener) { 22 | super(listener); 23 | } 24 | 25 | @Override 26 | public boolean onHandler() { 27 | if (!isChatListSwitch()) { 28 | return false; 29 | } 30 | 31 | List nodes = AccessibilityNodeUtils.findNodeListById(getRootNode(), WECHAT_ID_LUCKY_MONEY_NEW); 32 | if (nodes == null) { 33 | nodes = AccessibilityNodeUtils.findNodeListById(getRootNode(), WECHAT_ID_LUCKY_MONEY); 34 | } 35 | 36 | if (nodes != null) { 37 | 38 | for (AccessibilityNodeInfo nodeInfo : nodes) { 39 | if (nodeInfo != null && nodeInfo.getText() != null) { 40 | if (nodeInfo.getText().toString().contains(WX_TEXT_LUCKY_MONEY)) { 41 | toast("发现红包了"); 42 | performClick(nodeInfo.getParent()); 43 | return true; 44 | } 45 | } 46 | } 47 | } 48 | return false; 49 | } 50 | 51 | @Override 52 | protected String getInterceptActivityName() { 53 | return "LauncherUI"; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/six_six_three/SstRedPacketGetHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.six_six_three; 2 | 3 | import android.view.accessibility.AccessibilityNodeInfo; 4 | 5 | import com.max.wechatluckymoney.activitys.LoadingActivity; 6 | import com.max.wechatluckymoney.services.handler.AccessibilityHandler; 7 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 8 | import com.max.wechatluckymoney.services.handler.base.RedPacketGetHandler; 9 | import com.max.wechatluckymoney.support.enums.WidgetType; 10 | import com.max.wechatluckymoney.utils.AccessibilityNodeUtils; 11 | 12 | /** 13 | * Created by max on 2018/2/9. 14 | * 领取红包详情 处理类 15 | */ 16 | public class SstRedPacketGetHandler extends RedPacketGetHandler { 17 | 18 | public SstRedPacketGetHandler(AccessibilityHandlerListener listener) { 19 | super(listener); 20 | } 21 | 22 | @Override 23 | public boolean onHandler() { 24 | 25 | //红包弹窗页面 26 | if (AccessibilityNodeUtils.hasOneNodeByTexts(getRootNode(), WX_TEXT_SLOW, WX_TEXT_OUT_OF_DATE)) { 27 | //已经领完了 或者过期 28 | log("-> 已经领完了 或者过期"); 29 | postDelayedBack(); 30 | return true; 31 | } else { 32 | AccessibilityNodeInfo node = AccessibilityNodeUtils.getOneNodeByViewTag(getRootNode(), WidgetType.Button.getContent()); 33 | if (node != null) { 34 | //还没有领 35 | log("-> 还没有领"); 36 | 37 | if (isAutoOpen()) { 38 | toast("领红包啦"); 39 | performClick(node); 40 | } 41 | 42 | return true; 43 | } 44 | } 45 | 46 | //红包页面 生命周期的改变 才能正常获取有用信息 47 | //暂时这样解决 微信对 红包页面做的特殊处理 48 | getService().startActivity(LoadingActivity.getInstance(getService())); 49 | return false; 50 | } 51 | 52 | @Override 53 | protected String getInterceptActivityName() { 54 | return "LuckyMoneyReceiveUI"; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/services/handler/six_six_three/SstRedPacketGetRecordHandler.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.services.handler.six_six_three; 2 | 3 | 4 | import com.max.wechatluckymoney.services.handler.AccessibilityHandlerListener; 5 | import com.max.wechatluckymoney.services.handler.base.RedPacketGetRecordHandler; 6 | 7 | /** 8 | * Created by max on 2018/2/9. 9 | * 红包详情 处理类 10 | */ 11 | public class SstRedPacketGetRecordHandler extends RedPacketGetRecordHandler 12 | { 13 | 14 | private boolean mIsComplete = true; 15 | 16 | private Runnable mBackrunnable = () -> { 17 | log("返回咯"); 18 | getService().performGlobalAction(getService().GLOBAL_ACTION_BACK); 19 | mIsComplete = true; 20 | }; 21 | 22 | public SstRedPacketGetRecordHandler(AccessibilityHandlerListener listener) 23 | { 24 | super(listener); 25 | } 26 | 27 | @Override 28 | public boolean onHandler() 29 | { 30 | if (mIsComplete) 31 | { 32 | mIsComplete = false; 33 | startDelayedTask(mBackrunnable, 350); 34 | } 35 | return true; 36 | } 37 | 38 | @Override 39 | protected String getInterceptActivityName() 40 | { 41 | return "LuckyMoneyDetailUI"; 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/support/FloatingHelper.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.support; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.graphics.PixelFormat; 7 | import android.os.Build; 8 | import android.view.Gravity; 9 | import android.view.WindowManager; 10 | import android.widget.Toast; 11 | 12 | import com.max.wechatluckymoney.activitys.MainActivity; 13 | import com.max.wechatluckymoney.utils.L; 14 | import com.max.wechatluckymoney.utils.Utils; 15 | import com.max.wechatluckymoney.view.FloatingView; 16 | 17 | import static android.content.Context.WINDOW_SERVICE; 18 | 19 | /** 20 | * 悬浮视图 21 | * Created by Max on 2019/1/5. 22 | */ 23 | public class FloatingHelper implements FloatingView.OnFloatingListener 24 | { 25 | 26 | private Context mContext; 27 | 28 | private int mWinW, mWinH; 29 | 30 | private WindowManager.LayoutParams mParams; 31 | 32 | private WindowManager mWindowManager; 33 | 34 | private FloatingView mFloatingView; 35 | 36 | private OnFloatingHelperListener mListener; 37 | 38 | public FloatingHelper(Context context, OnFloatingHelperListener listener) 39 | { 40 | this.mContext = context; 41 | this.mListener = listener; 42 | } 43 | 44 | /** 45 | * 检查加载 46 | */ 47 | public void checkLoad() 48 | { 49 | if (isFloatingEnabled()) 50 | { 51 | show(); 52 | } else 53 | { 54 | hide(); 55 | } 56 | } 57 | 58 | private void show() 59 | { 60 | if (mFloatingView == null) 61 | { 62 | mFloatingView = new FloatingView(mContext, this); 63 | } 64 | 65 | if (mWindowManager == null) 66 | { 67 | mWindowManager = (WindowManager) mContext.getSystemService(WINDOW_SERVICE); 68 | mParams = new WindowManager.LayoutParams(); 69 | mWinW = mWindowManager.getDefaultDisplay().getWidth(); 70 | mWinH = mWindowManager.getDefaultDisplay().getHeight(); 71 | mParams.height = WindowManager.LayoutParams.WRAP_CONTENT; 72 | mParams.width = WindowManager.LayoutParams.WRAP_CONTENT; 73 | mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 74 | | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; 75 | mParams.format = PixelFormat.TRANSLUCENT; 76 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 77 | { 78 | mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 79 | } else 80 | { 81 | mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; 82 | } 83 | mParams.gravity = Gravity.RIGHT + Gravity.TOP;// 将重心位置设置为右上方, 84 | mParams.y = mWinH / 6; 85 | mWindowManager.addView(mFloatingView, mParams); 86 | } 87 | 88 | //改变状态 89 | changeState(! isHandler()); 90 | } 91 | 92 | private void hide() 93 | { 94 | if (mWindowManager != null && mFloatingView != null) 95 | { 96 | mWindowManager.removeView(mFloatingView); 97 | mFloatingView = null; 98 | mWindowManager = null; 99 | } 100 | } 101 | 102 | /** 103 | * 解绑 104 | */ 105 | public void onUnbind() 106 | { 107 | hide(); 108 | } 109 | 110 | /** 111 | * 改变状态显示 112 | */ 113 | private void changeState(boolean state) 114 | { 115 | if (mFloatingView == null) 116 | { 117 | return; 118 | } 119 | mFloatingView.changeState(state); 120 | } 121 | 122 | /** 123 | * 是否处理 124 | * 125 | * @return 126 | */ 127 | private boolean isHandler() 128 | { 129 | //开关 130 | return mListener.getSharedPreferences().getBoolean("switch_app", true); 131 | } 132 | 133 | 134 | /** 135 | * 设置开关 136 | * 137 | * @param sw 138 | */ 139 | private void setSwitch(boolean sw) 140 | { 141 | if (sw) 142 | { 143 | Toast.makeText(mContext, "红包助手启动成功.", Toast.LENGTH_LONG).show(); 144 | } 145 | mListener.getSharedPreferences().edit().putBoolean("switch_app", sw).commit(); 146 | } 147 | 148 | /** 149 | * 是否 show 悬浮按钮 150 | * 151 | * @return 152 | */ 153 | private boolean isFloatingEnabled() 154 | { 155 | return mListener.getSharedPreferences().getBoolean("switch_float", true); 156 | } 157 | 158 | @Override 159 | public void onMove(float offsetX, float offsetY) 160 | { 161 | mParams.x += offsetX; 162 | mParams.y += offsetY; 163 | 164 | if (mParams.x > mWinW - mFloatingView.getWidth()) 165 | { 166 | mParams.x = mWinW - mFloatingView.getWidth(); 167 | } 168 | if (mParams.y > mWinH - mFloatingView.getHeight()) 169 | { 170 | mParams.y = mWinH - mFloatingView.getHeight(); 171 | } 172 | 173 | mWindowManager.updateViewLayout(mFloatingView, mParams); 174 | } 175 | 176 | @Override 177 | public void onClick() 178 | { 179 | Utils.vibrate(mContext, 50); 180 | setSwitch(! isHandler()); 181 | } 182 | 183 | @Override 184 | public void onLongClick() 185 | { 186 | Utils.vibrate(mContext, 150); 187 | Intent intent = new Intent(mContext, MainActivity.class); 188 | mContext.startActivity(intent); 189 | } 190 | 191 | public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) 192 | { 193 | checkLoad(); 194 | } 195 | 196 | 197 | public interface OnFloatingHelperListener 198 | { 199 | SharedPreferences getSharedPreferences(); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/support/OpenRedPacketDelayTask.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.support; 2 | 3 | import android.os.Handler; 4 | import android.view.accessibility.AccessibilityNodeInfo; 5 | 6 | import com.max.wechatluckymoney.utils.L; 7 | import com.max.wechatluckymoney.utils.Utils; 8 | 9 | import java.util.LinkedHashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * 打开红包延时任务 14 | * Created by Max on 2019/1/9. 15 | */ 16 | public class OpenRedPacketDelayTask { 17 | 18 | private Handler mHandler; 19 | 20 | /** 21 | * 打开红包 延迟时间 22 | */ 23 | private int mOpenRedPacketDelayTime; 24 | 25 | /** 26 | * 当前延时打开的红包 27 | */ 28 | private AccessibilityNodeInfo mCurDelayedNode; 29 | 30 | /** 31 | * 等待延时打开的红包列表 32 | */ 33 | private LinkedHashMap mRedPacketQueue; 34 | 35 | /** 36 | * 打开红包延时任务 37 | */ 38 | private Runnable mOpenRedPacketDelayedRunnable = () -> { 39 | L.e("延时任务,打开红包 "); 40 | if (mCurDelayedNode != null) { 41 | openRedPacket(mCurDelayedNode); 42 | mCurDelayedNode = null; 43 | } 44 | }; 45 | 46 | /** 47 | * @param handler 48 | * @param delayTime 延时打开红包的时间 49 | */ 50 | public OpenRedPacketDelayTask(Handler handler, int delayTime) { 51 | this.mHandler = handler; 52 | this.mOpenRedPacketDelayTime = delayTime; 53 | this.mRedPacketQueue = new LinkedHashMap<>(); 54 | } 55 | 56 | /** 57 | * 添加任务 58 | * 59 | * @param nodeInfo 60 | */ 61 | public void addTask(AccessibilityNodeInfo nodeInfo) { 62 | 63 | if (mCurDelayedNode == null) { 64 | //当前没有延时任务在执行 65 | 66 | if (mRedPacketQueue.isEmpty()) { 67 | //当前没有等待任务 可添加此任务 68 | startDelayedTask(nodeInfo, System.currentTimeMillis()); 69 | 70 | } else if (mRedPacketQueue.containsKey(nodeInfo)) { 71 | //已经在队列中 这次直接执行该红包任务 72 | startDelayedTask(nodeInfo, mRedPacketQueue.remove(nodeInfo)); 73 | 74 | } else { 75 | //没有在队列中 这次添加到队列中等待执行 76 | 77 | //拿取第一个Node 执行定时任务 78 | Map.Entry entry = Utils.getMapFirstEntry(mRedPacketQueue); 79 | mRedPacketQueue.remove(entry.getKey()); 80 | startDelayedTask(entry.getKey(), entry.getValue()); 81 | 82 | mRedPacketQueue.put(nodeInfo, System.currentTimeMillis()); 83 | } 84 | 85 | } else { 86 | 87 | //当前已有延时任务在执行 88 | if (isSameNode(mCurDelayedNode, nodeInfo)) return; 89 | if (!mRedPacketQueue.containsKey(nodeInfo)) { 90 | //之前没有添加过 91 | mRedPacketQueue.put(nodeInfo, System.currentTimeMillis()); 92 | } 93 | } 94 | } 95 | 96 | /** 97 | * 是否同一个Node 98 | * 99 | * @param nodeInfoA 100 | * @param nodeInfoB 101 | * @return 102 | */ 103 | private boolean isSameNode(AccessibilityNodeInfo nodeInfoA, AccessibilityNodeInfo nodeInfoB) { 104 | if (nodeInfoA == nodeInfoB) return true; 105 | return nodeInfoA.equals(nodeInfoB); 106 | } 107 | 108 | /** 109 | * 更新 延时打开红包 的时间 110 | * 111 | * @param delayTime 112 | */ 113 | public void updateDelayTime(int delayTime) { 114 | this.mOpenRedPacketDelayTime = delayTime; 115 | } 116 | 117 | /** 118 | * 延时任务 119 | */ 120 | private void startDelayedTask(AccessibilityNodeInfo nodeInfo, long nodeCreateTime) { 121 | if (nodeInfo != null) { 122 | mCurDelayedNode = nodeInfo; 123 | long time = mOpenRedPacketDelayTime * 1000 - (System.currentTimeMillis() - nodeCreateTime); 124 | time = time > 0 ? time : 0; 125 | mHandler.postDelayed(mOpenRedPacketDelayedRunnable, time); 126 | } 127 | } 128 | 129 | /** 130 | * 打开红包 131 | * 132 | * @param nodeInfo 133 | */ 134 | private void openRedPacket(AccessibilityNodeInfo nodeInfo) { 135 | 136 | if (nodeInfo != null) { 137 | nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/support/enums/WidgetType.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.support.enums; 2 | 3 | /** 4 | * Created by max on 2018/2/9. 5 | * 控件 6 | */ 7 | public enum WidgetType 8 | { 9 | Button("android.widget.Button"), 10 | 11 | TextView("android.widget.TextView"), 12 | 13 | LinearLayout("android.widget.RelativeLayout"), 14 | 15 | RelativeLayout("android.widget.RelativeLayout"); 16 | 17 | 18 | WidgetType(String content) 19 | { 20 | this.content = content; 21 | } 22 | 23 | private String content; 24 | 25 | public String getContent() 26 | { 27 | return content; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/utils/AppUtils.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.utils; 2 | 3 | import android.content.Context; 4 | import android.content.pm.PackageInfo; 5 | import android.content.pm.PackageManager; 6 | 7 | /** 8 | * Created by Max on 2018/12/22. 9 | */ 10 | public class AppUtils { 11 | private AppUtils() { 12 | throw new UnsupportedOperationException("u can't instantiate me..."); 13 | } 14 | 15 | 16 | /** 17 | * 获取本地软件版本号 18 | */ 19 | public static int getLocalVersionCode(Context ctx) { 20 | int localVersion = 0; 21 | try { 22 | PackageInfo packageInfo = ctx.getApplicationContext() 23 | .getPackageManager() 24 | .getPackageInfo(ctx.getPackageName(), 0); 25 | localVersion = packageInfo.versionCode; 26 | } catch (PackageManager.NameNotFoundException e) { 27 | e.printStackTrace(); 28 | } 29 | return localVersion; 30 | } 31 | 32 | /** 33 | * 获取本地软件版本号名称 34 | */ 35 | public static String getLocalVersionName(Context ctx) { 36 | String localVersion = ""; 37 | try { 38 | PackageInfo packageInfo = ctx.getApplicationContext() 39 | .getPackageManager() 40 | .getPackageInfo(ctx.getPackageName(), 0); 41 | localVersion = packageInfo.versionName; 42 | } catch (PackageManager.NameNotFoundException e) { 43 | e.printStackTrace(); 44 | } 45 | return localVersion; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/utils/DebugUtils.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.utils; 2 | 3 | import android.content.Context; 4 | import android.content.pm.ApplicationInfo; 5 | 6 | /** 7 | * author : HJQ 8 | * github : https://github.com/getActivity/AndroidProject 9 | * time : 2018/10/18 10 | * desc : Debug 判断工具类 11 | */ 12 | public final class DebugUtils { 13 | 14 | private static Boolean isDebug = null; 15 | 16 | public static boolean isDebug() { 17 | return isDebug == null ? false : isDebug; 18 | } 19 | 20 | /** 21 | * 当前是否为Debug模式 22 | */ 23 | public static void syncIsDebug(Context context) { 24 | if (isDebug == null) { 25 | isDebug = context.getApplicationInfo() != null 26 | && (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/utils/L.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.utils; 2 | 3 | 4 | import com.orhanobut.logger.AndroidLogAdapter; 5 | import com.orhanobut.logger.FormatStrategy; 6 | import com.orhanobut.logger.Logger; 7 | import com.orhanobut.logger.PrettyFormatStrategy; 8 | 9 | /** 10 | * Created by max on 2017/4/10. 11 | * LOG 日志 12 | */ 13 | public final class L 14 | { 15 | static 16 | { 17 | 18 | FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder() 19 | .showThreadInfo(false) // (Optional) Whether to show thread info or not. Default true 20 | .methodCount(0) // (Optional) How many method line to show. Default 2 21 | .methodOffset(0) // (Optional) Skips some method invokes in stack trace. Default 5 22 | // .logStrategy(customLog) // (Optional) Changes the log strategy to print out. Default LogCat 23 | .tag("MAX") // (Optional) Custom tag for each log. Default PRETTY_LOGGER 24 | .build(); 25 | 26 | AndroidLogAdapter androidLogAdapter = new AndroidLogAdapter(formatStrategy) 27 | { 28 | @Override 29 | public boolean isLoggable(int priority, String tag) 30 | { 31 | return DebugUtils.isDebug(); 32 | } 33 | }; 34 | 35 | Logger.addLogAdapter(androidLogAdapter); 36 | } 37 | 38 | private L() 39 | { 40 | } 41 | 42 | /** 43 | * 设置 TAG 44 | * 45 | * @param tag 46 | */ 47 | public static void setTag(String tag) 48 | { 49 | Logger.t(tag); 50 | } 51 | 52 | public static void v(String msg) 53 | { 54 | Logger.v(msg); 55 | } 56 | 57 | public static void i(String msg) 58 | { 59 | Logger.i(msg); 60 | } 61 | 62 | public static void e(String msg) 63 | { 64 | Logger.e(msg); 65 | } 66 | 67 | public static void d(String msg) 68 | { 69 | Logger.d(msg); 70 | } 71 | 72 | 73 | public static void v(String tag, String msg) 74 | { 75 | setTag(tag); 76 | Logger.v(msg); 77 | } 78 | 79 | public static void d(String tag, String msg) 80 | { 81 | setTag(tag); 82 | Logger.d(msg); 83 | } 84 | 85 | public static void i(String tag, String msg) 86 | { 87 | setTag(tag); 88 | Logger.i(msg); 89 | } 90 | 91 | public static void e(String tag, String msg) 92 | { 93 | setTag(tag); 94 | Logger.e(msg); 95 | } 96 | 97 | } 98 | 99 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.utils; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.content.pm.PackageManager; 6 | import android.os.Vibrator; 7 | import android.text.TextUtils; 8 | 9 | import java.util.Iterator; 10 | import java.util.LinkedHashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * Created by Max on 2018/2/12. 16 | */ 17 | 18 | public class Utils { 19 | 20 | //震动milliseconds毫秒 21 | public static void vibrate(final Context context, long milliseconds) { 22 | Vibrator vib = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE); 23 | vib.vibrate(milliseconds); 24 | } 25 | 26 | 27 | /** 28 | * 判断 list 是否为空 29 | * 30 | * @param list 31 | * @return 32 | */ 33 | public static boolean listIsEmpty(List list) { 34 | return list == null || list.isEmpty(); 35 | } 36 | 37 | /** 38 | * 获取Map 第一条数据 39 | * 40 | * @param map 41 | * @param 42 | * @param 43 | * @return 44 | */ 45 | public static Map.Entry getMapFirstEntry(LinkedHashMap map) { 46 | return map.entrySet().iterator().next(); 47 | } 48 | 49 | /** 50 | * 获取Map最后一条数据 51 | * 52 | * @param map 53 | * @param 54 | * @param 55 | * @return 56 | */ 57 | public static Map.Entry getMapLastEntry(LinkedHashMap map) { 58 | Iterator> iterator = map.entrySet().iterator(); 59 | Map.Entry tail = null; 60 | while (iterator.hasNext()) { 61 | tail = iterator.next(); 62 | } 63 | return tail; 64 | } 65 | 66 | /** 67 | * 获取微信版本号 68 | * 69 | * @return 70 | */ 71 | public static String getWeChatVersion(Context context) { 72 | try { 73 | //获取软件版本号,对应AndroidManifest.xml下android:versionCode 74 | return context.getPackageManager(). 75 | getPackageInfo("com.tencent.mm", 0).versionName; 76 | } catch (PackageManager.NameNotFoundException e) { 77 | e.printStackTrace(); 78 | } 79 | return null; 80 | } 81 | 82 | 83 | /** 84 | * 是否包含 某文本 85 | * 86 | * @param arr 数组 87 | * @param str 文本 88 | * @return 89 | */ 90 | public static boolean isArrContains(String[] arr, String str) { 91 | if (str == null || arr == null) 92 | return false; 93 | 94 | for (String s : arr) { 95 | if (!TextUtils.isEmpty(s) && str.contains(s)) { 96 | return true; 97 | } 98 | } 99 | 100 | return false; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/view/FloatingView.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.view; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.os.SystemClock; 6 | import android.view.LayoutInflater; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.view.ViewConfiguration; 10 | import android.widget.FrameLayout; 11 | 12 | import com.max.wechatluckymoney.R; 13 | import com.wang.avi.AVLoadingIndicatorView; 14 | 15 | /** 16 | * 悬浮视图 17 | * Created by Max on 2019/1/5. 18 | */ 19 | public class FloatingView extends FrameLayout 20 | { 21 | private boolean mScrolling; 22 | private float touchDownX, mStartX, mStartY; 23 | 24 | private AVLoadingIndicatorView mIndicatorViewForeground; 25 | private OnFloatingListener mListener; 26 | 27 | public FloatingView(Context context, OnFloatingListener listener) 28 | { 29 | super(context); 30 | this.mListener = listener; 31 | init(); 32 | } 33 | 34 | 35 | private void init() 36 | { 37 | LayoutInflater.from(getContext()).inflate(R.layout.layout_floating, this, true); 38 | 39 | mIndicatorViewForeground = findViewById(R.id.avi_foreground); 40 | mIndicatorViewForeground.show(); 41 | 42 | findViewById(R.id.ll_switch).setOnClickListener(view -> { 43 | if (mListener != null) 44 | { 45 | mListener.onClick(); 46 | } 47 | }); 48 | 49 | findViewById(R.id.ll_switch).setOnLongClickListener(view -> 50 | { 51 | if (mListener != null) 52 | { 53 | mListener.onLongClick(); 54 | } 55 | return true; 56 | }); 57 | } 58 | 59 | /** 60 | * 改变状态显示 61 | */ 62 | public void changeState(boolean state) 63 | { 64 | if (state) 65 | { 66 | findViewById(R.id.ll_switch).setBackgroundResource(R.drawable.bg_circle_switch_on); 67 | findViewById(R.id.iv_start).setVisibility(VISIBLE); 68 | mIndicatorViewForeground.setVisibility(GONE); 69 | mIndicatorViewForeground.hide(); 70 | } else 71 | { 72 | findViewById(R.id.ll_switch).setBackgroundResource(R.drawable.bg_circle_switch_off); 73 | findViewById(R.id.iv_start).setVisibility(GONE); 74 | mIndicatorViewForeground.setVisibility(VISIBLE); 75 | mIndicatorViewForeground.show(); 76 | } 77 | } 78 | 79 | 80 | @Override 81 | public boolean onInterceptTouchEvent(MotionEvent event) 82 | { 83 | switch (event.getAction()) 84 | { 85 | case MotionEvent.ACTION_DOWN: 86 | mStartX = (int) event.getRawX(); 87 | mStartY = (int) event.getRawY(); 88 | touchDownX = event.getX(); 89 | mScrolling = false; 90 | break; 91 | case MotionEvent.ACTION_MOVE: 92 | if (Math.abs(touchDownX - event.getX()) >= ViewConfiguration.get( 93 | getContext()).getScaledTouchSlop()) 94 | { 95 | mScrolling = true; 96 | } else 97 | { 98 | mScrolling = false; 99 | } 100 | break; 101 | case MotionEvent.ACTION_UP: 102 | mScrolling = false; 103 | break; 104 | } 105 | return mScrolling; 106 | } 107 | 108 | @Override 109 | public boolean onTouchEvent(MotionEvent motionEvent) 110 | { 111 | switch (motionEvent.getAction()) 112 | { 113 | case MotionEvent.ACTION_MOVE: 114 | float dx = mStartX - motionEvent.getRawX(); 115 | float dy = motionEvent.getRawY() - mStartY; 116 | 117 | mStartX = motionEvent.getRawX(); 118 | mStartY = motionEvent.getRawY(); 119 | 120 | if (mListener != null) 121 | { 122 | mListener.onMove(dx, dy); 123 | } 124 | break; 125 | } 126 | return super.onTouchEvent(motionEvent); 127 | } 128 | 129 | 130 | public interface OnFloatingListener 131 | { 132 | 133 | /** 134 | * 移动 135 | * 136 | * @param offsetX 偏移X 137 | * @param offsetY 偏移Y 138 | */ 139 | void onMove(float offsetX, float offsetY); 140 | 141 | void onClick(); 142 | 143 | void onLongClick(); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/java/com/max/wechatluckymoney/view/dialog/SeekBarPreference.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney.view.dialog; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.preference.DialogPreference; 6 | import android.util.AttributeSet; 7 | import android.view.View; 8 | import android.widget.SeekBar; 9 | import android.widget.TextView; 10 | 11 | import com.max.wechatluckymoney.R; 12 | 13 | 14 | /** 15 | * Created by Max on 2018/2/10. 16 | * SeekBar 17 | */ 18 | public class SeekBarPreference extends DialogPreference 19 | { 20 | private SeekBar seekBar; 21 | private TextView textView; 22 | private String hintText, prefKind; 23 | 24 | public SeekBarPreference(Context context, AttributeSet attrs) 25 | { 26 | super(context, attrs); 27 | setDialogLayoutResource(R.layout.preference_seekbar); 28 | 29 | for (int i = 0; i < attrs.getAttributeCount(); i++) 30 | { 31 | String attr = attrs.getAttributeName(i); 32 | if (attr.equalsIgnoreCase("pref_kind")) 33 | { 34 | prefKind = attrs.getAttributeValue(i); 35 | break; 36 | } 37 | } 38 | if (prefKind.equals("pref_open_delay")) 39 | { 40 | hintText = getContext().getString(R.string.delay_open); 41 | } else if (prefKind.equals("pref_comment_delay")) 42 | { 43 | hintText = "发送回复(暂不支持延时)"; 44 | } 45 | } 46 | 47 | @Override 48 | protected void onBindDialogView(View view) 49 | { 50 | super.onBindDialogView(view); 51 | 52 | SharedPreferences pref = getSharedPreferences(); 53 | 54 | int delay = pref.getInt(prefKind, 0); 55 | this.seekBar = (SeekBar) view.findViewById(R.id.delay_seekBar); 56 | this.seekBar.setProgress(delay); 57 | 58 | if (prefKind.equals("pref_comment_delay")) 59 | { 60 | this.seekBar.setEnabled(false); 61 | } 62 | 63 | this.textView = (TextView) view.findViewById(R.id.pref_seekbar_textview); 64 | setHintText(delay); 65 | 66 | this.seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() 67 | { 68 | @Override 69 | public void onProgressChanged(SeekBar seekBar, int i, boolean b) 70 | { 71 | setHintText(i); 72 | } 73 | 74 | @Override 75 | public void onStartTrackingTouch(SeekBar seekBar) 76 | { 77 | 78 | } 79 | 80 | @Override 81 | public void onStopTrackingTouch(SeekBar seekBar) 82 | { 83 | 84 | } 85 | }); 86 | } 87 | 88 | @Override 89 | protected void onDialogClosed(boolean positiveResult) 90 | { 91 | if (positiveResult) 92 | { 93 | SharedPreferences.Editor editor = getEditor(); 94 | editor.putInt(prefKind, this.seekBar.getProgress()); 95 | editor.commit(); 96 | } 97 | super.onDialogClosed(positiveResult); 98 | } 99 | 100 | private void setHintText(int delay) 101 | { 102 | if (delay == 0) 103 | { 104 | this.textView.setText(getContext().getString(R.string.delay_instantly) + hintText); 105 | } else 106 | { 107 | this.textView.setText(getContext().getString(R.string.delay_delay) + 108 | delay + getContext().getString(R.string.delay_s) + hintText); 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/drawable/bg_circle_switch_off.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/drawable/bg_circle_switch_on.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/drawable/icon_max.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/drawable/icon_max.jpg -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/drawable/progress_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |   4 |   5 | 6 | 7 | 8 | 9 | 10 |   11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/activity_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/activity_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 15 | 16 | 27 | 28 | 39 | 40 | 52 | 53 | 54 | 59 | 60 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/activity_webview.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | 25 | 26 | 41 | 42 | 54 | 55 | 56 | 59 | 60 | 65 | 66 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/layout_floating.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 25 | 26 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/preference_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 24 | 25 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/preference_checkbox.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 18 | 19 | 27 | 28 | 36 | 37 | 38 | 39 | 40 | 46 | 47 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/layout/preference_seekbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 17 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_browser.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/bg_snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/bg_snow.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_back.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_community.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_github.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_settings.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_start.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_start_floating.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_start_floating.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_start_floating_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_start_floating_2.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxhdpi/ic_stop.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/app/src/main/res/mipmap-xxxhdpi/ic_setting.png -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @color/theme 4 | @color/theme 5 | #03A388 6 | 7 | #00000000 8 | 9 | #E46C62 10 | 11 | #ffffff 12 | #dfaa6a 13 | 14 | #E46C62 15 | #E46C62 16 | #E56B61 17 | 18 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 微信红包助手 3 | 4 | 本插件只适用于微信 \n\n功能描述:\n\n\t\t\ta: 微信自助抢红包 \n\n使用说明:\n\n\t\t\t1. 打开右上方开关\n\n\t\t\t2. 进入微信APP聊天页面 \n\n\t\t\t3. 系统将自动监测领取红包 \n\n注意事项:\n\n\t\t\t1. 微信的版本升级,可能导致功能无法正常运转\n\n\t\t\t2. 部分手机会有兼容性问题,可能无法正常运转\n\n\t\t\t3. 注意悬浮操作按钮的状态哦,点击试下 5 | 6 | 7 | 大吉大利 8 | 9 | 关闭插件 10 | 开启插件 11 | 偏好设置 12 | 13 | 关于应用 14 | 设置 15 | 监视选项 16 | 监视系统通知(敬请期待) 17 | 读取新消息通知中的红包提示并进入聊天页 18 | 监视聊天列表 19 | 读取聊天列表中的红包提示并进入聊天页 20 | 防封号选项 21 | 自动拆开红包 22 | 延时拆开红包 23 | 拆开自己发的红包 24 | 帮助与反馈 25 | 前往GitHub项目主页提交issue 26 | 持续监视列表 27 | 领取红包后自动返回首页列表继续监视 28 | 29 | 快捷选项 30 | 31 | 悬浮操作 32 | 悬浮操作启动或暂停本插件 33 | 34 | 屏蔽红包文字 35 | 不拆开包含这些文字的红包(空格间隔) 36 | 37 | 屏蔽聊天对象 38 | 不拆开包含这些人或群聊发出的红包(空格间隔) 39 | 40 | 41 | 然后 42 | 延迟 43 | 立即 44 | 拆开红包 45 | 特别说明 46 | 警告 47 | 本插件仅供学习使用,使用者自行承担随之而来的各种风险,不限于“禁用红包功能”、“微信封号” 48 | 49 | 50 | https://github.com/mxruan/WechatLuckyMoney 51 | https://github.com/mxruan/WechatLuckyMoney/issues 52 | 53 | GitHub 项目主页 54 | GitHub Issues 55 | 56 | 电子邮箱 57 | mxruan@163.com 58 | 59 | 兼容性 60 | 部分手机可能无法正常使用 ^_^\" 61 | 62 | 社区 63 | GitHub 64 | 开启插件 65 | 关闭插件 66 | 67 | 在 GitHub 上 68 | 本项目,支持应用开源 69 | Star 70 | 71 | 72 | 73 | 74 | 启动 75 | 暂停 76 | 77 | 78 | 允许 79 | 去设置 80 | 退出 81 | 取消 82 | 83 | 为保证APP稳定运行, 请允许获取相关权限 84 | 获取相关权限失败,将导致部分功能无法正常使用,需要到设置页面手动授权 85 | 为保证APP稳定运行,请允许获取相关权限 86 | 87 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/xml/general_preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 17 | 18 | 19 | 22 | 28 | 34 | 40 | 41 | 44 | 49 | 54 | 59 | 64 | 69 | 70 | 73 | 78 | 83 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/xml/lucky_money_service_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/main/res/xml/provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /WechatLuckyMoney/app/src/test/java/com/max/wechatluckymoney/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.max.wechatluckymoney; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest 11 | { 12 | @Test 13 | public void addition_isCorrect() throws Exception 14 | { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /WechatLuckyMoney/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | google() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.1' 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | jcenter() 19 | google() 20 | maven { url "https://jitpack.io" } 21 | mavenCentral() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | 29 | 30 | 31 | ext{ 32 | // Sdk and tools 33 | targetSdkVersion = 28 34 | compileSdkVersion = 28 35 | minSdkVersion = 18 36 | flavorDimensions = "1.0" 37 | buildToolsVersion = '28.0.2' 38 | // Google Support 39 | supportLibraryVersion = '28.0.0' 40 | constraintlayoutVersion = '1.1.3' 41 | junitVersion = '4.12' 42 | // App dependencies 43 | butterknifeVersion = '9.0.0-rc1' 44 | } -------------------------------------------------------------------------------- /WechatLuckyMoney/build_system/LuckyMoney.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/WechatLuckyMoney/build_system/LuckyMoney.jks -------------------------------------------------------------------------------- /WechatLuckyMoney/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /WechatLuckyMoney/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Feb 09 20:07:56 GMT+08:00 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip 7 | -------------------------------------------------------------------------------- /WechatLuckyMoney/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /WechatLuckyMoney/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.ap_ 3 | 4 | # files for the dex VM 5 | *.dex 6 | 7 | # Java class files 8 | *.class 9 | 10 | # generated files 11 | bin/ 12 | gen/ 13 | 14 | # Local configuration file (sdk path, etc) 15 | local.properties 16 | 17 | # Proguard folder generated by Eclipse 18 | proguard/ 19 | 20 | # Ignore gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | .settings/ 28 | 29 | # Intellij project files 30 | *.iml 31 | *.ipr 32 | *.iws 33 | .idea/ 34 | 35 | # Mac system files 36 | .DS_Store 37 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion rootProject.ext.minSdkVersion 9 | targetSdkVersion rootProject.ext.targetSdkVersion 10 | flavorDimensions rootProject.ext.flavorDimensions 11 | versionCode 33 12 | versionName "2.1.3" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\Jack\AppData\Local\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/androidTest/java/com/wang/avi/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallBeatIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import android.animation.ValueAnimator; 7 | import com.wang.avi.Indicator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/19. 13 | */ 14 | public class BallBeatIndicator extends Indicator { 15 | 16 | public static final float SCALE=1.0f; 17 | 18 | public static final int ALPHA=255; 19 | 20 | private float[] scaleFloats=new float[]{SCALE, 21 | SCALE, 22 | SCALE}; 23 | 24 | int[] alphas=new int[]{ALPHA, 25 | ALPHA, 26 | ALPHA,}; 27 | 28 | @Override 29 | public void draw(Canvas canvas, Paint paint) { 30 | float circleSpacing=4; 31 | float radius=(getWidth()-circleSpacing*2)/6; 32 | float x = getWidth()/ 2-(radius*2+circleSpacing); 33 | float y=getHeight() / 2; 34 | for (int i = 0; i < 3; i++) { 35 | canvas.save(); 36 | float translateX=x+(radius*2)*i+circleSpacing*i; 37 | canvas.translate(translateX, y); 38 | canvas.scale(scaleFloats[i], scaleFloats[i]); 39 | paint.setAlpha(alphas[i]); 40 | canvas.drawCircle(0, 0, radius, paint); 41 | canvas.restore(); 42 | } 43 | } 44 | 45 | @Override 46 | public ArrayList onCreateAnimators() { 47 | ArrayList animators=new ArrayList<>(); 48 | int[] delays=new int[]{350,0,350}; 49 | for (int i = 0; i < 3; i++) { 50 | final int index=i; 51 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.75f,1); 52 | scaleAnim.setDuration(700); 53 | scaleAnim.setRepeatCount(-1); 54 | scaleAnim.setStartDelay(delays[i]); 55 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 56 | @Override 57 | public void onAnimationUpdate(ValueAnimator animation) { 58 | scaleFloats[index] = (float) animation.getAnimatedValue(); 59 | postInvalidate(); 60 | } 61 | }); 62 | 63 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255,51,255); 64 | alphaAnim.setDuration(700); 65 | alphaAnim.setRepeatCount(-1); 66 | alphaAnim.setStartDelay(delays[i]); 67 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 68 | @Override 69 | public void onAnimationUpdate(ValueAnimator animation) { 70 | alphas[index] = (int) animation.getAnimatedValue(); 71 | postInvalidate(); 72 | } 73 | }); 74 | animators.add(scaleAnim); 75 | animators.add(alphaAnim); 76 | } 77 | return animators; 78 | } 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallClipRotateIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/16. 14 | */ 15 | public class BallClipRotateIndicator extends Indicator { 16 | 17 | float scaleFloat=1,degrees; 18 | 19 | @Override 20 | public void draw(Canvas canvas, Paint paint) { 21 | paint.setStyle(Paint.Style.STROKE); 22 | paint.setStrokeWidth(3); 23 | 24 | float circleSpacing=12; 25 | float x = (getWidth()) / 2; 26 | float y=(getHeight()) / 2; 27 | canvas.translate(x, y); 28 | canvas.scale(scaleFloat, scaleFloat); 29 | canvas.rotate(degrees); 30 | RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,0+x-circleSpacing,0+y-circleSpacing); 31 | canvas.drawArc(rectF, -45, 270, false, paint); 32 | } 33 | 34 | @Override 35 | public ArrayList onCreateAnimators() { 36 | ArrayList animators=new ArrayList<>(); 37 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.6f,0.5f,1); 38 | scaleAnim.setDuration(750); 39 | scaleAnim.setRepeatCount(-1); 40 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 41 | @Override 42 | public void onAnimationUpdate(ValueAnimator animation) { 43 | scaleFloat = (float) animation.getAnimatedValue(); 44 | postInvalidate(); 45 | } 46 | }); 47 | ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360); 48 | rotateAnim.setDuration(750); 49 | rotateAnim.setRepeatCount(-1); 50 | addUpdateListener(rotateAnim,new ValueAnimator.AnimatorUpdateListener() { 51 | @Override 52 | public void onAnimationUpdate(ValueAnimator animation) { 53 | degrees = (float) animation.getAnimatedValue(); 54 | postInvalidate(); 55 | } 56 | }); 57 | animators.add(scaleAnim); 58 | animators.add(rotateAnim); 59 | return animators; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallClipRotateMultipleIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/17. 14 | */ 15 | public class BallClipRotateMultipleIndicator extends Indicator { 16 | 17 | float scaleFloat=1,degrees; 18 | 19 | 20 | @Override 21 | public void draw(Canvas canvas, Paint paint) { 22 | paint.setStrokeWidth(3); 23 | paint.setStyle(Paint.Style.STROKE); 24 | 25 | float circleSpacing=12; 26 | float x=getWidth()/2; 27 | float y=getHeight()/2; 28 | 29 | canvas.save(); 30 | 31 | canvas.translate(x, y); 32 | canvas.scale(scaleFloat, scaleFloat); 33 | canvas.rotate(degrees); 34 | 35 | //draw two big arc 36 | float[] bStartAngles=new float[]{135,-45}; 37 | for (int i = 0; i < 2; i++) { 38 | RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing); 39 | canvas.drawArc(rectF, bStartAngles[i], 90, false, paint); 40 | } 41 | 42 | canvas.restore(); 43 | canvas.translate(x, y); 44 | canvas.scale(scaleFloat, scaleFloat); 45 | canvas.rotate(-degrees); 46 | //draw two small arc 47 | float[] sStartAngles=new float[]{225,45}; 48 | for (int i = 0; i < 2; i++) { 49 | RectF rectF=new RectF(-x/1.8f+circleSpacing,-y/1.8f+circleSpacing,x/1.8f-circleSpacing,y/1.8f-circleSpacing); 50 | canvas.drawArc(rectF, sStartAngles[i], 90, false, paint); 51 | } 52 | } 53 | 54 | @Override 55 | public ArrayList onCreateAnimators() { 56 | ArrayList animators=new ArrayList<>(); 57 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.6f,1); 58 | scaleAnim.setDuration(2000); 59 | scaleAnim.setRepeatCount(-1); 60 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 61 | @Override 62 | public void onAnimationUpdate(ValueAnimator animation) { 63 | scaleFloat = (float) animation.getAnimatedValue(); 64 | postInvalidate(); 65 | } 66 | }); 67 | 68 | ValueAnimator rotateAnim=ValueAnimator.ofFloat(0, 180,360); 69 | rotateAnim.setDuration(1000); 70 | rotateAnim.setRepeatCount(-1); 71 | addUpdateListener(rotateAnim,new ValueAnimator.AnimatorUpdateListener() { 72 | @Override 73 | public void onAnimationUpdate(ValueAnimator animation) { 74 | degrees = (float) animation.getAnimatedValue(); 75 | postInvalidate(); 76 | } 77 | }); 78 | animators.add(scaleAnim); 79 | animators.add(rotateAnim); 80 | return animators; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallClipRotatePulseIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/16. 14 | */ 15 | public class BallClipRotatePulseIndicator extends Indicator { 16 | 17 | float scaleFloat1,scaleFloat2,degrees; 18 | 19 | 20 | @Override 21 | public void draw(Canvas canvas, Paint paint) { 22 | float circleSpacing=12; 23 | float x=getWidth()/2; 24 | float y=getHeight()/2; 25 | 26 | //draw fill circle 27 | canvas.save(); 28 | canvas.translate(x, y); 29 | canvas.scale(scaleFloat1, scaleFloat1); 30 | paint.setStyle(Paint.Style.FILL); 31 | canvas.drawCircle(0, 0, x / 2.5f, paint); 32 | 33 | canvas.restore(); 34 | 35 | canvas.translate(x, y); 36 | canvas.scale(scaleFloat2, scaleFloat2); 37 | canvas.rotate(degrees); 38 | 39 | paint.setStrokeWidth(3); 40 | paint.setStyle(Paint.Style.STROKE); 41 | 42 | //draw two arc 43 | float[] startAngles=new float[]{225,45}; 44 | for (int i = 0; i < 2; i++) { 45 | RectF rectF=new RectF(-x+circleSpacing,-y+circleSpacing,x-circleSpacing,y-circleSpacing); 46 | canvas.drawArc(rectF, startAngles[i], 90, false, paint); 47 | } 48 | } 49 | 50 | @Override 51 | public ArrayList onCreateAnimators() { 52 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1); 53 | scaleAnim.setDuration(1500); 54 | scaleAnim.setRepeatCount(-1); 55 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 56 | @Override 57 | public void onAnimationUpdate(ValueAnimator animation) { 58 | scaleFloat1 = (float) animation.getAnimatedValue(); 59 | postInvalidate(); 60 | } 61 | }); 62 | 63 | ValueAnimator scaleAnim2=ValueAnimator.ofFloat(1,0.6f,1); 64 | scaleAnim2.setDuration(1500); 65 | scaleAnim2.setRepeatCount(-1); 66 | addUpdateListener(scaleAnim2,new ValueAnimator.AnimatorUpdateListener() { 67 | @Override 68 | public void onAnimationUpdate(ValueAnimator animation) { 69 | scaleFloat2 = (float) animation.getAnimatedValue(); 70 | postInvalidate(); 71 | } 72 | }); 73 | 74 | ValueAnimator rotateAnim=ValueAnimator.ofFloat(0, 180,360); 75 | rotateAnim.setDuration(1500); 76 | rotateAnim.setRepeatCount(-1); 77 | addUpdateListener(rotateAnim,new ValueAnimator.AnimatorUpdateListener() { 78 | @Override 79 | public void onAnimationUpdate(ValueAnimator animation) { 80 | degrees = (float) animation.getAnimatedValue(); 81 | postInvalidate(); 82 | } 83 | }); 84 | ArrayList animators=new ArrayList<>(); 85 | animators.add(scaleAnim); 86 | animators.add(scaleAnim2); 87 | animators.add(rotateAnim); 88 | return animators; 89 | } 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallGridBeatIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import android.animation.ValueAnimator; 7 | import com.wang.avi.Indicator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/20. 13 | */ 14 | public class BallGridBeatIndicator extends Indicator { 15 | 16 | public static final int ALPHA=255; 17 | 18 | int[] alphas=new int[]{ALPHA, 19 | ALPHA, 20 | ALPHA, 21 | ALPHA, 22 | ALPHA, 23 | ALPHA, 24 | ALPHA, 25 | ALPHA, 26 | ALPHA}; 27 | 28 | @Override 29 | public void draw(Canvas canvas, Paint paint) { 30 | float circleSpacing=4; 31 | float radius=(getWidth()-circleSpacing*4)/6; 32 | float x = getWidth()/ 2-(radius*2+circleSpacing); 33 | float y = getWidth()/ 2-(radius*2+circleSpacing); 34 | 35 | for (int i = 0; i < 3; i++) { 36 | for (int j = 0; j < 3; j++) { 37 | canvas.save(); 38 | float translateX=x+(radius*2)*j+circleSpacing*j; 39 | float translateY=y+(radius*2)*i+circleSpacing*i; 40 | canvas.translate(translateX, translateY); 41 | paint.setAlpha(alphas[3 * i + j]); 42 | canvas.drawCircle(0, 0, radius, paint); 43 | canvas.restore(); 44 | } 45 | } 46 | } 47 | 48 | @Override 49 | public ArrayList onCreateAnimators() { 50 | ArrayList animators=new ArrayList<>(); 51 | 52 | int[] durations={960, 930, 1190, 1130, 1340, 940, 1200, 820, 1190}; 53 | int[] delays= {360, 400, 680, 410, 710, -150, -120, 10, 320}; 54 | 55 | for (int i = 0; i < 9; i++) { 56 | final int index=i; 57 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 168,255); 58 | alphaAnim.setDuration(durations[i]); 59 | alphaAnim.setRepeatCount(-1); 60 | alphaAnim.setStartDelay(delays[i]); 61 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 62 | @Override 63 | public void onAnimationUpdate(ValueAnimator animation) { 64 | alphas[index] = (int) animation.getAnimatedValue(); 65 | postInvalidate(); 66 | } 67 | }); 68 | animators.add(alphaAnim); 69 | } 70 | return animators; 71 | } 72 | 73 | 74 | 75 | 76 | } 77 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallGridPulseIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import android.animation.ValueAnimator; 7 | import com.wang.avi.Indicator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/16. 13 | */ 14 | public class BallGridPulseIndicator extends Indicator { 15 | 16 | public static final int ALPHA=255; 17 | 18 | public static final float SCALE=1.0f; 19 | 20 | int[] alphas=new int[]{ALPHA, 21 | ALPHA, 22 | ALPHA, 23 | ALPHA, 24 | ALPHA, 25 | ALPHA, 26 | ALPHA, 27 | ALPHA, 28 | ALPHA}; 29 | 30 | float[] scaleFloats=new float[]{SCALE, 31 | SCALE, 32 | SCALE, 33 | SCALE, 34 | SCALE, 35 | SCALE, 36 | SCALE, 37 | SCALE, 38 | SCALE}; 39 | 40 | 41 | 42 | @Override 43 | public void draw(Canvas canvas, Paint paint) { 44 | float circleSpacing=4; 45 | float radius=(getWidth()-circleSpacing*4)/6; 46 | float x = getWidth()/ 2-(radius*2+circleSpacing); 47 | float y = getWidth()/ 2-(radius*2+circleSpacing); 48 | 49 | for (int i = 0; i < 3; i++) { 50 | for (int j = 0; j < 3; j++) { 51 | canvas.save(); 52 | float translateX=x+(radius*2)*j+circleSpacing*j; 53 | float translateY=y+(radius*2)*i+circleSpacing*i; 54 | canvas.translate(translateX, translateY); 55 | canvas.scale(scaleFloats[3 * i + j], scaleFloats[3 * i + j]); 56 | paint.setAlpha(alphas[3 * i + j]); 57 | canvas.drawCircle(0, 0, radius, paint); 58 | canvas.restore(); 59 | } 60 | } 61 | } 62 | 63 | @Override 64 | public ArrayList onCreateAnimators() { 65 | ArrayList animators=new ArrayList<>(); 66 | int[] durations={720, 1020, 1280, 1420, 1450, 1180, 870, 1450, 1060}; 67 | int[] delays= {-60, 250, -170, 480, 310, 30, 460, 780, 450}; 68 | 69 | for (int i = 0; i < 9; i++) { 70 | final int index=i; 71 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.5f,1); 72 | scaleAnim.setDuration(durations[i]); 73 | scaleAnim.setRepeatCount(-1); 74 | scaleAnim.setStartDelay(delays[i]); 75 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 76 | @Override 77 | public void onAnimationUpdate(ValueAnimator animation) { 78 | scaleFloats[index] = (float) animation.getAnimatedValue(); 79 | postInvalidate(); 80 | } 81 | }); 82 | 83 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 210, 122, 255); 84 | alphaAnim.setDuration(durations[i]); 85 | alphaAnim.setRepeatCount(-1); 86 | alphaAnim.setStartDelay(delays[i]); 87 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 88 | @Override 89 | public void onAnimationUpdate(ValueAnimator animation) { 90 | alphas[index] = (int) animation.getAnimatedValue(); 91 | postInvalidate(); 92 | } 93 | }); 94 | animators.add(scaleAnim); 95 | animators.add(alphaAnim); 96 | } 97 | return animators; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallPulseIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import android.animation.ValueAnimator; 7 | import com.wang.avi.Indicator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/16. 13 | */ 14 | public class BallPulseIndicator extends Indicator { 15 | 16 | public static final float SCALE=1.0f; 17 | 18 | //scale x ,y 19 | private float[] scaleFloats=new float[]{SCALE, 20 | SCALE, 21 | SCALE}; 22 | 23 | 24 | 25 | @Override 26 | public void draw(Canvas canvas, Paint paint) { 27 | float circleSpacing=4; 28 | float radius=(Math.min(getWidth(),getHeight())-circleSpacing*2)/6; 29 | float x = getWidth()/ 2-(radius*2+circleSpacing); 30 | float y=getHeight() / 2; 31 | for (int i = 0; i < 3; i++) { 32 | canvas.save(); 33 | float translateX=x+(radius*2)*i+circleSpacing*i; 34 | canvas.translate(translateX, y); 35 | canvas.scale(scaleFloats[i], scaleFloats[i]); 36 | canvas.drawCircle(0, 0, radius, paint); 37 | canvas.restore(); 38 | } 39 | } 40 | 41 | @Override 42 | public ArrayList onCreateAnimators() { 43 | ArrayList animators=new ArrayList<>(); 44 | int[] delays=new int[]{120,240,360}; 45 | for (int i = 0; i < 3; i++) { 46 | final int index=i; 47 | 48 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1); 49 | 50 | scaleAnim.setDuration(750); 51 | scaleAnim.setRepeatCount(-1); 52 | scaleAnim.setStartDelay(delays[i]); 53 | 54 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 55 | @Override 56 | public void onAnimationUpdate(ValueAnimator animation) { 57 | scaleFloats[index] = (float) animation.getAnimatedValue(); 58 | postInvalidate(); 59 | } 60 | }); 61 | animators.add(scaleAnim); 62 | } 63 | return animators; 64 | } 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallPulseRiseIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Camera; 5 | import android.graphics.Canvas; 6 | import android.graphics.Matrix; 7 | import android.graphics.Paint; 8 | import android.view.animation.LinearInterpolator; 9 | 10 | import com.wang.avi.Indicator; 11 | 12 | import java.util.ArrayList; 13 | 14 | /** 15 | * Created by Jack on 2015/10/17. 16 | */ 17 | public class BallPulseRiseIndicator extends Indicator { 18 | 19 | private Camera mCamera; 20 | private Matrix mMatrix; 21 | 22 | private float degress; 23 | 24 | public BallPulseRiseIndicator(){ 25 | mCamera=new Camera(); 26 | mMatrix=new Matrix(); 27 | } 28 | 29 | @Override 30 | public void draw(Canvas canvas, Paint paint) { 31 | 32 | mMatrix.reset(); 33 | mCamera.save(); 34 | mCamera.rotateX(degress); 35 | mCamera.getMatrix(mMatrix); 36 | mCamera.restore(); 37 | 38 | mMatrix.preTranslate(-centerX(), -centerY()); 39 | mMatrix.postTranslate(centerX(), centerY()); 40 | canvas.concat(mMatrix); 41 | 42 | float radius=getWidth()/10; 43 | canvas.drawCircle(getWidth()/4,radius*2,radius,paint); 44 | canvas.drawCircle(getWidth()*3/4,radius*2,radius,paint); 45 | 46 | canvas.drawCircle(radius,getHeight()-2*radius,radius,paint); 47 | canvas.drawCircle(getWidth()/2,getHeight()-2*radius,radius,paint); 48 | canvas.drawCircle(getWidth()-radius,getHeight()-2*radius,radius,paint); 49 | } 50 | 51 | @Override 52 | public ArrayList onCreateAnimators() { 53 | ArrayList animators=new ArrayList<>(); 54 | ValueAnimator animator=ValueAnimator.ofFloat(0,360); 55 | addUpdateListener(animator,new ValueAnimator.AnimatorUpdateListener() { 56 | @Override 57 | public void onAnimationUpdate(ValueAnimator animation) { 58 | degress = (float) animation.getAnimatedValue(); 59 | postInvalidate(); 60 | } 61 | }); 62 | animator.setInterpolator(new LinearInterpolator()); 63 | animator.setRepeatCount(-1); 64 | animator.setDuration(1500); 65 | animators.add(animator); 66 | return animators; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallPulseSyncIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import android.animation.ValueAnimator; 7 | import com.wang.avi.Indicator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/19. 13 | */ 14 | public class BallPulseSyncIndicator extends Indicator { 15 | 16 | float[] translateYFloats=new float[3]; 17 | 18 | @Override 19 | public void draw(Canvas canvas, Paint paint) { 20 | float circleSpacing=4; 21 | float radius=(getWidth()-circleSpacing*2)/6; 22 | float x = getWidth()/ 2-(radius*2+circleSpacing); 23 | for (int i = 0; i < 3; i++) { 24 | canvas.save(); 25 | float translateX=x+(radius*2)*i+circleSpacing*i; 26 | canvas.translate(translateX, translateYFloats[i]); 27 | canvas.drawCircle(0, 0, radius, paint); 28 | canvas.restore(); 29 | } 30 | } 31 | 32 | @Override 33 | public ArrayList onCreateAnimators() { 34 | ArrayList animators=new ArrayList<>(); 35 | float circleSpacing=4; 36 | float radius=(getWidth()-circleSpacing*2)/6; 37 | int[] delays=new int[]{70,140,210}; 38 | for (int i = 0; i < 3; i++) { 39 | final int index=i; 40 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(getHeight()/2,getHeight()/2-radius*2,getHeight()/2); 41 | scaleAnim.setDuration(600); 42 | scaleAnim.setRepeatCount(-1); 43 | scaleAnim.setStartDelay(delays[i]); 44 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 45 | @Override 46 | public void onAnimationUpdate(ValueAnimator animation) { 47 | translateYFloats[index] = (float) animation.getAnimatedValue(); 48 | postInvalidate(); 49 | } 50 | }); 51 | animators.add(scaleAnim); 52 | } 53 | return animators; 54 | } 55 | 56 | 57 | } 58 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallRotateIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Matrix; 6 | import android.graphics.Paint; 7 | 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/17. 14 | */ 15 | public class BallRotateIndicator extends Indicator { 16 | 17 | float scaleFloat=0.5f; 18 | 19 | float degress; 20 | 21 | private Matrix mMatrix; 22 | 23 | public BallRotateIndicator(){ 24 | mMatrix=new Matrix(); 25 | } 26 | 27 | @Override 28 | public void draw(Canvas canvas, Paint paint) { 29 | float radius=getWidth()/10; 30 | float x = getWidth()/ 2; 31 | float y=getHeight()/2; 32 | 33 | /*mMatrix.preTranslate(-centerX(), -centerY()); 34 | mMatrix.preRotate(degress,centerX(),centerY()); 35 | mMatrix.postTranslate(centerX(), centerY()); 36 | canvas.concat(mMatrix);*/ 37 | 38 | canvas.rotate(degress,centerX(),centerY()); 39 | 40 | canvas.save(); 41 | canvas.translate(x - radius * 2 - radius, y); 42 | canvas.scale(scaleFloat, scaleFloat); 43 | canvas.drawCircle(0, 0, radius, paint); 44 | canvas.restore(); 45 | 46 | canvas.save(); 47 | canvas.translate(x, y); 48 | canvas.scale(scaleFloat, scaleFloat); 49 | canvas.drawCircle(0, 0, radius, paint); 50 | canvas.restore(); 51 | 52 | canvas.save(); 53 | canvas.translate(x + radius * 2 + radius, y); 54 | canvas.scale(scaleFloat, scaleFloat); 55 | canvas.drawCircle(0,0,radius, paint); 56 | canvas.restore(); 57 | } 58 | 59 | @Override 60 | public ArrayList onCreateAnimators() { 61 | ArrayList animators=new ArrayList<>(); 62 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(0.5f,1,0.5f); 63 | scaleAnim.setDuration(1000); 64 | scaleAnim.setRepeatCount(-1); 65 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 66 | @Override 67 | public void onAnimationUpdate(ValueAnimator animation) { 68 | scaleFloat = (float) animation.getAnimatedValue(); 69 | postInvalidate(); 70 | } 71 | }); 72 | 73 | ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360); 74 | addUpdateListener(rotateAnim,new ValueAnimator.AnimatorUpdateListener() { 75 | @Override 76 | public void onAnimationUpdate(ValueAnimator animation) { 77 | degress = (float) animation.getAnimatedValue(); 78 | postInvalidate(); 79 | } 80 | }); 81 | rotateAnim.setDuration(1000); 82 | rotateAnim.setRepeatCount(-1); 83 | 84 | animators.add(scaleAnim); 85 | animators.add(rotateAnim); 86 | return animators; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallScaleIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/19. 14 | */ 15 | public class BallScaleIndicator extends Indicator { 16 | 17 | float scale=1; 18 | int alpha=255; 19 | 20 | @Override 21 | public void draw(Canvas canvas, Paint paint) { 22 | float circleSpacing=4; 23 | paint.setAlpha(alpha); 24 | canvas.scale(scale,scale,getWidth()/2,getHeight()/2); 25 | paint.setAlpha(alpha); 26 | canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2-circleSpacing,paint); 27 | } 28 | 29 | @Override 30 | public ArrayList onCreateAnimators() { 31 | ArrayList animators=new ArrayList<>(); 32 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(0f,1); 33 | scaleAnim.setInterpolator(new LinearInterpolator()); 34 | scaleAnim.setDuration(2000); 35 | scaleAnim.setRepeatCount(-1); 36 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 37 | @Override 38 | public void onAnimationUpdate(ValueAnimator animation) { 39 | scale = (float) animation.getAnimatedValue(); 40 | postInvalidate(); 41 | } 42 | }); 43 | 44 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 0); 45 | alphaAnim.setInterpolator(new LinearInterpolator()); 46 | alphaAnim.setDuration(1000); 47 | alphaAnim.setRepeatCount(-1); 48 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 49 | @Override 50 | public void onAnimationUpdate(ValueAnimator animation) { 51 | alpha = (int) animation.getAnimatedValue(); 52 | postInvalidate(); 53 | } 54 | }); 55 | animators.add(scaleAnim); 56 | animators.add(alphaAnim); 57 | return animators; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallScaleMultipleIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/19. 14 | */ 15 | public class BallScaleMultipleIndicator extends Indicator { 16 | 17 | float[] scaleFloats=new float[]{1,1,1}; 18 | int[] alphaInts=new int[]{255,255,255}; 19 | 20 | @Override 21 | public void draw(Canvas canvas, Paint paint) { 22 | float circleSpacing=4; 23 | for (int i = 0; i < 3; i++) { 24 | paint.setAlpha(alphaInts[i]); 25 | canvas.scale(scaleFloats[i],scaleFloats[i],getWidth()/2,getHeight()/2); 26 | canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/2-circleSpacing,paint); 27 | } 28 | } 29 | 30 | @Override 31 | public ArrayList onCreateAnimators() { 32 | ArrayList animators=new ArrayList<>(); 33 | long[] delays=new long[]{0, 200, 400}; 34 | for (int i = 0; i < 3; i++) { 35 | final int index=i; 36 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); 37 | scaleAnim.setInterpolator(new LinearInterpolator()); 38 | scaleAnim.setDuration(1000); 39 | scaleAnim.setRepeatCount(-1); 40 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 41 | @Override 42 | public void onAnimationUpdate(ValueAnimator animation) { 43 | scaleFloats[index] = (float) animation.getAnimatedValue(); 44 | postInvalidate(); 45 | } 46 | }); 47 | scaleAnim.setStartDelay(delays[i]); 48 | 49 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255,0); 50 | alphaAnim.setInterpolator(new LinearInterpolator()); 51 | alphaAnim.setDuration(1000); 52 | alphaAnim.setRepeatCount(-1); 53 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 54 | @Override 55 | public void onAnimationUpdate(ValueAnimator animation) { 56 | alphaInts[index] = (int) animation.getAnimatedValue(); 57 | postInvalidate(); 58 | } 59 | }); 60 | scaleAnim.setStartDelay(delays[i]); 61 | 62 | animators.add(scaleAnim); 63 | animators.add(alphaAnim); 64 | } 65 | return animators; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallScaleRippleIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import android.animation.ValueAnimator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/19. 13 | */ 14 | public class BallScaleRippleIndicator extends BallScaleIndicator { 15 | 16 | 17 | @Override 18 | public void draw(Canvas canvas, Paint paint) { 19 | paint.setStyle(Paint.Style.STROKE); 20 | paint.setStrokeWidth(3); 21 | super.draw(canvas, paint); 22 | } 23 | 24 | @Override 25 | public ArrayList onCreateAnimators() { 26 | ArrayList animators=new ArrayList<>(); 27 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); 28 | scaleAnim.setInterpolator(new LinearInterpolator()); 29 | scaleAnim.setDuration(1000); 30 | scaleAnim.setRepeatCount(-1); 31 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 32 | @Override 33 | public void onAnimationUpdate(ValueAnimator animation) { 34 | scale = (float) animation.getAnimatedValue(); 35 | postInvalidate(); 36 | } 37 | }); 38 | 39 | ValueAnimator alphaAnim=ValueAnimator.ofInt(0, 255); 40 | alphaAnim.setInterpolator(new LinearInterpolator()); 41 | alphaAnim.setDuration(1000); 42 | alphaAnim.setRepeatCount(-1); 43 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 44 | @Override 45 | public void onAnimationUpdate(ValueAnimator animation) { 46 | alpha = (int) animation.getAnimatedValue(); 47 | postInvalidate(); 48 | } 49 | }); 50 | 51 | animators.add(scaleAnim); 52 | animators.add(alphaAnim); 53 | return animators; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallScaleRippleMultipleIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import android.animation.ValueAnimator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/19. 13 | */ 14 | public class BallScaleRippleMultipleIndicator extends BallScaleMultipleIndicator { 15 | 16 | 17 | @Override 18 | public void draw(Canvas canvas, Paint paint) { 19 | paint.setStyle(Paint.Style.STROKE); 20 | paint.setStrokeWidth(3); 21 | super.draw(canvas, paint); 22 | } 23 | 24 | @Override 25 | public ArrayList onCreateAnimators() { 26 | ArrayList animators=new ArrayList<>(); 27 | long[] delays=new long[]{0, 200, 400}; 28 | for (int i = 0; i < 3; i++) { 29 | final int index=i; 30 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(0,1); 31 | scaleAnim.setInterpolator(new LinearInterpolator()); 32 | scaleAnim.setDuration(1000); 33 | scaleAnim.setRepeatCount(-1); 34 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 35 | @Override 36 | public void onAnimationUpdate(ValueAnimator animation) { 37 | scaleFloats[index] = (float) animation.getAnimatedValue(); 38 | postInvalidate(); 39 | } 40 | }); 41 | scaleAnim.setStartDelay(delays[i]); 42 | 43 | ValueAnimator alphaAnim=ValueAnimator.ofInt(0,255); 44 | scaleAnim.setInterpolator(new LinearInterpolator()); 45 | alphaAnim.setDuration(1000); 46 | alphaAnim.setRepeatCount(-1); 47 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 48 | @Override 49 | public void onAnimationUpdate(ValueAnimator animation) { 50 | alphaInts[index] = (int) animation.getAnimatedValue(); 51 | postInvalidate(); 52 | } 53 | }); 54 | scaleAnim.setStartDelay(delays[i]); 55 | 56 | animators.add(scaleAnim); 57 | animators.add(alphaAnim); 58 | } 59 | return animators; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallSpinFadeLoaderIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | import android.animation.ValueAnimator; 7 | import com.wang.avi.Indicator; 8 | 9 | import java.util.ArrayList; 10 | 11 | /** 12 | * Created by Jack on 2015/10/20. 13 | */ 14 | public class BallSpinFadeLoaderIndicator extends Indicator { 15 | 16 | public static final float SCALE=1.0f; 17 | 18 | public static final int ALPHA=255; 19 | 20 | float[] scaleFloats=new float[]{SCALE, 21 | SCALE, 22 | SCALE, 23 | SCALE, 24 | SCALE, 25 | SCALE, 26 | SCALE, 27 | SCALE}; 28 | 29 | int[] alphas=new int[]{ALPHA, 30 | ALPHA, 31 | ALPHA, 32 | ALPHA, 33 | ALPHA, 34 | ALPHA, 35 | ALPHA, 36 | ALPHA}; 37 | 38 | 39 | @Override 40 | public void draw(Canvas canvas, Paint paint) { 41 | float radius=getWidth()/10; 42 | for (int i = 0; i < 8; i++) { 43 | canvas.save(); 44 | Point point=circleAt(getWidth(),getHeight(),getWidth()/2-radius,i*(Math.PI/4)); 45 | canvas.translate(point.x,point.y); 46 | canvas.scale(scaleFloats[i],scaleFloats[i]); 47 | paint.setAlpha(alphas[i]); 48 | canvas.drawCircle(0,0,radius,paint); 49 | canvas.restore(); 50 | } 51 | } 52 | 53 | @Override 54 | public ArrayList onCreateAnimators() { 55 | ArrayList animators=new ArrayList<>(); 56 | int[] delays= {0, 120, 240, 360, 480, 600, 720, 780, 840}; 57 | for (int i = 0; i < 8; i++) { 58 | final int index=i; 59 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1); 60 | scaleAnim.setDuration(1000); 61 | scaleAnim.setRepeatCount(-1); 62 | scaleAnim.setStartDelay(delays[i]); 63 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 64 | @Override 65 | public void onAnimationUpdate(ValueAnimator animation) { 66 | scaleFloats[index] = (float) animation.getAnimatedValue(); 67 | postInvalidate(); 68 | } 69 | }); 70 | 71 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 77, 255); 72 | alphaAnim.setDuration(1000); 73 | alphaAnim.setRepeatCount(-1); 74 | alphaAnim.setStartDelay(delays[i]); 75 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 76 | @Override 77 | public void onAnimationUpdate(ValueAnimator animation) { 78 | alphas[index] = (int) animation.getAnimatedValue(); 79 | postInvalidate(); 80 | } 81 | }); 82 | animators.add(scaleAnim); 83 | animators.add(alphaAnim); 84 | } 85 | return animators; 86 | } 87 | 88 | /** 89 | * 圆O的圆心为(a,b),半径为R,点A与到X轴的为角α. 90 | *则点A的坐标为(a+R*cosα,b+R*sinα) 91 | * @param width 92 | * @param height 93 | * @param radius 94 | * @param angle 95 | * @return 96 | */ 97 | Point circleAt(int width,int height,float radius,double angle){ 98 | float x= (float) (width/2+radius*(Math.cos(angle))); 99 | float y= (float) (height/2+radius*(Math.sin(angle))); 100 | return new Point(x,y); 101 | } 102 | 103 | final class Point{ 104 | public float x; 105 | public float y; 106 | 107 | public Point(float x, float y){ 108 | this.x=x; 109 | this.y=y; 110 | } 111 | } 112 | 113 | 114 | } 115 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallTrianglePathIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/19. 14 | */ 15 | public class BallTrianglePathIndicator extends Indicator { 16 | 17 | float[] translateX=new float[3],translateY=new float[3]; 18 | 19 | @Override 20 | public void draw(Canvas canvas, Paint paint) { 21 | paint.setStrokeWidth(3); 22 | paint.setStyle(Paint.Style.STROKE); 23 | for (int i = 0; i < 3; i++) { 24 | canvas.save(); 25 | canvas.translate(translateX[i], translateY[i]); 26 | canvas.drawCircle(0, 0, getWidth() / 10, paint); 27 | canvas.restore(); 28 | } 29 | } 30 | 31 | @Override 32 | public ArrayList onCreateAnimators() { 33 | ArrayList animators=new ArrayList<>(); 34 | float startX=getWidth()/5; 35 | float startY=getWidth()/5; 36 | for (int i = 0; i < 3; i++) { 37 | final int index=i; 38 | ValueAnimator translateXAnim=ValueAnimator.ofFloat(getWidth()/2,getWidth()-startX,startX,getWidth()/2); 39 | if (i==1){ 40 | translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()/2,getWidth()-startX); 41 | }else if (i==2){ 42 | translateXAnim=ValueAnimator.ofFloat(startX,getWidth()/2,getWidth()-startX,startX); 43 | } 44 | ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,getHeight()-startY,getHeight()-startY,startY); 45 | if (i==1){ 46 | translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,getHeight()-startY); 47 | }else if (i==2){ 48 | translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,startY,getHeight()-startY,getHeight()-startY); 49 | } 50 | 51 | translateXAnim.setDuration(2000); 52 | translateXAnim.setInterpolator(new LinearInterpolator()); 53 | translateXAnim.setRepeatCount(-1); 54 | addUpdateListener(translateXAnim,new ValueAnimator.AnimatorUpdateListener() { 55 | @Override 56 | public void onAnimationUpdate(ValueAnimator animation) { 57 | translateX [index]= (float) animation.getAnimatedValue(); 58 | postInvalidate(); 59 | } 60 | }); 61 | 62 | translateYAnim.setDuration(2000); 63 | translateYAnim.setInterpolator(new LinearInterpolator()); 64 | translateYAnim.setRepeatCount(-1); 65 | addUpdateListener(translateYAnim,new ValueAnimator.AnimatorUpdateListener() { 66 | @Override 67 | public void onAnimationUpdate(ValueAnimator animation) { 68 | translateY [index]= (float) animation.getAnimatedValue(); 69 | postInvalidate(); 70 | } 71 | }); 72 | 73 | animators.add(translateXAnim); 74 | animators.add(translateYAnim); 75 | } 76 | return animators; 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallZigZagDeflectIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | 4 | import android.view.animation.LinearInterpolator; 5 | import android.animation.ValueAnimator; 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * Created by Jack on 2015/10/19. 10 | */ 11 | public class BallZigZagDeflectIndicator extends BallZigZagIndicator { 12 | 13 | 14 | 15 | 16 | @Override 17 | public ArrayList onCreateAnimators() { 18 | ArrayList animators=new ArrayList<>(); 19 | float startX=getWidth()/6; 20 | float startY=getWidth()/6; 21 | for (int i = 0; i < 2; i++) { 22 | final int index=i; 23 | ValueAnimator translateXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,startX,getWidth()-startX,startX); 24 | if (i==1){ 25 | translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()-startX,startX,getWidth()-startX); 26 | } 27 | ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()-startY,getHeight()-startY,startY); 28 | if (i==1){ 29 | translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,startY,getHeight()-startY); 30 | } 31 | 32 | translateXAnim.setDuration(2000); 33 | translateXAnim.setInterpolator(new LinearInterpolator()); 34 | translateXAnim.setRepeatCount(-1); 35 | addUpdateListener(translateXAnim,new ValueAnimator.AnimatorUpdateListener() { 36 | @Override 37 | public void onAnimationUpdate(ValueAnimator animation) { 38 | translateX [index]= (float) animation.getAnimatedValue(); 39 | postInvalidate(); 40 | } 41 | }); 42 | 43 | translateYAnim.setDuration(2000); 44 | translateYAnim.setInterpolator(new LinearInterpolator()); 45 | translateYAnim.setRepeatCount(-1); 46 | addUpdateListener(translateYAnim,new ValueAnimator.AnimatorUpdateListener() { 47 | @Override 48 | public void onAnimationUpdate(ValueAnimator animation) { 49 | translateY [index]= (float) animation.getAnimatedValue(); 50 | postInvalidate(); 51 | } 52 | }); 53 | 54 | animators.add(translateXAnim); 55 | animators.add(translateYAnim); 56 | } 57 | return animators; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/BallZigZagIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.view.animation.LinearInterpolator; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/19. 14 | */ 15 | public class BallZigZagIndicator extends Indicator { 16 | 17 | float[] translateX=new float[2],translateY=new float[2]; 18 | 19 | 20 | @Override 21 | public void draw(Canvas canvas, Paint paint) { 22 | for (int i = 0; i < 2; i++) { 23 | canvas.save(); 24 | canvas.translate(translateX[i], translateY[i]); 25 | canvas.drawCircle(0, 0, getWidth() / 10, paint); 26 | canvas.restore(); 27 | } 28 | } 29 | 30 | @Override 31 | public ArrayList onCreateAnimators() { 32 | ArrayList animators=new ArrayList<>(); 33 | float startX=getWidth()/6; 34 | float startY=getWidth()/6; 35 | for (int i = 0; i < 2; i++) { 36 | final int index=i; 37 | ValueAnimator translateXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,getWidth()/2,startX); 38 | if (i==1){ 39 | translateXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,getWidth()/2,getWidth()-startX); 40 | } 41 | ValueAnimator translateYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()/2,startY); 42 | if (i==1){ 43 | translateYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,getHeight()/2,getHeight()-startY); 44 | } 45 | 46 | translateXAnim.setDuration(1000); 47 | translateXAnim.setInterpolator(new LinearInterpolator()); 48 | translateXAnim.setRepeatCount(-1); 49 | addUpdateListener(translateXAnim,new ValueAnimator.AnimatorUpdateListener() { 50 | @Override 51 | public void onAnimationUpdate(ValueAnimator animation) { 52 | translateX[index] = (float) animation.getAnimatedValue(); 53 | postInvalidate(); 54 | } 55 | }); 56 | 57 | translateYAnim.setDuration(1000); 58 | translateYAnim.setInterpolator(new LinearInterpolator()); 59 | translateYAnim.setRepeatCount(-1); 60 | addUpdateListener(translateYAnim,new ValueAnimator.AnimatorUpdateListener() { 61 | @Override 62 | public void onAnimationUpdate(ValueAnimator animation) { 63 | translateY[index] = (float) animation.getAnimatedValue(); 64 | postInvalidate(); 65 | } 66 | }); 67 | animators.add(translateXAnim); 68 | animators.add(translateYAnim); 69 | } 70 | return animators; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/CubeTransitionIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | import android.view.animation.LinearInterpolator; 7 | 8 | import android.animation.ValueAnimator; 9 | import com.wang.avi.Indicator; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Created by Jack on 2015/10/18. 15 | */ 16 | public class CubeTransitionIndicator extends Indicator { 17 | 18 | float[] translateX=new float[2],translateY=new float[2]; 19 | float degrees,scaleFloat=1.0f; 20 | 21 | @Override 22 | public void draw(Canvas canvas, Paint paint) { 23 | float rWidth=getWidth()/5; 24 | float rHeight=getHeight()/5; 25 | for (int i = 0; i < 2; i++) { 26 | canvas.save(); 27 | canvas.translate(translateX[i], translateY[i]); 28 | canvas.rotate(degrees); 29 | canvas.scale(scaleFloat,scaleFloat); 30 | RectF rectF=new RectF(-rWidth/2,-rHeight/2,rWidth/2,rHeight/2); 31 | canvas.drawRect(rectF,paint); 32 | canvas.restore(); 33 | } 34 | } 35 | 36 | @Override 37 | public ArrayList onCreateAnimators() { 38 | ArrayList animators=new ArrayList<>(); 39 | float startX=getWidth()/5; 40 | float startY=getHeight()/5; 41 | for (int i = 0; i < 2; i++) { 42 | final int index=i; 43 | translateX[index]=startX; 44 | ValueAnimator translationXAnim=ValueAnimator.ofFloat(startX,getWidth()-startX,getWidth()-startX, startX,startX); 45 | if (i==1){ 46 | translationXAnim=ValueAnimator.ofFloat(getWidth()-startX,startX,startX, getWidth()-startX,getWidth()-startX); 47 | } 48 | translationXAnim.setInterpolator(new LinearInterpolator()); 49 | translationXAnim.setDuration(1600); 50 | translationXAnim.setRepeatCount(-1); 51 | translationXAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 52 | @Override 53 | public void onAnimationUpdate(ValueAnimator animation) { 54 | translateX[index] = (float) animation.getAnimatedValue(); 55 | postInvalidate(); 56 | } 57 | }); 58 | translateY[index]=startY; 59 | ValueAnimator translationYAnim=ValueAnimator.ofFloat(startY,startY,getHeight()-startY,getHeight()- startY,startY); 60 | if (i==1){ 61 | translationYAnim=ValueAnimator.ofFloat(getHeight()-startY,getHeight()-startY,startY,startY,getHeight()-startY); 62 | } 63 | translationYAnim.setDuration(1600); 64 | translationYAnim.setInterpolator(new LinearInterpolator()); 65 | translationYAnim.setRepeatCount(-1); 66 | addUpdateListener(translationYAnim,new ValueAnimator.AnimatorUpdateListener() { 67 | @Override 68 | public void onAnimationUpdate(ValueAnimator animation) { 69 | translateY[index] = (float) animation.getAnimatedValue(); 70 | postInvalidate(); 71 | } 72 | }); 73 | 74 | animators.add(translationXAnim); 75 | animators.add(translationYAnim); 76 | } 77 | 78 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.5f,1,0.5f,1); 79 | scaleAnim.setDuration(1600); 80 | scaleAnim.setInterpolator(new LinearInterpolator()); 81 | scaleAnim.setRepeatCount(-1); 82 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 83 | @Override 84 | public void onAnimationUpdate(ValueAnimator animation) { 85 | scaleFloat = (float) animation.getAnimatedValue(); 86 | postInvalidate(); 87 | } 88 | }); 89 | 90 | ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360,1.5f*360,2*360); 91 | rotateAnim.setDuration(1600); 92 | rotateAnim.setInterpolator(new LinearInterpolator()); 93 | rotateAnim.setRepeatCount(-1); 94 | addUpdateListener(rotateAnim,new ValueAnimator.AnimatorUpdateListener() { 95 | @Override 96 | public void onAnimationUpdate(ValueAnimator animation) { 97 | degrees = (float) animation.getAnimatedValue(); 98 | postInvalidate(); 99 | } 100 | }); 101 | 102 | animators.add(scaleAnim); 103 | animators.add(rotateAnim); 104 | return animators; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/LineScaleIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/19. 14 | */ 15 | public class LineScaleIndicator extends Indicator { 16 | 17 | public static final float SCALE=1.0f; 18 | 19 | float[] scaleYFloats=new float[]{SCALE, 20 | SCALE, 21 | SCALE, 22 | SCALE, 23 | SCALE,}; 24 | 25 | @Override 26 | public void draw(Canvas canvas, Paint paint) { 27 | float translateX=getWidth()/11; 28 | float translateY=getHeight()/2; 29 | for (int i = 0; i < 5; i++) { 30 | canvas.save(); 31 | canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY); 32 | canvas.scale(SCALE, scaleYFloats[i]); 33 | RectF rectF=new RectF(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f); 34 | canvas.drawRoundRect(rectF, 5, 5, paint); 35 | canvas.restore(); 36 | } 37 | } 38 | 39 | @Override 40 | public ArrayList onCreateAnimators() { 41 | ArrayList animators=new ArrayList<>(); 42 | long[] delays=new long[]{100,200,300,400,500}; 43 | for (int i = 0; i < 5; i++) { 44 | final int index=i; 45 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1, 0.4f, 1); 46 | scaleAnim.setDuration(1000); 47 | scaleAnim.setRepeatCount(-1); 48 | scaleAnim.setStartDelay(delays[i]); 49 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 50 | @Override 51 | public void onAnimationUpdate(ValueAnimator animation) { 52 | scaleYFloats[index] = (float) animation.getAnimatedValue(); 53 | postInvalidate(); 54 | } 55 | }); 56 | animators.add(scaleAnim); 57 | } 58 | return animators; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/LineScalePartyIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | import android.animation.ValueAnimator; 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/19. 14 | */ 15 | public class LineScalePartyIndicator extends Indicator { 16 | 17 | public static final float SCALE=1.0f; 18 | 19 | float[] scaleFloats=new float[]{SCALE, 20 | SCALE, 21 | SCALE, 22 | SCALE, 23 | SCALE,}; 24 | 25 | @Override 26 | public void draw(Canvas canvas, Paint paint) { 27 | float translateX=getWidth()/9; 28 | float translateY=getHeight()/2; 29 | for (int i = 0; i < 4; i++) { 30 | canvas.save(); 31 | canvas.translate((2 + i * 2) * translateX - translateX / 2, translateY); 32 | canvas.scale(scaleFloats[i], scaleFloats[i]); 33 | RectF rectF=new RectF(-translateX/2,-getHeight()/2.5f,translateX/2,getHeight()/2.5f); 34 | canvas.drawRoundRect(rectF,5,5,paint); 35 | canvas.restore(); 36 | } 37 | } 38 | 39 | 40 | @Override 41 | public ArrayList onCreateAnimators() { 42 | ArrayList animators=new ArrayList<>(); 43 | long[] durations=new long[]{1260, 430, 1010, 730}; 44 | long[] delays=new long[]{770, 290, 280, 740}; 45 | for (int i = 0; i < 4; i++) { 46 | final int index=i; 47 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1); 48 | scaleAnim.setDuration(durations[i]); 49 | scaleAnim.setRepeatCount(-1); 50 | scaleAnim.setStartDelay(delays[i]); 51 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 52 | @Override 53 | public void onAnimationUpdate(ValueAnimator animation) { 54 | scaleFloats[index] = (float) animation.getAnimatedValue(); 55 | postInvalidate(); 56 | } 57 | }); 58 | animators.add(scaleAnim); 59 | } 60 | return animators; 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/LineScalePulseOutIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | 4 | import android.animation.ValueAnimator; 5 | 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * Created by Jack on 2015/10/19. 10 | */ 11 | public class LineScalePulseOutIndicator extends LineScaleIndicator { 12 | 13 | @Override 14 | public ArrayList onCreateAnimators() { 15 | ArrayList animators=new ArrayList<>(); 16 | long[] delays=new long[]{500,250,0,250,500}; 17 | for (int i = 0; i < 5; i++) { 18 | final int index=i; 19 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.3f,1); 20 | scaleAnim.setDuration(900); 21 | scaleAnim.setRepeatCount(-1); 22 | scaleAnim.setStartDelay(delays[i]); 23 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 24 | @Override 25 | public void onAnimationUpdate(ValueAnimator animation) { 26 | scaleYFloats[index] = (float) animation.getAnimatedValue(); 27 | postInvalidate(); 28 | } 29 | }); 30 | animators.add(scaleAnim); 31 | } 32 | return animators; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/LineScalePulseOutRapidIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | 4 | import android.animation.ValueAnimator; 5 | 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * Created by Jack on 2015/10/19. 10 | */ 11 | public class LineScalePulseOutRapidIndicator extends LineScaleIndicator { 12 | 13 | @Override 14 | public ArrayList onCreateAnimators() { 15 | ArrayList animators=new ArrayList<>(); 16 | long[] delays=new long[]{400,200,0,200,400}; 17 | for (int i = 0; i < 5; i++) { 18 | final int index=i; 19 | ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1); 20 | scaleAnim.setDuration(1000); 21 | scaleAnim.setRepeatCount(-1); 22 | scaleAnim.setStartDelay(delays[i]); 23 | addUpdateListener(scaleAnim,new ValueAnimator.AnimatorUpdateListener() { 24 | @Override 25 | public void onAnimationUpdate(ValueAnimator animation) { 26 | scaleYFloats[index] = (float) animation.getAnimatedValue(); 27 | postInvalidate(); 28 | } 29 | }); 30 | animators.add(scaleAnim); 31 | } 32 | return animators; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/LineSpinFadeLoaderIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | /** 8 | * Created by Jack on 2015/10/24. 9 | * Email:81813780@qq.com 10 | */ 11 | public class LineSpinFadeLoaderIndicator extends BallSpinFadeLoaderIndicator { 12 | 13 | 14 | @Override 15 | public void draw(Canvas canvas, Paint paint) { 16 | float radius=getWidth()/10; 17 | for (int i = 0; i < 8; i++) { 18 | canvas.save(); 19 | Point point=circleAt(getWidth(),getHeight(),getWidth()/2.5f-radius,i*(Math.PI/4)); 20 | canvas.translate(point.x, point.y); 21 | canvas.scale(scaleFloats[i], scaleFloats[i]); 22 | canvas.rotate(i*45); 23 | paint.setAlpha(alphas[i]); 24 | RectF rectF=new RectF(-radius,-radius/1.5f,1.5f*radius,radius/1.5f); 25 | canvas.drawRoundRect(rectF,5,5,paint); 26 | canvas.restore(); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/PacmanIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | import android.view.animation.LinearInterpolator; 7 | 8 | import android.animation.ValueAnimator; 9 | import com.wang.avi.Indicator; 10 | 11 | import java.util.ArrayList; 12 | 13 | /** 14 | * Created by Jack on 2015/10/16. 15 | */ 16 | public class PacmanIndicator extends Indicator { 17 | 18 | private float translateX; 19 | 20 | private int alpha; 21 | 22 | private float degrees1,degrees2; 23 | 24 | @Override 25 | public void draw(Canvas canvas, Paint paint) { 26 | drawPacman(canvas,paint); 27 | drawCircle(canvas,paint); 28 | } 29 | 30 | private void drawPacman(Canvas canvas,Paint paint){ 31 | float x=getWidth()/2; 32 | float y=getHeight()/2; 33 | 34 | canvas.save(); 35 | 36 | canvas.translate(x, y); 37 | canvas.rotate(degrees1); 38 | paint.setAlpha(255); 39 | RectF rectF1=new RectF(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f); 40 | canvas.drawArc(rectF1, 0, 270, true, paint); 41 | 42 | canvas.restore(); 43 | 44 | canvas.save(); 45 | canvas.translate(x, y); 46 | canvas.rotate(degrees2); 47 | paint.setAlpha(255); 48 | RectF rectF2=new RectF(-x/1.7f,-y/1.7f,x/1.7f,y/1.7f); 49 | canvas.drawArc(rectF2,90,270,true,paint); 50 | canvas.restore(); 51 | } 52 | 53 | 54 | private void drawCircle(Canvas canvas, Paint paint) { 55 | float radius=getWidth()/11; 56 | paint.setAlpha(alpha); 57 | canvas.drawCircle(translateX, getHeight() / 2, radius, paint); 58 | } 59 | 60 | @Override 61 | public ArrayList onCreateAnimators() { 62 | ArrayList animators=new ArrayList<>(); 63 | float startT=getWidth()/11; 64 | ValueAnimator translationAnim=ValueAnimator.ofFloat(getWidth()-startT,getWidth()/2); 65 | translationAnim.setDuration(650); 66 | translationAnim.setInterpolator(new LinearInterpolator()); 67 | translationAnim.setRepeatCount(-1); 68 | addUpdateListener(translationAnim,new ValueAnimator.AnimatorUpdateListener() { 69 | @Override 70 | public void onAnimationUpdate(ValueAnimator animation) { 71 | translateX = (float) animation.getAnimatedValue(); 72 | postInvalidate(); 73 | } 74 | }); 75 | 76 | ValueAnimator alphaAnim=ValueAnimator.ofInt(255,122); 77 | alphaAnim.setDuration(650); 78 | alphaAnim.setRepeatCount(-1); 79 | addUpdateListener(alphaAnim,new ValueAnimator.AnimatorUpdateListener() { 80 | @Override 81 | public void onAnimationUpdate(ValueAnimator animation) { 82 | alpha = (int) animation.getAnimatedValue(); 83 | postInvalidate(); 84 | } 85 | }); 86 | 87 | ValueAnimator rotateAnim1=ValueAnimator.ofFloat(0, 45, 0); 88 | rotateAnim1.setDuration(650); 89 | rotateAnim1.setRepeatCount(-1); 90 | addUpdateListener(rotateAnim1,new ValueAnimator.AnimatorUpdateListener() { 91 | @Override 92 | public void onAnimationUpdate(ValueAnimator animation) { 93 | degrees1 = (float) animation.getAnimatedValue(); 94 | postInvalidate(); 95 | } 96 | }); 97 | 98 | ValueAnimator rotateAnim2=ValueAnimator.ofFloat(0,-45,0); 99 | rotateAnim2.setDuration(650); 100 | rotateAnim2.setRepeatCount(-1); 101 | addUpdateListener(rotateAnim2,new ValueAnimator.AnimatorUpdateListener() { 102 | @Override 103 | public void onAnimationUpdate(ValueAnimator animation) { 104 | degrees2 = (float) animation.getAnimatedValue(); 105 | postInvalidate(); 106 | } 107 | }); 108 | 109 | animators.add(translationAnim); 110 | animators.add(alphaAnim); 111 | animators.add(rotateAnim1); 112 | animators.add(rotateAnim2); 113 | return animators; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/SemiCircleSpinIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.RectF; 7 | 8 | import com.wang.avi.Indicator; 9 | 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Jack on 2015/10/20. 14 | */ 15 | public class SemiCircleSpinIndicator extends Indicator { 16 | 17 | private float degress; 18 | 19 | @Override 20 | public void draw(Canvas canvas, Paint paint) { 21 | canvas.rotate(degress,centerX(),centerY()); 22 | RectF rectF=new RectF(0,0,getWidth(),getHeight()); 23 | canvas.drawArc(rectF,-60,120,false,paint); 24 | } 25 | 26 | @Override 27 | public ArrayList onCreateAnimators() { 28 | ArrayList animators=new ArrayList<>(); 29 | ValueAnimator rotateAnim=ValueAnimator.ofFloat(0,180,360); 30 | addUpdateListener(rotateAnim,new ValueAnimator.AnimatorUpdateListener() { 31 | @Override 32 | public void onAnimationUpdate(ValueAnimator animation) { 33 | degress= (float) animation.getAnimatedValue(); 34 | postInvalidate(); 35 | } 36 | }); 37 | rotateAnim.setDuration(600); 38 | rotateAnim.setRepeatCount(-1); 39 | animators.add(rotateAnim); 40 | return animators; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/SquareSpinIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Camera; 5 | import android.graphics.Canvas; 6 | import android.graphics.Matrix; 7 | import android.graphics.Paint; 8 | import android.graphics.RectF; 9 | import android.view.animation.LinearInterpolator; 10 | 11 | import com.wang.avi.Indicator; 12 | 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * Created by Jack on 2015/10/16. 17 | */ 18 | public class SquareSpinIndicator extends Indicator { 19 | 20 | private float rotateX; 21 | private float rotateY; 22 | 23 | private Camera mCamera; 24 | private Matrix mMatrix; 25 | 26 | public SquareSpinIndicator(){ 27 | mCamera=new Camera(); 28 | mMatrix=new Matrix(); 29 | } 30 | 31 | @Override 32 | public void draw(Canvas canvas, Paint paint) { 33 | 34 | mMatrix.reset(); 35 | mCamera.save(); 36 | mCamera.rotateX(rotateX); 37 | mCamera.rotateY(rotateY); 38 | mCamera.getMatrix(mMatrix); 39 | mCamera.restore(); 40 | 41 | mMatrix.preTranslate(-centerX(), -centerY()); 42 | mMatrix.postTranslate(centerX(), centerY()); 43 | canvas.concat(mMatrix); 44 | 45 | canvas.drawRect(new RectF(getWidth()/5,getHeight()/5,getWidth()*4/5,getHeight()*4/5),paint); 46 | } 47 | 48 | @Override 49 | public ArrayList onCreateAnimators() { 50 | ArrayList animators=new ArrayList<>(); 51 | ValueAnimator animator=ValueAnimator.ofFloat(0,180,180,0,0); 52 | addUpdateListener(animator,new ValueAnimator.AnimatorUpdateListener() { 53 | @Override 54 | public void onAnimationUpdate(ValueAnimator animation) { 55 | rotateX= (float) animation.getAnimatedValue(); 56 | postInvalidate(); 57 | } 58 | }); 59 | animator.setInterpolator(new LinearInterpolator()); 60 | animator.setRepeatCount(-1); 61 | animator.setDuration(2500); 62 | 63 | ValueAnimator animator1=ValueAnimator.ofFloat(0,0,180,180,0); 64 | addUpdateListener(animator1,new ValueAnimator.AnimatorUpdateListener() { 65 | @Override 66 | public void onAnimationUpdate(ValueAnimator animation) { 67 | rotateY= (float) animation.getAnimatedValue(); 68 | postInvalidate(); 69 | } 70 | }); 71 | animator1.setInterpolator(new LinearInterpolator()); 72 | animator1.setRepeatCount(-1); 73 | animator1.setDuration(2500); 74 | 75 | animators.add(animator); 76 | animators.add(animator1); 77 | return animators; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/java/com/wang/avi/indicators/TriangleSkewSpinIndicator.java: -------------------------------------------------------------------------------- 1 | package com.wang.avi.indicators; 2 | 3 | import android.animation.ValueAnimator; 4 | import android.graphics.Camera; 5 | import android.graphics.Canvas; 6 | import android.graphics.Matrix; 7 | import android.graphics.Paint; 8 | import android.graphics.Path; 9 | import android.view.animation.LinearInterpolator; 10 | 11 | import com.wang.avi.Indicator; 12 | 13 | import java.util.ArrayList; 14 | 15 | /** 16 | * Created by Jack on 2015/10/20. 17 | */ 18 | public class TriangleSkewSpinIndicator extends Indicator { 19 | 20 | private float rotateX; 21 | private float rotateY; 22 | 23 | private Camera mCamera; 24 | private Matrix mMatrix; 25 | 26 | public TriangleSkewSpinIndicator(){ 27 | mCamera=new Camera(); 28 | mMatrix=new Matrix(); 29 | } 30 | 31 | @Override 32 | public void draw(Canvas canvas, Paint paint) { 33 | 34 | 35 | mMatrix.reset(); 36 | mCamera.save(); 37 | mCamera.rotateX(rotateX); 38 | mCamera.rotateY(rotateY); 39 | mCamera.getMatrix(mMatrix); 40 | mCamera.restore(); 41 | 42 | mMatrix.preTranslate(-centerX(), -centerY()); 43 | mMatrix.postTranslate(centerX(), centerY()); 44 | canvas.concat(mMatrix); 45 | 46 | Path path=new Path(); 47 | path.moveTo(getWidth()/5,getHeight()*4/5); 48 | path.lineTo(getWidth()*4/5, getHeight()*4/5); 49 | path.lineTo(getWidth()/2,getHeight()/5); 50 | path.close(); 51 | canvas.drawPath(path, paint); 52 | } 53 | 54 | @Override 55 | public ArrayList onCreateAnimators() { 56 | ArrayList animators=new ArrayList<>(); 57 | ValueAnimator animator=ValueAnimator.ofFloat(0,180,180,0,0); 58 | addUpdateListener(animator,new ValueAnimator.AnimatorUpdateListener() { 59 | @Override 60 | public void onAnimationUpdate(ValueAnimator animation) { 61 | rotateX= (float) animation.getAnimatedValue(); 62 | postInvalidate(); 63 | } 64 | }); 65 | animator.setInterpolator(new LinearInterpolator()); 66 | animator.setRepeatCount(-1); 67 | animator.setDuration(2500); 68 | 69 | ValueAnimator animator1=ValueAnimator.ofFloat(0,0,180,180,0); 70 | addUpdateListener(animator1,new ValueAnimator.AnimatorUpdateListener() { 71 | @Override 72 | public void onAnimationUpdate(ValueAnimator animation) { 73 | rotateY= (float) animation.getAnimatedValue(); 74 | postInvalidate(); 75 | } 76 | }); 77 | animator1.setInterpolator(new LinearInterpolator()); 78 | animator1.setRepeatCount(-1); 79 | animator1.setDuration(2500); 80 | 81 | animators.add(animator); 82 | animators.add(animator1); 83 | return animators; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Library 3 | 4 | -------------------------------------------------------------------------------- /WechatLuckyMoney/loadingIndicator/src/main/res/values/style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 18 | 19 | 26 | 27 | -------------------------------------------------------------------------------- /WechatLuckyMoney/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':loadingIndicator' 2 | -------------------------------------------------------------------------------- /resources/apk/release/v1.0_release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/resources/apk/release/v1.0_release.apk -------------------------------------------------------------------------------- /resources/apk/release/v2.0_release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/resources/apk/release/v2.0_release.apk -------------------------------------------------------------------------------- /resources/image/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxxls/WechatLuckyMoney/25f1e3245e9a35619cdf98e7097c4272b51dce8e/resources/image/demo.gif --------------------------------------------------------------------------------