├── .gitignore ├── README.md ├── build.gradle ├── example ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── assets │ │ └── zepto.js │ ├── dist │ │ ├── css │ │ │ ├── sm-extend.css │ │ │ ├── sm-extend.min.css │ │ │ ├── sm.css │ │ │ └── sm.min.css │ │ └── js │ │ │ ├── sm-city-picker.js │ │ │ ├── sm-city-picker.min.js │ │ │ ├── sm-extend.js │ │ │ ├── sm-extend.min.js │ │ │ ├── sm.js │ │ │ └── sm.min.js │ ├── index.html │ ├── index2.html │ ├── js │ │ └── index.js │ └── second.html │ ├── java │ └── com │ │ └── wuchao │ │ └── fastec │ │ └── example │ │ ├── ExampleActivity.java │ │ ├── ExampleApp.java │ │ ├── ExampleDelegate.java │ │ ├── event │ │ ├── TestEvent.java │ │ └── shareEvent.java │ │ ├── generators │ │ ├── AppRegister.java │ │ ├── WeChatEntry.java │ │ └── WeChatPayEntry.java │ │ └── push │ │ └── PushReceiver.java │ └── res │ ├── layout │ ├── activity_main.xml │ └── delegate_example.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_round.png │ └── xdy_launcher.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── raw │ └── test │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images └── preview.gif ├── latte-annotations ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── wuchao │ └── latte │ └── annotations │ ├── AppRegisterGenerator.java │ ├── EntryGenerator.java │ └── PayEntryGenerator.java ├── latte-compiler ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── wuchao │ └── latte │ └── compiler │ ├── AppRegisterVisitor.java │ ├── EntryVisitor.java │ ├── LatteProcessor.java │ └── PayEntryVisitor.java ├── latte-core ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wuchao │ │ └── latte │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── wuchao │ │ │ └── latte │ │ │ ├── activitys │ │ │ └── ProxyActivity.java │ │ │ ├── app │ │ │ ├── AccountManager.java │ │ │ ├── ConfigKeys.java │ │ │ ├── Configurator.java │ │ │ ├── IUserChecker.java │ │ │ └── Latte.java │ │ │ ├── delegates │ │ │ ├── BaseDelegate.java │ │ │ ├── IPageLoadListener.java │ │ │ ├── LatteDelegate.java │ │ │ ├── PermissionCheckerDelegate.java │ │ │ ├── bottom │ │ │ │ ├── BaseBottomDelegate.java │ │ │ │ ├── BottomItemDelegate.java │ │ │ │ ├── BottomTabBean.java │ │ │ │ └── ItemBuilder.java │ │ │ └── web │ │ │ │ ├── IWebViewInitializer.java │ │ │ │ ├── LatteWebInterface.java │ │ │ │ ├── WebDelegate.java │ │ │ │ ├── WebDelegateImpl.java │ │ │ │ ├── WebViewInitializer.java │ │ │ │ ├── chromeclient │ │ │ │ └── WebChromeClientImpl.java │ │ │ │ ├── client │ │ │ │ └── WebViewClientImpl.java │ │ │ │ ├── event │ │ │ │ ├── Event.java │ │ │ │ ├── EventManager.java │ │ │ │ ├── IEvent.java │ │ │ │ └── UndefineEvent.java │ │ │ │ └── route │ │ │ │ ├── RouteKeys.java │ │ │ │ └── Router.java │ │ │ ├── net │ │ │ ├── HttpMethod.java │ │ │ ├── base │ │ │ │ └── BaseObserver.java │ │ │ ├── bean │ │ │ │ └── BaseData.java │ │ │ ├── callback │ │ │ │ ├── IError.java │ │ │ │ ├── IFailure.java │ │ │ │ ├── IRequest.java │ │ │ │ ├── ISuccess.java │ │ │ │ └── RequestCallbacks.java │ │ │ ├── download │ │ │ │ ├── DownloadHandler.java │ │ │ │ └── SaveFileTask.java │ │ │ ├── interceptors │ │ │ │ ├── AddCookieInterceptor.java │ │ │ │ ├── BaseInterceptor.java │ │ │ │ ├── DebugInterceptor.java │ │ │ │ └── InterceptorUtil.java │ │ │ ├── interfaces │ │ │ │ └── ISubscriber.java │ │ │ └── rx │ │ │ │ ├── ApiException.java │ │ │ │ ├── RxRestClient.java │ │ │ │ ├── RxRestClientBuilder.java │ │ │ │ ├── RxRestCreator.java │ │ │ │ ├── RxRestService.java │ │ │ │ └── Transformer.java │ │ │ ├── ui │ │ │ ├── animation │ │ │ │ ├── BezierAnimation.java │ │ │ │ └── BezierUtil.java │ │ │ ├── banner │ │ │ │ ├── BannerCreator.java │ │ │ │ ├── HolderCreator.java │ │ │ │ └── ImageHolder.java │ │ │ ├── camera │ │ │ │ ├── CameraHandler.java │ │ │ │ ├── CameraImageBean.java │ │ │ │ ├── LatteCamera.java │ │ │ │ └── RequestCodes.java │ │ │ ├── date │ │ │ │ └── DateDialogUtil.java │ │ │ ├── launcher │ │ │ │ ├── LauncherHolder.java │ │ │ │ ├── LauncherHolderCreator.java │ │ │ │ └── ScrollLauncherTag.java │ │ │ ├── loader │ │ │ │ ├── LatteLoader.java │ │ │ │ ├── LoaderCreator.java │ │ │ │ └── LoaderStyle.java │ │ │ ├── recycler │ │ │ │ ├── BaseDecoration.java │ │ │ │ ├── DataConverter.java │ │ │ │ ├── DividerLookupImpl.java │ │ │ │ ├── ItemType.java │ │ │ │ ├── MultipleFields.java │ │ │ │ ├── MultipleItemEntity.java │ │ │ │ ├── MultipleItemEntityBuilder.java │ │ │ │ ├── MultipleRecyclerAdapter.java │ │ │ │ ├── MultipleViewHolder.java │ │ │ │ └── RgbValue.java │ │ │ ├── refresh │ │ │ │ ├── PagingBean.java │ │ │ │ └── RefreshHandler.java │ │ │ ├── scanner │ │ │ │ ├── LatteViewFinderView.java │ │ │ │ ├── ScanView.java │ │ │ │ └── ScannerDelegate.java │ │ │ └── widget │ │ │ │ ├── AutoPhotoLayout.java │ │ │ │ ├── CircleTextView.java │ │ │ │ └── StarLayout.java │ │ │ ├── util │ │ │ ├── callback │ │ │ │ ├── CallbackManager.java │ │ │ │ ├── CallbackType.java │ │ │ │ └── IGlobalCallback.java │ │ │ ├── dimen │ │ │ │ └── DimenUtil.java │ │ │ ├── file │ │ │ │ └── FileUtil.java │ │ │ ├── log │ │ │ │ └── LatteLogger.java │ │ │ ├── storage │ │ │ │ └── LattePreference.java │ │ │ └── timer │ │ │ │ ├── BaseTimerTask.java │ │ │ │ └── ITimerListener.java │ │ │ └── wechat │ │ │ ├── BaseWXActivity.java │ │ │ ├── BaseWXEntryActivity.java │ │ │ ├── BaseWXPayEntryActivity.java │ │ │ ├── LatteWeChat.java │ │ │ ├── callbacks │ │ │ └── IWeChatSignInCallback.java │ │ │ └── templates │ │ │ ├── AppRegisterTemplate.java │ │ │ ├── WXEntryTemplate.java │ │ │ └── WXPayEntryTemplate.java │ └── res │ │ ├── anim │ │ ├── push_bottom_in.xml │ │ └── push_bottom_out.xml │ │ ├── drawable │ │ ├── border_text.xml │ │ ├── btn_border.xml │ │ ├── btn_border_nativephoto.xml │ │ ├── btn_border_takephoto.xml │ │ ├── dot_focus.xml │ │ └── dot_normal.xml │ │ ├── layout │ │ ├── bottom_item_icon_text_layout.xml │ │ ├── delegate_bottom.xml │ │ ├── dialog_camera_panel.xml │ │ ├── dialog_image_click_panel.xml │ │ ├── item_multiple_banner.xml │ │ ├── item_multiple_image.xml │ │ ├── item_multiple_image_text.xml │ │ └── item_multiple_text.xml │ │ └── values │ │ ├── attrs.xml │ │ ├── dimen.xml │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── style.xml │ └── test │ └── java │ └── com │ └── wuchao │ └── latte │ └── ExampleUnitTest.java ├── latte-ec ├── .gitignore ├── build.gradle ├── libs │ └── alipaySdk-20170922.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── iconfont.ttf │ ├── java │ └── com │ │ └── wuchao │ │ └── latte │ │ └── ec │ │ ├── database │ │ ├── DatabaseManager.java │ │ ├── ReleaseOpenHelper.java │ │ └── UserProfile.java │ │ ├── detail │ │ ├── GoodsDetailDelegate.java │ │ ├── GoodsInfoDelegate.java │ │ ├── ImageDelegate.java │ │ ├── RecyclerImageAdapter.java │ │ ├── ScaleUpAnimator.java │ │ └── TabPagerAdapter.java │ │ ├── icon │ │ ├── EcIcons.java │ │ └── FontEcModule.java │ │ ├── launcher │ │ ├── ILauncherListener.java │ │ ├── LauncherDelegate.java │ │ ├── LauncherScrollDelegate.java │ │ └── OnLauncherFinishTag.java │ │ ├── main │ │ ├── EcBottomDelegate.java │ │ ├── cart │ │ │ ├── ICartItemListener.java │ │ │ ├── ShopCartAdapter.java │ │ │ ├── ShopCartDelegate.java │ │ │ ├── ShopCartItemFields.java │ │ │ ├── ShopCartItemType.java │ │ │ └── shopCartDataConvert.java │ │ ├── discover │ │ │ └── DiscoverDelegate.java │ │ ├── index │ │ │ ├── IndexDataConvert.java │ │ │ ├── IndexDelegate.java │ │ │ ├── IndexItemClickListener.java │ │ │ ├── TranslucentBehavior.java │ │ │ └── search │ │ │ │ ├── SearchAdapter.java │ │ │ │ ├── SearchDataConverter.java │ │ │ │ ├── SearchDelegate.java │ │ │ │ └── SearchItemType.java │ │ ├── personal │ │ │ ├── PersonalClickListener.java │ │ │ ├── PersonalDelegate.java │ │ │ ├── address │ │ │ │ ├── AddressAdapter.java │ │ │ │ ├── AddressDataConverter.java │ │ │ │ ├── AddressDelegate.java │ │ │ │ ├── AddressItemFields.java │ │ │ │ └── AddressItemType.java │ │ │ ├── list │ │ │ │ ├── ListAdapter.java │ │ │ │ ├── ListBean.java │ │ │ │ └── ListItemType.java │ │ │ ├── order │ │ │ │ ├── OrderCommentDelegate.java │ │ │ │ ├── OrderItemFields.java │ │ │ │ ├── OrderListAdapter.java │ │ │ │ ├── OrderListClickListener.java │ │ │ │ ├── OrderListDataConverter.java │ │ │ │ ├── OrderListDelegate.java │ │ │ │ └── OrderListItemType.java │ │ │ ├── profile │ │ │ │ ├── UploadConfig.java │ │ │ │ ├── UserProfileClickListener.java │ │ │ │ └── UserProfileDelegate.java │ │ │ └── settings │ │ │ │ ├── AboutDelegate.java │ │ │ │ ├── NameDelegate.java │ │ │ │ ├── SettingsClickListener.java │ │ │ │ └── SettingsDelegate.java │ │ └── sort │ │ │ ├── SortDelegate.java │ │ │ ├── content │ │ │ ├── ContentDelegate.java │ │ │ ├── SectionAdapter.java │ │ │ ├── SectionBean.java │ │ │ ├── SectionContentItemEntity.java │ │ │ └── SectionDataConvert.java │ │ │ └── list │ │ │ ├── SortRecyclerAdapter.java │ │ │ ├── VerticalListDataConvert.java │ │ │ └── VerticalListDelegate.java │ │ ├── pay │ │ ├── FastPay.java │ │ ├── IAlPayResultListener.java │ │ ├── PayAsyncTask.java │ │ └── PayResult.java │ │ └── sign │ │ ├── ISignListener.java │ │ ├── SignHandler.java │ │ ├── SignInDelegate.java │ │ └── SignUpDelegate.java │ └── res │ ├── anim │ ├── push_bottom_in.xml │ └── push_bottom_out.xml │ ├── drawable │ ├── border_circle_timer.xml │ ├── dot_focus.xml │ └── dot_normal.xml │ ├── layout │ ├── arrow_item_avatar.xml │ ├── arrow_item_layout.xml │ ├── arrow_switch_layout.xml │ ├── delegate_about.xml │ ├── delegate_address.xml │ ├── delegate_discover.xml │ ├── delegate_goods_detail.xml │ ├── delegate_goods_info.xml │ ├── delegate_image.xml │ ├── delegate_index.xml │ ├── delegate_launcher.xml │ ├── delegate_list_content.xml │ ├── delegate_name.xml │ ├── delegate_order_comment.xml │ ├── delegate_order_list.xml │ ├── delegate_personal.xml │ ├── delegate_search.xml │ ├── delegate_settings.xml │ ├── delegate_shop_cart.xml │ ├── delegate_sign_in.xml │ ├── delegate_sign_up.xml │ ├── delegate_sort.xml │ ├── delegate_user_profile.xml │ ├── delegate_vertical_list.xml │ ├── dialog_pay_panel.xml │ ├── item_address.xml │ ├── item_image.xml │ ├── item_order_list.xml │ ├── item_search.xml │ ├── item_section_content.xml │ ├── item_section_header.xml │ ├── item_shop_cart.xml │ ├── item_vertical_menu_list.xml │ ├── layout_goods_detail_bottom.xml │ └── stub_shop_cart_no_item.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── avatar.jpg │ ├── ic_launcher.png │ ├── ic_launcher_round.png │ ├── launcher_00.jpeg │ ├── launcher_01.jpeg │ ├── launcher_02.jpeg │ ├── launcher_03.jpeg │ ├── launcher_04.jpeg │ └── launcher_05.jpeg │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── style.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | .idea 4 | .DS_Store 5 | build 6 | local.properties 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FastEC 2 | ### Android通用框架设计与完整电商APP 3 | 4 | 1. latte-annotations:注解model-提供代码生成器所需注解 5 | 类型为Java Library 6 | 2. latte-compiler:代码生成器model-从注解获取信息,通过annotationProcessor或apt生成代码 7 | 类型为Java Library 8 | 3. latte-core:核心model-路由架构、HTTP请求、照相和二维码及图片剪裁、具有共性的通用UI、通用工具、WebView处理 9 | 微信登录和支付封装、支付宝支付封装、诸多重复性的处理 10 | 类型为Android Library 11 | 依赖latte-annotations 12 | 4. latte-ec:业务model-相应一类业务的特殊UI、相应一类业务需要的通用逻辑、相应一类业务的特殊处理 13 | 类型为Android Library 14 | 依赖latte-core 15 | 5. latte-example:项目model-项目特有的个别功能、只有该项目需要的第三方库、只有该项目会更改的UI及逻辑 16 | 需要在application model中使用的一些签名和验证 17 | 类型为Android Application 18 | 依赖latte-ec 19 | 依赖latte-compiler 20 | 21 | 22 | ![image](https://github.com/wuchao226/FastEC/blob/master/images/preview.gif) 23 | 24 | #### 混合应用模块 25 | - 封装自己的WebView框架 26 | - 构建路由机制 27 | - 构建Web与原生的事件机制 28 | - WebView填坑 29 | - 创建类原生的Web体验 30 | - 整合框架,一键式混合App部署 31 | #### 第三方登录与分享模块 32 | - 微信登录流程、潜规则梳理和分析 33 | - 编译期生成代码绕过微信包名限制 34 | - 一键式登录工具设计与封装 35 | - 多平台分享工具设计与封装 36 | #### 商品模块 37 | - 可复用瀑布流布局商品列表 38 | - 分页逻辑梳理 39 | - 高仿京东App分类 40 | - 购物车飞入效果实现 41 | - 酷炫MD风格商品详情 42 | - CoordinatorLayout填坑 43 | #### 购物车模块 44 | - 购物车数据计算和逻辑梳理 45 | - RecyclerView填坑 46 | - 订单生成和逻辑梳理 47 | - 通用购物车UI实现和封装 48 | #### 支付模块 49 | - 支付宝支付流程梳理与对接 50 | - 微信支付流程梳理与对接 51 | - 设计和实现代码生成器生成支付类 52 | - 一键式支付工具封装与注意事项 53 | #### 用户模块 54 | - 登录、注册、验证 55 | - 个人信息管理 56 | - 订单管理 57 | - 地址管理 58 | -------------------------------------------------------------------------------- /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 | mavenCentral() 7 | google() 8 | // 添加MobSDK的maven地址 9 | maven { 10 | url "http://mvn.mob.com/android" 11 | } 12 | } 13 | dependencies { 14 | classpath 'com.android.tools.build:gradle:3.1.2' 15 | classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0' 16 | classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' 17 | // 注册MobSDK 18 | classpath "com.mob.sdk:MobSDK:+" 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | jcenter() 25 | google() 26 | mavenCentral() 27 | maven { url "https://jitpack.io" } 28 | } 29 | } 30 | 31 | task clean(type: Delete) { 32 | delete rootProject.buildDir 33 | } 34 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /example/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: "com.mob.sdk" 3 | 4 | android { 5 | compileSdkVersion 27 6 | defaultConfig { 7 | applicationId "com.wuchao.fastec.example" 8 | minSdkVersion 15 9 | targetSdkVersion 27 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | multiDexEnabled true 14 | 15 | ndk { 16 | //选择要添加的对应cpu类型的.so库。 17 | abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64' 18 | } 19 | 20 | manifestPlaceholders = [ 21 | JPUSH_PKGNAME: applicationId, 22 | JPUSH_APPKEY : "f25d6e92e37c6407a9de0567", //JPush上注册的包名对应的appkey. 23 | JPUSH_CHANNEL: "developer-default", //暂时填写默认值即可. 24 | ] 25 | } 26 | buildTypes { 27 | release { 28 | minifyEnabled false 29 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 30 | } 31 | } 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | } 37 | 38 | dependencies { 39 | compile fileTree(include: ['*.jar'], dir: 'libs') 40 | compile project(':latte-ec') 41 | compileOnly project(':latte-annotations') 42 | implementation 'com.facebook.stetho:stetho:1.5.0' 43 | implementation 'com.facebook.stetho:stetho-okhttp3:1.5.0' 44 | implementation project(':latte-compiler') 45 | annotationProcessor project(':latte-compiler') 46 | implementation 'cn.jiguang.sdk:jpush:3.0.9' 47 | implementation 'cn.jiguang.sdk:jcore:1.1.7' 48 | } 49 | -------------------------------------------------------------------------------- /example/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 /Users/wuchao/working/android/android-sdk-macosx/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 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /example/src/main/assets/index2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 本地测试 9 | 10 | 11 |

这是本地页面1

12 | 13 | 24 | 25 | -------------------------------------------------------------------------------- /example/src/main/assets/js/index.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | $('.share').click(function () { 3 | var json = { 4 | action: "share", 5 | params: { 6 | imageUrl:"http://i9.qhimg.com/t017d891ca365ef60b5.jpg", 7 | url:"https://www.baidu.com", 8 | title:"标题", 9 | text:"描述" 10 | } 11 | }; 12 | 13 | latte.event(JSON.stringify(json)); 14 | 15 | }); 16 | 17 | $('.comment').click(function () { 18 | 19 | var json = { 20 | action: "comment" 21 | }; 22 | 23 | latte.event(JSON.stringify(json)); 24 | 25 | }); 26 | }); -------------------------------------------------------------------------------- /example/src/main/assets/second.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 本地测试2 9 | 10 | 11 | 12 |

这是本地页面2

13 | 14 | 15 | -------------------------------------------------------------------------------- /example/src/main/java/com/wuchao/fastec/example/ExampleDelegate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.fastec.example; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.view.View; 6 | import android.widget.Toast; 7 | 8 | import com.wuchao.latte.app.Latte; 9 | import com.wuchao.latte.delegates.LatteDelegate; 10 | import com.wuchao.latte.net.rx.RxRestClient; 11 | 12 | import io.reactivex.Observer; 13 | import io.reactivex.android.schedulers.AndroidSchedulers; 14 | import io.reactivex.disposables.Disposable; 15 | import io.reactivex.schedulers.Schedulers; 16 | 17 | /** 18 | * @author: wuchao 19 | * @date: 2017/10/22 23:15 20 | * @desciption: 21 | */ 22 | 23 | public class ExampleDelegate extends LatteDelegate { 24 | @Override 25 | public Object setLayout() { 26 | return R.layout.delegate_example; 27 | } 28 | 29 | @Override 30 | public void onBindView(@Nullable Bundle savedInstanceState, View rootView) { 31 | testRestClient(); 32 | } 33 | 34 | private void testRestClient() { 35 | RxRestClient.builder() 36 | .url("http://192.168.1.102/index") 37 | .build() 38 | .get() 39 | .subscribeOn(Schedulers.io()) 40 | .observeOn(AndroidSchedulers.mainThread()) 41 | .subscribe(new Observer() { 42 | @Override 43 | public void onSubscribe(Disposable d) { 44 | 45 | } 46 | 47 | @Override 48 | public void onNext(String s) { 49 | Toast.makeText(Latte.getApplicationContext(),s,Toast.LENGTH_LONG).show(); 50 | } 51 | 52 | @Override 53 | public void onError(Throwable e) { 54 | 55 | } 56 | 57 | @Override 58 | public void onComplete() { 59 | 60 | } 61 | }); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /example/src/main/java/com/wuchao/fastec/example/event/TestEvent.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.fastec.example.event; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.webkit.WebView; 5 | import android.widget.Toast; 6 | 7 | import com.wuchao.latte.delegates.web.event.Event; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2017/12/23 18:13 12 | * @desciption: 13 | */ 14 | 15 | public class TestEvent extends Event { 16 | @Override 17 | public String execute(String params) { 18 | Toast.makeText(getContext(), getAction(), Toast.LENGTH_LONG).show(); 19 | if (getAction().equals("test")) { 20 | final WebView webView = getWebView(); 21 | webView.post(new Runnable() { 22 | @SuppressLint("NewApi") 23 | @Override 24 | public void run() { 25 | webView.evaluateJavascript("nativeCall()", null); 26 | } 27 | }); 28 | } 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/src/main/java/com/wuchao/fastec/example/event/shareEvent.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.fastec.example.event; 2 | 3 | import com.blankj.utilcode.util.ToastUtils; 4 | import com.wuchao.latte.delegates.web.event.Event; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2018/1/18 16:48 9 | * @desciption: 10 | */ 11 | 12 | public class shareEvent extends Event { 13 | @Override 14 | public String execute(String params) { 15 | ToastUtils.showLong("分享"); 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /example/src/main/java/com/wuchao/fastec/example/generators/AppRegister.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.fastec.example.generators; 2 | 3 | import com.wuchao.latte.annotations.AppRegisterGenerator; 4 | import com.wuchao.latte.wechat.templates.AppRegisterTemplate; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2017/12/27 23:05 9 | * @desciption: 10 | */ 11 | @AppRegisterGenerator(packageName = "com.wuchao.fastec.example", 12 | registerTemplate = AppRegisterTemplate.class) 13 | public interface AppRegister { 14 | } 15 | -------------------------------------------------------------------------------- /example/src/main/java/com/wuchao/fastec/example/generators/WeChatEntry.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.fastec.example.generators; 2 | 3 | import com.wuchao.latte.annotations.EntryGenerator; 4 | import com.wuchao.latte.wechat.templates.WXEntryTemplate; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2017/12/27 23:05 9 | * @desciption: 10 | */ 11 | @EntryGenerator(packageName = "com.wuchao.fastec.example", 12 | entryTemplate = WXEntryTemplate.class) 13 | public interface WeChatEntry { 14 | } 15 | -------------------------------------------------------------------------------- /example/src/main/java/com/wuchao/fastec/example/generators/WeChatPayEntry.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.fastec.example.generators; 2 | 3 | import com.wuchao.latte.annotations.PayEntryGenerator; 4 | import com.wuchao.latte.wechat.templates.WXPayEntryTemplate; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2017/12/27 23:05 9 | * @desciption: 10 | */ 11 | @PayEntryGenerator(packageName = "com.wuchao.fastec.example", 12 | payEntryTemplate = WXPayEntryTemplate.class) 13 | public interface WeChatPayEntry { 14 | } 15 | -------------------------------------------------------------------------------- /example/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/src/main/res/layout/delegate_example.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /example/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xxhdpi/xdy_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xxhdpi/xdy_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/example/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/src/main/res/raw/test: -------------------------------------------------------------------------------- 1 | { 2 | "key":"value" 3 | } -------------------------------------------------------------------------------- /example/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /example/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 电商 3 | 4 | -------------------------------------------------------------------------------- /example/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /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 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu May 31 11:40:30 CST 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.4-all.zip 7 | -------------------------------------------------------------------------------- /images/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wuchao226/FastEC/ce24a6a544b0f55845dd3c5f6671e60c594d3545/images/preview.gif -------------------------------------------------------------------------------- /latte-annotations/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | dependencies { 4 | compile fileTree(dir: 'libs', include: ['*.jar']) 5 | } 6 | 7 | sourceCompatibility = "1.7" 8 | targetCompatibility = "1.7" 9 | -------------------------------------------------------------------------------- /latte-annotations/src/main/java/com/wuchao/latte/annotations/AppRegisterGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2017/12/26 22:58 11 | * @desciption: 12 | */ 13 | 14 | @Target(ElementType.TYPE)//告诉编译器注解是用在类上面的,不是方法和属性 15 | @Retention(RetentionPolicy.SOURCE)//编译器处理注解时是在源码阶段处理的, 16 | // 即打包成apk或者运行时不再使用了,对性能没有影响 17 | public @interface AppRegisterGenerator { 18 | 19 | String packageName(); 20 | 21 | Class registerTemplate(); 22 | } 23 | -------------------------------------------------------------------------------- /latte-annotations/src/main/java/com/wuchao/latte/annotations/EntryGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2017/12/26 22:51 11 | * @desciption: 用来传入包名,微信需要的模板代码也就是绕过微信的限制,不需要在主程序里写 12 | */ 13 | 14 | @Target(ElementType.TYPE)//告诉编译器注解是用在类上面的,不是方法和属性 15 | @Retention(RetentionPolicy.SOURCE)//编译器处理注解时是在源码阶段处理的, 16 | // 即打包成apk或者运行时不再使用了,对性能没有影响 17 | public @interface EntryGenerator { 18 | 19 | String packageName(); 20 | 21 | Class entryTemplate(); 22 | } 23 | -------------------------------------------------------------------------------- /latte-annotations/src/main/java/com/wuchao/latte/annotations/PayEntryGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.annotations; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2017/12/26 22:56 11 | * @desciption: 12 | */ 13 | 14 | @Target(ElementType.TYPE)//告诉编译器注解是用在类上面的,不是方法和属性 15 | @Retention(RetentionPolicy.SOURCE)//编译器处理注解时是在源码阶段处理的, 16 | // 即打包成apk或者运行时不再使用了,对性能没有影响 17 | public @interface PayEntryGenerator { 18 | 19 | String packageName(); 20 | 21 | Class payEntryTemplate(); 22 | } 23 | -------------------------------------------------------------------------------- /latte-compiler/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | dependencies { 4 | compile fileTree(include: ['*.jar'], dir: 'libs') 5 | implementation project(':latte-annotations') 6 | compile 'com.squareup:javapoet:1.9.0' 7 | compile 'com.google.auto.service:auto-service:1.0-rc4' 8 | compile 'com.google.auto:auto-common:0.9' 9 | } 10 | 11 | sourceCompatibility = "1.7" 12 | targetCompatibility = "1.7" 13 | -------------------------------------------------------------------------------- /latte-compiler/src/main/java/com/wuchao/latte/compiler/AppRegisterVisitor.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.compiler; 2 | 3 | import com.squareup.javapoet.JavaFile; 4 | import com.squareup.javapoet.TypeName; 5 | import com.squareup.javapoet.TypeSpec; 6 | 7 | import java.io.IOException; 8 | 9 | import javax.annotation.processing.Filer; 10 | import javax.lang.model.element.Modifier; 11 | import javax.lang.model.type.TypeMirror; 12 | import javax.lang.model.util.SimpleAnnotationValueVisitor7; 13 | 14 | import static javax.lang.model.element.Modifier.PUBLIC; 15 | 16 | /** 17 | * @author: wuchao 18 | * @date: 2017/12/27 22:55 19 | * @desciption: 20 | */ 21 | 22 | public class AppRegisterVisitor extends SimpleAnnotationValueVisitor7 { 23 | 24 | private final Filer FILER; 25 | private String mPackageName = null; 26 | 27 | AppRegisterVisitor(Filer FILER) { 28 | this.FILER = FILER; 29 | } 30 | 31 | @Override 32 | public Void visitString(String s, Void p) { 33 | mPackageName = s; 34 | return p; 35 | } 36 | 37 | @Override 38 | public Void visitType(TypeMirror t, Void p) { 39 | generateJavaCode(t); 40 | return p; 41 | } 42 | 43 | private void generateJavaCode(TypeMirror typeMirror) { 44 | final TypeSpec targetActivity = 45 | TypeSpec.classBuilder("AppRegister") 46 | .addModifiers(PUBLIC) 47 | .addModifiers(Modifier.FINAL) 48 | .superclass(TypeName.get(typeMirror)) 49 | .build(); 50 | 51 | final JavaFile javaFile = JavaFile.builder(mPackageName + ".wxapi", targetActivity) 52 | .addFileComment("微信广播接收器") 53 | .build(); 54 | try { 55 | javaFile.writeTo(FILER); 56 | } catch (IOException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /latte-compiler/src/main/java/com/wuchao/latte/compiler/EntryVisitor.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.compiler; 2 | 3 | 4 | import com.squareup.javapoet.JavaFile; 5 | import com.squareup.javapoet.TypeName; 6 | import com.squareup.javapoet.TypeSpec; 7 | 8 | import java.io.IOException; 9 | 10 | import javax.annotation.processing.Filer; 11 | import javax.lang.model.element.Modifier; 12 | import javax.lang.model.type.TypeMirror; 13 | import javax.lang.model.util.SimpleAnnotationValueVisitor7; 14 | 15 | /** 16 | * @author: wuchao 17 | * @date: 2017/12/27 22:39 18 | * @desciption: 19 | */ 20 | 21 | public class EntryVisitor extends SimpleAnnotationValueVisitor7 { 22 | 23 | private final Filer mFiler; 24 | private String mPackageName = null; 25 | 26 | EntryVisitor(Filer filer) { 27 | mFiler = filer; 28 | } 29 | 30 | @Override 31 | public Void visitString(String s, Void p) { 32 | mPackageName = s; 33 | return p; 34 | } 35 | 36 | @Override 37 | public Void visitType(TypeMirror t, Void p) { 38 | generateJavaCode(t); 39 | return p; 40 | } 41 | 42 | private void generateJavaCode(TypeMirror typeMirror) { 43 | final TypeSpec targetActivity = 44 | TypeSpec.classBuilder("WXEntryActivity") 45 | .addModifiers(Modifier.PUBLIC) 46 | .addModifiers(Modifier.FINAL) 47 | .superclass(TypeName.get(typeMirror)) 48 | .build(); 49 | final JavaFile javaFile = JavaFile.builder(mPackageName + ".wxapi", targetActivity) 50 | .addFileComment("微信入口文件") 51 | .build(); 52 | try { 53 | javaFile.writeTo(mFiler); 54 | } catch (IOException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /latte-compiler/src/main/java/com/wuchao/latte/compiler/PayEntryVisitor.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.compiler; 2 | 3 | import com.squareup.javapoet.JavaFile; 4 | import com.squareup.javapoet.TypeName; 5 | import com.squareup.javapoet.TypeSpec; 6 | 7 | import java.io.IOException; 8 | 9 | import javax.annotation.processing.Filer; 10 | import javax.lang.model.element.Modifier; 11 | import javax.lang.model.type.TypeMirror; 12 | import javax.lang.model.util.SimpleAnnotationValueVisitor7; 13 | 14 | /** 15 | * @author: wuchao 16 | * @date: 2017/12/27 22:54 17 | * @desciption: 18 | */ 19 | 20 | public class PayEntryVisitor extends SimpleAnnotationValueVisitor7 { 21 | 22 | private final Filer FILER; 23 | private String mPackageName = null; 24 | 25 | PayEntryVisitor(Filer FILER) { 26 | this.FILER = FILER; 27 | } 28 | 29 | @Override 30 | public Void visitString(String s, Void p) { 31 | mPackageName = s; 32 | return p; 33 | } 34 | 35 | @Override 36 | public Void visitType(TypeMirror t, Void p) { 37 | generateJavaCode(t); 38 | return p; 39 | } 40 | 41 | private void generateJavaCode(TypeMirror typeMirror) { 42 | final TypeSpec targetActivity = 43 | TypeSpec.classBuilder("WXPayEntryActivity") 44 | .addModifiers(Modifier.PUBLIC) 45 | .addModifiers(Modifier.FINAL) 46 | .superclass(TypeName.get(typeMirror)) 47 | .build(); 48 | 49 | final JavaFile javaFile = JavaFile.builder(mPackageName + ".wxapi", targetActivity) 50 | .addFileComment("微信支付入口文件") 51 | .build(); 52 | try { 53 | javaFile.writeTo(FILER); 54 | } catch (IOException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /latte-core/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /latte-core/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 /Users/wuchao/working/android/android-sdk-macosx/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 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /latte-core/src/androidTest/java/com/wuchao/latte/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.wuchao.latte.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /latte-core/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/app/AccountManager.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.app; 2 | 3 | import com.wuchao.latte.util.storage.LattePreference; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/11/27 19:00 8 | * @desciption: 管理用户信息 9 | */ 10 | 11 | public class AccountManager { 12 | 13 | private enum SignTag { 14 | SIGN_TAG 15 | } 16 | 17 | /** 18 | * 保存用户状态 19 | * 20 | * @param state 21 | */ 22 | public static void setSignState(boolean state) { 23 | LattePreference.setAppFlag(SignTag.SIGN_TAG.name(), state); 24 | } 25 | 26 | public static boolean isSignIn() { 27 | return LattePreference.getAppFlag(SignTag.SIGN_TAG.name()); 28 | } 29 | 30 | public static void checkAccount(IUserChecker checker) { 31 | if (isSignIn()) { 32 | checker.onSignIn(); 33 | } else { 34 | checker.onNotSignIn(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/app/ConfigKeys.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.app; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/16 22:40 6 | * @desciption: 唯一的单例,只初始化一次,进行多线程操作时,通过枚举安全的惰性单例初始化,即线程安全的懒汉模式 7 | */ 8 | 9 | public enum ConfigKeys { 10 | API_HOST, //配置网络请求域名 11 | APPLICATION_CONTEXT, //全局上下文 12 | APPLICATION, //全局上下文 13 | CONFIG_READY, //控制我的初始化或配置是否完成 14 | ICON, //存储自己初始化的项目 15 | INTERCEPTOR, 16 | WE_CHAT_APP_ID, 17 | WE_CHAT_APP_SECRET, 18 | JAVASCRIPT_INTERFACE, 19 | ACTIVITY, 20 | HANDLER, 21 | WEB_HOST, 22 | } 23 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/app/IUserChecker.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.app; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/11/27 18:58 6 | * @desciption: 用户信息 7 | */ 8 | 9 | public interface IUserChecker { 10 | 11 | void onSignIn(); 12 | 13 | void onNotSignIn(); 14 | } 15 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/app/Latte.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.app; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import android.os.Handler; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2017/10/16 22:36 10 | * @desciption: 11 | */ 12 | 13 | public final class Latte { 14 | 15 | /** 16 | * 返回配置 17 | * 18 | * @param context 19 | */ 20 | public static Configurator init(Context context) { 21 | getConfigurator().getLatteConfigs() 22 | .put(ConfigKeys.APPLICATION_CONTEXT, context.getApplicationContext()); 23 | getConfigurator().getLatteConfigs().put(ConfigKeys.APPLICATION, context); 24 | return Configurator.getInstance(); 25 | } 26 | 27 | public static Configurator getConfigurator() { 28 | return Configurator.getInstance(); 29 | } 30 | 31 | public static T getConfiguration(Object key) { 32 | return getConfigurator().getConfiguration(key); 33 | } 34 | 35 | public static Context getApplicationContext() { 36 | return getConfiguration(ConfigKeys.APPLICATION_CONTEXT); 37 | } 38 | 39 | public static Application getApplication() { 40 | return getConfiguration(ConfigKeys.APPLICATION); 41 | } 42 | 43 | public static Handler getHandler() { 44 | return getConfiguration(ConfigKeys.HANDLER); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/IPageLoadListener.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/12/23 17:59 6 | * @desciption: 7 | */ 8 | 9 | public interface IPageLoadListener { 10 | 11 | void onLoadStart(); 12 | 13 | void onLoadEnd(); 14 | } 15 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/LatteDelegate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/22 23:01 6 | * @desciption: 正式使用的 7 | */ 8 | 9 | public abstract class LatteDelegate extends PermissionCheckerDelegate { 10 | 11 | @SuppressWarnings("unchecked") 12 | public T getParentDelegate() { 13 | return (T) getParentFragment(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/bottom/BottomItemDelegate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.bottom; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.wuchao.latte.R; 6 | import com.wuchao.latte.app.Latte; 7 | import com.wuchao.latte.delegates.LatteDelegate; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2017/12/2 17:44 12 | * @desciption: 13 | */ 14 | 15 | public abstract class BottomItemDelegate extends LatteDelegate { 16 | 17 | //再点一次退出程序时间设置 18 | private static final long WAIT_TIME = 2000L; 19 | private long touchTime = 0; 20 | 21 | @Override 22 | public boolean onBackPressedSupport() { 23 | if (System.currentTimeMillis() - touchTime > WAIT_TIME) { 24 | Toast.makeText(_mActivity, "双击退出"+ Latte.getApplicationContext().getString(R.string.app_name), Toast.LENGTH_SHORT).show(); 25 | touchTime = System.currentTimeMillis(); 26 | } else { 27 | _mActivity.finish(); 28 | } 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/bottom/BottomTabBean.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.bottom; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/12/2 18:15 6 | * @desciption: 7 | */ 8 | 9 | public class BottomTabBean { 10 | 11 | private final CharSequence ICON; 12 | private final CharSequence TITLE; 13 | 14 | public BottomTabBean(CharSequence icon, CharSequence title) { 15 | this.ICON = icon; 16 | this.TITLE = title; 17 | } 18 | 19 | public CharSequence getIcon() { 20 | return ICON; 21 | } 22 | 23 | public CharSequence getTitle() { 24 | return TITLE; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/bottom/ItemBuilder.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.bottom; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/12/2 18:17 8 | * @desciption: 9 | */ 10 | 11 | public class ItemBuilder { 12 | 13 | private final LinkedHashMap ITEMS = new LinkedHashMap<>(); 14 | 15 | static ItemBuilder builder() { 16 | return new ItemBuilder(); 17 | } 18 | 19 | public final LinkedHashMap build() { 20 | return ITEMS; 21 | } 22 | 23 | public final ItemBuilder addItem(BottomTabBean bean, BottomItemDelegate delegate) { 24 | ITEMS.put(bean, delegate); 25 | return this; 26 | } 27 | 28 | public final ItemBuilder addItems(LinkedHashMap items) { 29 | ITEMS.putAll(items); 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/IWebViewInitializer.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web; 2 | 3 | import android.webkit.WebChromeClient; 4 | import android.webkit.WebView; 5 | import android.webkit.WebViewClient; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2017/11/28 22:49 10 | * @desciption: 11 | */ 12 | 13 | public interface IWebViewInitializer { 14 | 15 | WebView initWebView(WebView webView); 16 | 17 | WebViewClient initWebViewClient(); 18 | 19 | WebChromeClient initWebChromeClient(); 20 | } 21 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/LatteWebInterface.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web; 2 | 3 | import android.webkit.JavascriptInterface; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | import com.wuchao.latte.delegates.web.event.Event; 7 | import com.wuchao.latte.delegates.web.event.EventManager; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2017/11/28 23:06 12 | * @desciption: 13 | */ 14 | 15 | final class LatteWebInterface { 16 | 17 | private final WebDelegate DELEGATE; 18 | 19 | private LatteWebInterface(WebDelegate delegate) { 20 | this.DELEGATE = delegate; 21 | } 22 | 23 | static LatteWebInterface create(WebDelegate delegate) { 24 | return new LatteWebInterface(delegate); 25 | } 26 | 27 | @JavascriptInterface 28 | public String event(String params) { 29 | final String action = JSON.parseObject(params).getString("action"); 30 | final Event event = EventManager.getInstance().createEvent(action); 31 | if (event != null) { 32 | event.setAction(action); 33 | event.setContext(DELEGATE.getContext()); 34 | event.setDelegate(DELEGATE); 35 | event.setUrl(DELEGATE.getUrl()); 36 | return event.execute(params); 37 | } 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/chromeclient/WebChromeClientImpl.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web.chromeclient; 2 | 3 | import android.webkit.JsResult; 4 | import android.webkit.WebChromeClient; 5 | import android.webkit.WebView; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2017/11/29 21:58 10 | * @desciption: 11 | */ 12 | 13 | public class WebChromeClientImpl extends WebChromeClient { 14 | 15 | @Override 16 | public boolean onJsAlert(WebView view, String url, String message, JsResult result) { 17 | return super.onJsAlert(view, url, message, result); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/event/Event.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web.event; 2 | 3 | import android.content.Context; 4 | import android.webkit.WebView; 5 | 6 | import com.wuchao.latte.delegates.web.WebDelegate; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2017/11/29 22:22 11 | * @desciption: 12 | */ 13 | 14 | public abstract class Event implements IEvent { 15 | 16 | private Context mContext; 17 | private String mAction; 18 | private WebDelegate mDelegate; 19 | private String mUrl; 20 | private WebView mWebView; 21 | 22 | public Context getContext() { 23 | return mContext; 24 | } 25 | 26 | public void setContext(Context context) { 27 | mContext = context; 28 | } 29 | 30 | public String getAction() { 31 | return mAction; 32 | } 33 | 34 | public void setAction(String action) { 35 | mAction = action; 36 | } 37 | 38 | public WebDelegate getDelegate() { 39 | return mDelegate; 40 | } 41 | 42 | public void setDelegate(WebDelegate delegate) { 43 | mDelegate = delegate; 44 | } 45 | 46 | public String getUrl() { 47 | return mUrl; 48 | } 49 | 50 | public void setUrl(String url) { 51 | mUrl = url; 52 | } 53 | 54 | public WebView getWebView() { 55 | return mDelegate.getWebView(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/event/EventManager.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web.event; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import java.util.HashMap; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2017/11/29 22:21 10 | * @desciption: 11 | */ 12 | 13 | public class EventManager { 14 | 15 | private static final HashMap EVENTS = new HashMap<>(); 16 | 17 | private EventManager() { 18 | } 19 | 20 | private static class Holder { 21 | private static final EventManager INSTANCE = new EventManager(); 22 | } 23 | 24 | public static EventManager getInstance() { 25 | return Holder.INSTANCE; 26 | } 27 | 28 | public EventManager addEvent(@NonNull String name, @NonNull Event event) { 29 | EVENTS.put(name, event); 30 | return this; 31 | } 32 | 33 | public Event createEvent(@NonNull String action) { 34 | final Event event = EVENTS.get(action); 35 | if (event == null) { 36 | return new UndefineEvent(); 37 | } 38 | return event; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/event/IEvent.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web.event; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/11/29 22:22 6 | * @desciption: 7 | */ 8 | 9 | public interface IEvent { 10 | String execute(String params); 11 | } 12 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/event/UndefineEvent.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web.event; 2 | 3 | import com.wuchao.latte.util.log.LatteLogger; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/11/29 22:44 8 | * @desciption: 9 | */ 10 | 11 | public class UndefineEvent extends Event { 12 | @Override 13 | public String execute(String params) { 14 | LatteLogger.e("UndefineEvent", params); 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/delegates/web/route/RouteKeys.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.delegates.web.route; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/11/28 22:56 6 | * @desciption: 7 | */ 8 | 9 | public enum RouteKeys { 10 | /** 11 | * web页面跳转必须传递的参数 12 | */ 13 | URL 14 | } 15 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/HttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/23 22:51 6 | * @desciption: 7 | */ 8 | 9 | public enum HttpMethod { 10 | GET, 11 | POST, 12 | POST_RAW, 13 | PUT, 14 | PUT_RAW, 15 | DELETE, 16 | UPLOAD 17 | } 18 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/base/BaseObserver.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.base; 2 | 3 | import io.reactivex.Observer; 4 | import io.reactivex.disposables.Disposable; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2018/2/1 18:47 9 | * @desciption: 基类BaseObserver 10 | */ 11 | 12 | public abstract class BaseObserver implements Observer { 13 | 14 | @Override 15 | public void onSubscribe(Disposable d) { 16 | 17 | } 18 | 19 | @Override 20 | public void onNext(T t) { 21 | 22 | } 23 | 24 | @Override 25 | public void onError(Throwable e) { 26 | 27 | } 28 | 29 | @Override 30 | public void onComplete() { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/bean/BaseData.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.bean; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2018/2/1 18:44 6 | * @desciption: 返回数据基类 7 | */ 8 | 9 | public class BaseData { 10 | /** 11 | * 错误码 12 | */ 13 | private int code; 14 | /** 15 | * 错误描述 16 | */ 17 | private String msg; 18 | /** 19 | * 数据 20 | */ 21 | private T data; 22 | 23 | public int getCode() { 24 | return code; 25 | } 26 | 27 | public void setCode(int code) { 28 | this.code = code; 29 | } 30 | 31 | public String getMsg() { 32 | return msg; 33 | } 34 | 35 | public void setMsg(String msg) { 36 | this.msg = msg; 37 | } 38 | 39 | public T getData() { 40 | return data; 41 | } 42 | 43 | public void setData(T data) { 44 | this.data = data; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return "BaseData{" + 50 | "code=" + code + 51 | ", msg='" + msg + '\'' + 52 | ", data=" + data + 53 | '}'; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/callback/IError.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.callback; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/23 23:08 6 | * @desciption: 7 | */ 8 | 9 | public interface IError { 10 | 11 | void onError(int code, String msg); 12 | } 13 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/callback/IFailure.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.callback; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/23 23:09 6 | * @desciption: 7 | */ 8 | 9 | public interface IFailure { 10 | 11 | void onFailure(); 12 | } 13 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/callback/IRequest.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.callback; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/23 23:09 6 | * @desciption: 7 | */ 8 | 9 | public interface IRequest { 10 | 11 | void onRequestStart(); 12 | 13 | void onRequestEnd(); 14 | } 15 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/callback/ISuccess.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.callback; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/23 23:08 6 | * @desciption: 7 | */ 8 | 9 | public interface ISuccess { 10 | 11 | void onSuccess(String response); 12 | } 13 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/callback/RequestCallbacks.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.callback; 2 | 3 | import android.os.Handler; 4 | 5 | import com.wuchao.latte.ui.loader.LatteLoader; 6 | import com.wuchao.latte.ui.loader.LoaderStyle; 7 | 8 | import retrofit2.Call; 9 | import retrofit2.Callback; 10 | import retrofit2.Response; 11 | 12 | /** 13 | * @author: wuchao 14 | * @date: 2017/10/24 22:50 15 | * @desciption: 16 | */ 17 | 18 | public class RequestCallbacks implements Callback { 19 | 20 | private final IRequest REQUEST; 21 | private final ISuccess SUCCESS; 22 | private final IFailure FAILURE; 23 | private final IError ERROR; 24 | private final LoaderStyle LOADER_STYLE; 25 | private static final Handler HANDLER = new Handler(); 26 | 27 | public RequestCallbacks(IRequest request, ISuccess success, IFailure failure, IError error, LoaderStyle loaderStyle) { 28 | this.REQUEST = request; 29 | this.SUCCESS = success; 30 | this.FAILURE = failure; 31 | this.ERROR = error; 32 | this.LOADER_STYLE = loaderStyle; 33 | } 34 | 35 | @Override 36 | public void onResponse(Call call, Response response) { 37 | if (response.isSuccessful()) { 38 | if (call.isExecuted()) { 39 | if (SUCCESS != null) { 40 | SUCCESS.onSuccess(response.body()); 41 | } 42 | } 43 | } else { 44 | if (ERROR != null) { 45 | ERROR.onError(response.code(), response.message()); 46 | } 47 | } 48 | stopLoading(); 49 | } 50 | 51 | @Override 52 | public void onFailure(Call call, Throwable t) { 53 | if (FAILURE != null) { 54 | FAILURE.onFailure(); 55 | } 56 | if (REQUEST != null) { 57 | REQUEST.onRequestEnd(); 58 | } 59 | stopLoading(); 60 | } 61 | 62 | private void stopLoading() { 63 | if (LOADER_STYLE != null) { 64 | HANDLER.postDelayed(new Runnable() { 65 | @Override 66 | public void run() { 67 | LatteLoader.stopLoading(); 68 | } 69 | }, 1000); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/interceptors/AddCookieInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.interceptors; 2 | 3 | import com.wuchao.latte.util.log.LatteLogger; 4 | import com.wuchao.latte.util.storage.LattePreference; 5 | 6 | import java.io.IOException; 7 | 8 | import io.reactivex.Observable; 9 | import io.reactivex.functions.Consumer; 10 | import okhttp3.Interceptor; 11 | import okhttp3.Request; 12 | import okhttp3.Response; 13 | 14 | /** 15 | * @author: wuchao 16 | * @date: 2017/12/23 21:05 17 | * @desciption: 18 | */ 19 | 20 | public final class AddCookieInterceptor implements Interceptor { 21 | 22 | @Override 23 | public Response intercept(Chain chain) throws IOException { 24 | final Request.Builder builder = chain.request().newBuilder(); 25 | //通过just( )方式 直接触发onNext(),just中传递的参数将直接在Observer的onNext()方法中接收到 26 | Observable 27 | .just(LattePreference.getCustomAppProfile("cookie")) 28 | .subscribe(new Consumer() { 29 | @Override 30 | public void accept(String cookie) throws Exception { 31 | LatteLogger.d("AddCookieInterceptor", "cookie---》" +cookie); 32 | //给原生API请求附带上WebView拦截下来的Cookie 33 | builder.addHeader("Cookie", cookie); 34 | } 35 | }); 36 | return chain.proceed(builder.build()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/interceptors/BaseInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.interceptors; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import java.io.IOException; 6 | import java.util.LinkedHashMap; 7 | 8 | import okhttp3.FormBody; 9 | import okhttp3.HttpUrl; 10 | import okhttp3.Interceptor; 11 | import okhttp3.Request; 12 | import okhttp3.Response; 13 | 14 | /** 15 | * @author: wuchao 16 | * @date: 2017/11/7 23:34 17 | * @desciption: 18 | */ 19 | 20 | public abstract class BaseInterceptor implements Interceptor { 21 | @Override 22 | public Response intercept(@NonNull Chain chain) throws IOException { 23 | return null; 24 | } 25 | 26 | protected LinkedHashMap getUrlParameters(Chain chain) { 27 | final HttpUrl url = chain.request().url(); 28 | final int size = url.querySize(); 29 | LinkedHashMap params = new LinkedHashMap<>(); 30 | for (int i = 0; i < size; i++) { 31 | params.put(url.queryParameterName(i), url.queryParameterValue(i)); 32 | } 33 | return params; 34 | } 35 | 36 | protected String getUrlParameters(Chain chain, String key) { 37 | final Request request = chain.request(); 38 | return request.url().queryParameter(key); 39 | } 40 | 41 | /** 42 | * 从请求体获取参数 43 | * 44 | * @param chain 45 | * @return 46 | */ 47 | protected LinkedHashMap getBodyParameters(Chain chain) { 48 | final FormBody formBody = (FormBody) chain.request().body(); 49 | final int size = formBody.size(); 50 | LinkedHashMap params = new LinkedHashMap<>(); 51 | for (int i = 0; i < size; i++) { 52 | params.put(formBody.name(i), formBody.value(i)); 53 | } 54 | return params; 55 | } 56 | 57 | protected String getBodyParameters(Chain chain, String key) { 58 | return getBodyParameters(chain).get(key); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/interceptors/DebugInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.interceptors; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | import com.wuchao.latte.util.file.FileUtil; 6 | 7 | import java.io.IOException; 8 | 9 | import okhttp3.MediaType; 10 | import okhttp3.Protocol; 11 | import okhttp3.Response; 12 | import okhttp3.ResponseBody; 13 | 14 | /** 15 | * @author: wuchao 16 | * @date: 2017/11/12 19:45 17 | * @desciption: 18 | */ 19 | 20 | public class DebugInterceptor extends BaseInterceptor { 21 | 22 | private final String DEBUG_URL; 23 | private final int DEBUG_RAW_ID; 24 | 25 | public DebugInterceptor(String debugUrl, int rawId) { 26 | this.DEBUG_URL = debugUrl; 27 | this.DEBUG_RAW_ID = rawId; 28 | } 29 | 30 | private Response getResponse(Chain chain, String json) { 31 | return new Response.Builder() 32 | .code(200) 33 | .addHeader("content-Type", "application/json") 34 | .body(ResponseBody.create(MediaType.parse("application/json"), json)) 35 | .message("ok") 36 | .request(chain.request()) 37 | .protocol(Protocol.HTTP_1_1) 38 | .build(); 39 | } 40 | 41 | private Response debugResponse(Chain chain, int rawId) { 42 | String json = FileUtil.getRawFile(rawId); 43 | return getResponse(chain, json); 44 | } 45 | 46 | @Override 47 | public Response intercept(@NonNull Chain chain) throws IOException { 48 | final String url = chain.request().url().toString(); 49 | if (url.contains(DEBUG_URL)) { 50 | return debugResponse(chain, DEBUG_RAW_ID); 51 | } 52 | return chain.proceed(chain.request()); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/interceptors/InterceptorUtil.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.interceptors; 2 | 3 | import com.wuchao.latte.util.log.LatteLogger; 4 | 5 | import okhttp3.logging.HttpLoggingInterceptor; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2018/1/31 18:22 10 | * @desciption: 拦截器工具类! 11 | */ 12 | 13 | public class InterceptorUtil { 14 | private static String TAG = "RetrofitLog"; 15 | 16 | //日志拦截器 17 | public static HttpLoggingInterceptor LoggingInterceptor() { 18 | return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { 19 | @Override 20 | public void log(String message) { 21 | LatteLogger.i(TAG, message); 22 | } 23 | }).setLevel(HttpLoggingInterceptor.Level.BODY); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/interfaces/ISubscriber.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.interfaces; 2 | 3 | import io.reactivex.disposables.Disposable; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2018/2/1 18:50 8 | * @desciption: 定义请求结果处理接口 9 | */ 10 | 11 | public interface ISubscriber { 12 | /** 13 | * doOnSubscribe 回调 14 | * 15 | * @param d 16 | */ 17 | void doOnSubscribe(Disposable d); 18 | } 19 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/rx/ApiException.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.rx; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2018/1/22 16:58 6 | * @desciption: 7 | */ 8 | 9 | public class ApiException { 10 | } 11 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/rx/RxRestService.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.rx; 2 | 3 | import java.util.Map; 4 | 5 | import io.reactivex.Observable; 6 | import okhttp3.MultipartBody; 7 | import okhttp3.RequestBody; 8 | import okhttp3.ResponseBody; 9 | import retrofit2.http.Body; 10 | import retrofit2.http.DELETE; 11 | import retrofit2.http.FieldMap; 12 | import retrofit2.http.FormUrlEncoded; 13 | import retrofit2.http.GET; 14 | import retrofit2.http.Multipart; 15 | import retrofit2.http.POST; 16 | import retrofit2.http.PUT; 17 | import retrofit2.http.Part; 18 | import retrofit2.http.QueryMap; 19 | import retrofit2.http.Streaming; 20 | import retrofit2.http.Url; 21 | 22 | /** 23 | * @author: wuchao 24 | * @date: 2017/10/23 22:44 25 | * @desciption: 26 | */ 27 | 28 | public interface RxRestService { 29 | 30 | @GET 31 | Observable get(@Url String url, @QueryMap Map params); 32 | 33 | @FormUrlEncoded 34 | @POST 35 | Observable post(@Url String url, @FieldMap Map params); 36 | 37 | //传入原始数据 38 | @POST 39 | Observable postRaw(@Url String url, @Body RequestBody body); 40 | 41 | @FormUrlEncoded 42 | @PUT 43 | Observable put(@Url String url, @FieldMap Map params); 44 | 45 | //传入原始数据 46 | @PUT 47 | Observable putRaw(@Url String url, @Body RequestBody body); 48 | 49 | @DELETE 50 | Observable delete(@Url String url, @QueryMap Map params); 51 | 52 | @Streaming 53 | @GET 54 | Observable download(@Url String url, @QueryMap Map params); 55 | 56 | @Multipart 57 | @POST 58 | Observable upload(@Url String url, @Part MultipartBody.Part file); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/net/rx/Transformer.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.net.rx; 2 | 3 | import io.reactivex.Observable; 4 | import io.reactivex.ObservableSource; 5 | import io.reactivex.ObservableTransformer; 6 | import io.reactivex.android.schedulers.AndroidSchedulers; 7 | import io.reactivex.schedulers.Schedulers; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2018/1/22 11:40 12 | * @desciption: 13 | */ 14 | 15 | public class Transformer { 16 | /** 17 | * @param 泛型 18 | * @return 19 | */ 20 | public static ObservableTransformer switchSchedulers() { 21 | return new ObservableTransformer() { 22 | @Override 23 | public ObservableSource apply(Observable upstream) { 24 | return upstream 25 | .subscribeOn(Schedulers.io()) 26 | .observeOn(AndroidSchedulers.mainThread()) 27 | /*.doOnSubscribe(new Consumer() { 28 | @Override 29 | public void accept(Disposable disposable) throws Exception { 30 | 31 | } 32 | }) 33 | .subscribeOn(AndroidSchedulers.mainThread()) 34 | .observeOn(AndroidSchedulers.mainThread()*//*)*/; 35 | } 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/animation/BezierAnimation.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.animation; 2 | 3 | import android.view.View; 4 | import android.view.ViewGroup; 5 | import android.widget.ImageView; 6 | 7 | import com.blankj.utilcode.util.ScreenUtils; 8 | import com.wuchao.latte.delegates.LatteDelegate; 9 | 10 | /** 11 | * @author: wuchao 12 | * @date: 2018/1/20 22:03 13 | * @desciption: 14 | */ 15 | 16 | public class BezierAnimation { 17 | 18 | public static void addCart(LatteDelegate delegate, View start, View end, 19 | ImageView target, BezierUtil.AnimationListener animationListener) { 20 | /* 起点 */ 21 | final int[] startXY = new int[2]; 22 | start.getLocationInWindow(startXY); 23 | startXY[0] += start.getWidth() / 2; 24 | final int fx = startXY[0]; 25 | final int fy = startXY[1]; 26 | 27 | final ViewGroup anim_mask_layout = BezierUtil.createAnimLayout(delegate.getProxyActivity()); 28 | anim_mask_layout.addView(target); 29 | final View v = BezierUtil.addViewToAnimLayout(delegate.getContext(), target, startXY, true); 30 | if (v == null) { 31 | return; 32 | } 33 | /* 终点 */ 34 | final int[] endXY = new int[2]; 35 | end.getLocationInWindow(endXY); 36 | final int tx = endXY[0] + end.getWidth() / 2 - 48; 37 | final int ty = endXY[1] + end.getHeight() / 2; 38 | /* 中点 */ 39 | final int mx = (tx + fx) / 2; 40 | final int my = ScreenUtils.getScreenHeight() / 10; 41 | BezierUtil.startAnimationForJd(v, 0, 0, fx, fy, mx, my, tx, ty, animationListener); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/banner/BannerCreator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.banner; 2 | 3 | import com.bigkoo.convenientbanner.ConvenientBanner; 4 | import com.bigkoo.convenientbanner.listener.OnItemClickListener; 5 | import com.wuchao.latte.R; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2017/12/10 20:23 12 | * @desciption: 13 | */ 14 | 15 | public class BannerCreator { 16 | 17 | public static void setDefault(ConvenientBanner convenientBanner, 18 | ArrayList banners, 19 | OnItemClickListener clickListener) { 20 | convenientBanner.setPages(new HolderCreator(), banners) 21 | .setPageIndicator(new int[]{R.drawable.dot_normal, R.drawable.dot_focus}) 22 | .setPageIndicatorAlign(ConvenientBanner.PageIndicatorAlign.CENTER_HORIZONTAL) 23 | .setOnItemClickListener(clickListener) 24 | .startTurning(3000) 25 | .setCanLoop(true); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/banner/HolderCreator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.banner; 2 | 3 | import com.bigkoo.convenientbanner.holder.CBViewHolderCreator; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/12/10 20:25 8 | * @desciption: 9 | */ 10 | 11 | public class HolderCreator implements CBViewHolderCreator{ 12 | @Override 13 | public ImageHolder createHolder() { 14 | return new ImageHolder(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/banner/ImageHolder.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.banner; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.AppCompatImageView; 5 | import android.view.View; 6 | 7 | import com.bigkoo.convenientbanner.holder.Holder; 8 | import com.bumptech.glide.Glide; 9 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 10 | import com.bumptech.glide.request.RequestOptions; 11 | 12 | /** 13 | * @author: wuchao 14 | * @date: 2017/12/10 20:25 15 | * @desciption: 16 | */ 17 | 18 | public class ImageHolder implements Holder { 19 | 20 | private AppCompatImageView mImageView = null; 21 | 22 | private static final RequestOptions BANNER_OPTIONS = new RequestOptions() 23 | .diskCacheStrategy(DiskCacheStrategy.ALL) 24 | .dontAnimate() 25 | .centerCrop(); 26 | 27 | @Override 28 | public View createView(Context context) { 29 | mImageView = new AppCompatImageView(context); 30 | return mImageView; 31 | } 32 | 33 | @Override 34 | public void UpdateUI(Context context, int position, String data) { 35 | Glide.with(context) 36 | .load(data) 37 | .apply(BANNER_OPTIONS) 38 | .into(mImageView); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/camera/CameraImageBean.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.camera; 2 | 3 | import android.net.Uri; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2018/1/4 23:18 8 | * @desciption: 存储一些中间值 9 | */ 10 | 11 | public class CameraImageBean { 12 | 13 | private Uri mPath = null; 14 | 15 | private static final class Holder { 16 | private static final CameraImageBean INSTANCE = new CameraImageBean(); 17 | } 18 | 19 | public static CameraImageBean getInstance() { 20 | return Holder.INSTANCE; 21 | } 22 | 23 | public Uri getPath() { 24 | return mPath; 25 | } 26 | 27 | public void setPath(Uri path) { 28 | mPath = path; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/camera/LatteCamera.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.camera; 2 | 3 | import android.net.Uri; 4 | 5 | import com.wuchao.latte.delegates.PermissionCheckerDelegate; 6 | import com.wuchao.latte.util.file.FileUtil; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2018/1/4 23:17 11 | * @desciption: 照相机调用类 12 | */ 13 | 14 | public class LatteCamera { 15 | 16 | public static Uri createCropFile() { 17 | return Uri.parse(FileUtil.createFile("crop_image", 18 | FileUtil.getFileNameByTime("IMG", "jpg")).getPath()); 19 | } 20 | 21 | public static void start(PermissionCheckerDelegate delegate) { 22 | new CameraHandler(delegate).beginCameraDialog(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/camera/RequestCodes.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.camera; 2 | 3 | import com.yalantis.ucrop.UCrop; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2018/1/4 23:18 8 | * @desciption: 请求码存储 9 | */ 10 | 11 | public class RequestCodes { 12 | 13 | public static final int TAKE_PHOTO = 4; 14 | public static final int PICK_PHOTO = 5; 15 | public static final int CROP_PHOTO = UCrop.REQUEST_CROP; 16 | public static final int CROP_ERROR = UCrop.RESULT_ERROR; 17 | public static final int SCAN = 7; 18 | } 19 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/launcher/LauncherHolder.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.launcher; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.ImageView; 6 | 7 | import com.bigkoo.convenientbanner.holder.Holder; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2017/11/15 23:27 12 | * @desciption: 13 | */ 14 | 15 | public class LauncherHolder implements Holder { 16 | 17 | private ImageView mImageView; 18 | 19 | @Override 20 | public View createView(Context context) { 21 | mImageView = new ImageView(context); 22 | mImageView.setScaleType(ImageView.ScaleType.FIT_XY); 23 | return mImageView; 24 | } 25 | 26 | @Override 27 | public void UpdateUI(Context context, int position, Integer data) { 28 | mImageView.setBackgroundResource(data); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/launcher/LauncherHolderCreator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.launcher; 2 | 3 | import com.bigkoo.convenientbanner.holder.CBViewHolderCreator; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/11/15 23:31 8 | * @desciption: 9 | */ 10 | 11 | public class LauncherHolderCreator implements CBViewHolderCreator { 12 | 13 | @Override 14 | public LauncherHolder createHolder() { 15 | return new LauncherHolder(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/launcher/ScrollLauncherTag.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.launcher; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/11/16 22:15 6 | * @desciption: 7 | */ 8 | 9 | public enum ScrollLauncherTag { 10 | HAS_FIRST_LAUNCHER_APP 11 | } 12 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/loader/LoaderCreator.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.loader; 2 | 3 | import android.content.Context; 4 | 5 | import com.wang.avi.AVLoadingIndicatorView; 6 | import com.wang.avi.Indicator; 7 | 8 | import java.util.WeakHashMap; 9 | 10 | /** 11 | * @author: wuchao 12 | * @date: 2017/10/24 23:11 13 | * @desciption: 官方的加载方式是通过反射,通过取loader的名字来加载loader; 14 | * 以一种缓存的方式创建loader,就不需要每次使用loader时就反射一次,提高性能 15 | */ 16 | 17 | public final class LoaderCreator { 18 | 19 | private static final WeakHashMap LOADING_MAP = new WeakHashMap<>(); 20 | 21 | static AVLoadingIndicatorView create(String type, Context context) { 22 | final AVLoadingIndicatorView avLoadingIndicatorView = new AVLoadingIndicatorView(context); 23 | if (LOADING_MAP.get(type) == null) { 24 | final Indicator indicator = getIndicator(type); 25 | LOADING_MAP.put(type, indicator); 26 | } 27 | avLoadingIndicatorView.setIndicator(LOADING_MAP.get(type)); 28 | return avLoadingIndicatorView; 29 | } 30 | 31 | private static Indicator getIndicator(String name) { 32 | if (name == null || name.isEmpty()) { 33 | return null; 34 | } 35 | //通过反射获取包名如:com.wang.avi.indicators.BallPulseIndicator 36 | final StringBuilder drawableClassName = new StringBuilder(); 37 | //说明传入的是类名 38 | if (!name.equals(".")) { 39 | final String defaultPackageName = AVLoadingIndicatorView.class.getPackage().getName(); 40 | drawableClassName.append(defaultPackageName) 41 | .append(".indicators") 42 | .append("."); 43 | } 44 | drawableClassName.append(name); 45 | try { 46 | final Class drawableClass = Class.forName(drawableClassName.toString()); 47 | return (Indicator) drawableClass.newInstance(); 48 | } catch (Exception e) { 49 | e.printStackTrace(); 50 | return null; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/loader/LoaderStyle.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.loader; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/10/26 22:56 6 | * @desciption: 7 | */ 8 | @SuppressWarnings("unused") 9 | public enum LoaderStyle { 10 | BallPulseIndicator, 11 | BallGridPulseIndicator, 12 | BallClipRotateIndicator, 13 | BallClipRotatePulseIndicator, 14 | SquareSpinIndicator, 15 | BallClipRotateMultipleIndicator, 16 | BallPulseRiseIndicator, 17 | BallRotateIndicator, 18 | CubeTransitionIndicator, 19 | BallZigZagIndicator, 20 | BallZigZagDeflectIndicator, 21 | BallTrianglePathIndicator, 22 | BallScaleIndicator, 23 | LineScaleIndicator, 24 | LineScalePartyIndicator, 25 | BallScaleMultipleIndicator, 26 | BallPulseSyncIndicator, 27 | BallBeatIndicator, 28 | LineScalePulseOutIndicator, 29 | LineScalePulseOutRapidIndicator, 30 | BallScaleRippleIndicator, 31 | BallScaleRippleMultipleIndicator, 32 | BallSpinFadeLoaderIndicator, 33 | LineSpinFadeLoaderIndicator, 34 | TriangleSkewSpinIndicator, 35 | PacmanIndicator, 36 | BallGridBeatIndicator, 37 | SemiCircleSpinIndicator, 38 | CustomIndicator 39 | } 40 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/BaseDecoration.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import android.support.annotation.ColorInt; 4 | 5 | import com.choices.divider.DividerItemDecoration; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2017/12/10 22:33 10 | * @desciption: 11 | */ 12 | 13 | public class BaseDecoration extends DividerItemDecoration { 14 | 15 | private BaseDecoration(@ColorInt int color, int size) { 16 | setDividerLookup(new DividerLookupImpl(color, size)); 17 | } 18 | 19 | public static BaseDecoration create(@ColorInt int color, int size) { 20 | return new BaseDecoration(color, size); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/DataConverter.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/12/6 21:46 8 | * @desciption: 9 | */ 10 | 11 | public abstract class DataConverter { 12 | 13 | protected ArrayList ENTITIES = new ArrayList<>(); 14 | private String mJsonData = null; 15 | 16 | public abstract ArrayList convert(); 17 | 18 | public DataConverter setJsonData(String json) { 19 | this.mJsonData = json; 20 | return this; 21 | } 22 | 23 | protected String getJsonData() { 24 | if (mJsonData == null || mJsonData.isEmpty()) { 25 | throw new NullPointerException("DATA IS NULL"); 26 | } 27 | return mJsonData; 28 | } 29 | 30 | public void clearData() { 31 | ENTITIES.clear(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/DividerLookupImpl.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import com.choices.divider.Divider; 4 | import com.choices.divider.DividerItemDecoration; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2017/12/10 22:35 9 | * @desciption: 10 | */ 11 | 12 | public class DividerLookupImpl implements DividerItemDecoration.DividerLookup { 13 | 14 | private final int COLOR; 15 | private final int SIZE; 16 | 17 | public DividerLookupImpl(int color, int size) { 18 | this.COLOR = color; 19 | this.SIZE = size; 20 | } 21 | 22 | @Override 23 | public Divider getVerticalDivider(int position) { 24 | return new Divider.Builder() 25 | .size(SIZE) 26 | .color(COLOR) 27 | .build(); 28 | } 29 | 30 | @Override 31 | public Divider getHorizontalDivider(int position) { 32 | return new Divider.Builder() 33 | .size(SIZE) 34 | .color(COLOR) 35 | .build(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/ItemType.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/12/6 23:16 6 | * @desciption: 7 | */ 8 | 9 | public class ItemType { 10 | 11 | public static final int TEXT = 1; 12 | public static final int IMAGE = 2; 13 | public static final int TEXT_IMAGE = 3; 14 | public static final int BANNER = 4; 15 | public static final int VERTICAL_MENU_LIST = 5; 16 | public static final int SINGLE_BIG_IMAGE = 6; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/MultipleFields.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/12/6 21:59 6 | * @desciption: 7 | */ 8 | 9 | public enum MultipleFields { 10 | ITEM_TYPE, 11 | TITLE, 12 | TEXT, 13 | IMAGE_URL, 14 | BANNERS, 15 | SPAN_SIZE, 16 | ID, 17 | NAME, 18 | TAG 19 | } 20 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/MultipleItemEntity.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import com.chad.library.adapter.base.entity.MultiItemEntity; 4 | 5 | import java.lang.ref.ReferenceQueue; 6 | import java.lang.ref.SoftReference; 7 | import java.util.LinkedHashMap; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2017/12/6 21:46 12 | * @desciption: 13 | */ 14 | 15 | public class MultipleItemEntity implements MultiItemEntity { 16 | 17 | private final ReferenceQueue> ITEM_QUEUE = new ReferenceQueue<>(); 18 | private final LinkedHashMap MULTIPLE_FIELDS = new LinkedHashMap<>(); 19 | private final SoftReference> FIELDS_REFERENCE = 20 | new SoftReference<>(MULTIPLE_FIELDS, ITEM_QUEUE); 21 | 22 | MultipleItemEntity(LinkedHashMap fields) { 23 | FIELDS_REFERENCE.get().putAll(fields); 24 | } 25 | 26 | public static MultipleItemEntityBuilder builder() { 27 | return new MultipleItemEntityBuilder(); 28 | } 29 | 30 | @Override 31 | public int getItemType() { 32 | return (int) FIELDS_REFERENCE.get().get(MultipleFields.ITEM_TYPE); 33 | } 34 | 35 | public final T getField(Object key) { 36 | return (T) FIELDS_REFERENCE.get().get(key); 37 | } 38 | 39 | public final MultiItemEntity setField(Object key, Object value) { 40 | FIELDS_REFERENCE.get().put(key, value); 41 | return this; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/MultipleItemEntityBuilder.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/12/6 21:48 8 | * @desciption: 9 | */ 10 | 11 | public class MultipleItemEntityBuilder { 12 | 13 | private final LinkedHashMap FIELDS = new LinkedHashMap<>(); 14 | 15 | public MultipleItemEntityBuilder() { 16 | //先清除之前的数据 17 | FIELDS.clear(); 18 | } 19 | 20 | public final MultipleItemEntityBuilder setItemType(int itemType) { 21 | FIELDS.put(MultipleFields.ITEM_TYPE, itemType); 22 | return this; 23 | } 24 | 25 | public final MultipleItemEntityBuilder setField(Object key, Object value) { 26 | FIELDS.put(key, value); 27 | return this; 28 | } 29 | 30 | public final MultipleItemEntityBuilder setFields(LinkedHashMap map) { 31 | FIELDS.putAll(map); 32 | return this; 33 | } 34 | 35 | public final MultipleItemEntity build() { 36 | return new MultipleItemEntity(FIELDS); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/MultipleViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import android.view.View; 4 | 5 | import com.chad.library.adapter.base.BaseViewHolder; 6 | 7 | /** 8 | * @author: wuchao 9 | * @date: 2017/12/7 22:58 10 | * @desciption: 11 | */ 12 | 13 | public class MultipleViewHolder extends BaseViewHolder { 14 | 15 | public MultipleViewHolder(View view) { 16 | super(view); 17 | } 18 | 19 | public static MultipleViewHolder create(View view) { 20 | return new MultipleViewHolder(view); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/recycler/RgbValue.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.recycler; 2 | 3 | import com.google.auto.value.AutoValue; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/12/17 15:16 8 | * @desciption: 9 | */ 10 | @AutoValue 11 | public abstract class RgbValue { 12 | 13 | public abstract int red(); 14 | 15 | public abstract int green(); 16 | 17 | public abstract int blue(); 18 | 19 | public static RgbValue create(int red, int green, int blue) { 20 | return new AutoValue_RgbValue(red, green, blue); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/refresh/PagingBean.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.refresh; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/12/10 20:51 6 | * @desciption: 7 | */ 8 | 9 | public final class PagingBean { 10 | //当前是第几页 11 | private int mPageIndex = 0; 12 | //总数据条数 13 | private int mTotal = 0; 14 | //一页显示几条数据 15 | private int mPageSize = 0; 16 | //当前已经显示了几条数据 17 | private int mCurrentCount = 0; 18 | //加载延迟 19 | private int mDelayed = 0; 20 | 21 | public int getPageIndex() { 22 | return mPageIndex; 23 | } 24 | 25 | public PagingBean setPageIndex(int pageIndex) { 26 | mPageIndex = pageIndex; 27 | return this; 28 | } 29 | 30 | public int getTotal() { 31 | return mTotal; 32 | } 33 | 34 | public PagingBean setTotal(int total) { 35 | mTotal = total; 36 | return this; 37 | } 38 | 39 | public int getPageSize() { 40 | return mPageSize; 41 | } 42 | 43 | public PagingBean setPageSize(int pageSize) { 44 | mPageSize = pageSize; 45 | return this; 46 | } 47 | 48 | public int getCurrentCount() { 49 | return mCurrentCount; 50 | } 51 | 52 | public PagingBean setCurrentCount(int currentCount) { 53 | mCurrentCount = currentCount; 54 | return this; 55 | } 56 | 57 | public int getDelayed() { 58 | return mDelayed; 59 | } 60 | 61 | public PagingBean setDelayed(int delayed) { 62 | mDelayed = delayed; 63 | return this; 64 | } 65 | 66 | PagingBean addIndex() { 67 | mPageIndex++; 68 | return this; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/scanner/LatteViewFinderView.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.scanner; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.util.AttributeSet; 6 | 7 | import me.dm7.barcodescanner.core.ViewFinderView; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2018/1/11 22:43 12 | * @desciption: 13 | */ 14 | 15 | public class LatteViewFinderView extends ViewFinderView { 16 | 17 | public LatteViewFinderView(Context context) { 18 | this(context, null); 19 | } 20 | 21 | public LatteViewFinderView(Context context, AttributeSet attributeSet) { 22 | super(context, attributeSet); 23 | mSquareViewFinder = true; 24 | mBorderPaint.setColor(Color.YELLOW); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/scanner/ScanView.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.scanner; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import me.dm7.barcodescanner.core.IViewFinder; 7 | import me.dm7.barcodescanner.zbar.ZBarScannerView; 8 | 9 | /** 10 | * @author: wuchao 11 | * @date: 2018/1/11 21:54 12 | * @desciption: 13 | */ 14 | 15 | public class ScanView extends ZBarScannerView { 16 | 17 | public ScanView(Context context) { 18 | this(context, null); 19 | } 20 | 21 | public ScanView(Context context, AttributeSet attributeSet) { 22 | super(context, attributeSet); 23 | } 24 | 25 | @Override 26 | protected IViewFinder createViewFinderView(Context context) { 27 | return new LatteViewFinderView(context); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/scanner/ScannerDelegate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.scanner; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.view.View; 6 | 7 | import com.wuchao.latte.delegates.LatteDelegate; 8 | import com.wuchao.latte.util.callback.CallbackManager; 9 | import com.wuchao.latte.util.callback.CallbackType; 10 | import com.wuchao.latte.util.callback.IGlobalCallback; 11 | 12 | import me.dm7.barcodescanner.zbar.Result; 13 | import me.dm7.barcodescanner.zbar.ZBarScannerView; 14 | 15 | /** 16 | * @author: wuchao 17 | * @date: 2018/1/11 21:50 18 | * @desciption: 19 | */ 20 | 21 | public class ScannerDelegate extends LatteDelegate implements ZBarScannerView.ResultHandler { 22 | 23 | private ScanView mScanView = null; 24 | 25 | @Override 26 | public void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | if (mScanView == null) { 29 | mScanView = new ScanView(getContext()); 30 | } 31 | mScanView.setAutoFocus(true); 32 | mScanView.setResultHandler(this); 33 | } 34 | 35 | @Override 36 | public Object setLayout() { 37 | return mScanView; 38 | } 39 | 40 | @Override 41 | public void onBindView(@Nullable Bundle savedInstanceState, View rootView) { 42 | 43 | } 44 | 45 | @Override 46 | public void onResume() { 47 | super.onResume(); 48 | if (mScanView != null) { 49 | mScanView.startCamera(); 50 | } 51 | } 52 | 53 | @Override 54 | public void onPause() { 55 | super.onPause(); 56 | if (mScanView != null) { 57 | mScanView.stopCameraPreview(); 58 | mScanView.stopCamera(); 59 | } 60 | } 61 | 62 | @Override 63 | public void handleResult(Result result) { 64 | IGlobalCallback callback = CallbackManager.getInstance().getCallback(CallbackType.ON_SCAN); 65 | if (callback != null) { 66 | callback.executeCallback(result.getContents()); 67 | } 68 | getSupportDelegate().pop(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/ui/widget/CircleTextView.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.ui.widget; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.graphics.Canvas; 6 | import android.graphics.Color; 7 | import android.graphics.Paint; 8 | import android.graphics.PaintFlagsDrawFilter; 9 | import android.support.annotation.ColorInt; 10 | import android.support.v7.widget.AppCompatTextView; 11 | import android.util.AttributeSet; 12 | 13 | /** 14 | * @author: wuchao 15 | * @date: 2018/1/18 18:33 16 | * @desciption: 17 | */ 18 | 19 | public class CircleTextView extends AppCompatTextView { 20 | 21 | private Paint mPaint; 22 | //抗锯齿设置 23 | //给Canvas加上抗锯齿标志。 24 | //有些地方不能用paint的,就直接给canvas加抗锯齿,更方便。 25 | private PaintFlagsDrawFilter mFilter; 26 | 27 | public CircleTextView(Context context) { 28 | super(context, null); 29 | } 30 | 31 | public CircleTextView(Context context, AttributeSet attrs) { 32 | super(context, attrs, 0); 33 | mPaint = new Paint(); 34 | mFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 35 | mPaint.setColor(Color.RED); 36 | mPaint.setAntiAlias(true); 37 | } 38 | 39 | public CircleTextView(Context context, AttributeSet attrs, int defStyleAttr) { 40 | super(context, attrs, defStyleAttr); 41 | } 42 | 43 | public final void setCircleBackground(@ColorInt int color) { 44 | mPaint.setColor(color); 45 | } 46 | 47 | @SuppressLint("NewApi") 48 | @Override 49 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 50 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 51 | final int width = getMeasuredWidth(); 52 | final int height = getMaxHeight(); 53 | final int max = Math.max(width, height); 54 | setMeasuredDimension(max, max); 55 | } 56 | 57 | @Override 58 | public void draw(Canvas canvas) { 59 | canvas.setDrawFilter(mFilter); 60 | canvas.drawCircle(getWidth() / 2, getHeight() / 2, 61 | Math.max(getWidth() / 2, getHeight() / 2), mPaint); 62 | super.draw(canvas); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/callback/CallbackManager.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.callback; 2 | 3 | import java.util.WeakHashMap; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2018/1/7 16:56 8 | * @desciption: 9 | */ 10 | 11 | public class CallbackManager { 12 | 13 | private static final WeakHashMap CALLBACKS = new WeakHashMap<>(); 14 | 15 | private static class Holder { 16 | private static final CallbackManager INSTANCE = new CallbackManager(); 17 | } 18 | 19 | public static CallbackManager getInstance() { 20 | return Holder.INSTANCE; 21 | } 22 | 23 | public CallbackManager addCallback(Object tag, IGlobalCallback callback) { 24 | CALLBACKS.put(tag, callback); 25 | return this; 26 | } 27 | 28 | public IGlobalCallback getCallback(Object tag) { 29 | return CALLBACKS.get(tag); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/callback/CallbackType.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.callback; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2018/1/7 17:02 6 | * @desciption: 7 | */ 8 | 9 | public enum CallbackType { 10 | ON_CROP, 11 | TAG_OPEN_PUSH, 12 | TAG_STOP_PUSH, 13 | ON_SCAN 14 | } 15 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/callback/IGlobalCallback.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.callback; 2 | 3 | import android.support.annotation.NonNull; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2018/1/7 16:57 8 | * @desciption: 9 | */ 10 | 11 | public interface IGlobalCallback { 12 | 13 | void executeCallback(@NonNull T args); 14 | } 15 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/dimen/DimenUtil.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.dimen; 2 | 3 | import android.content.res.Resources; 4 | import android.util.DisplayMetrics; 5 | 6 | import com.wuchao.latte.app.Latte; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2017/10/26 23:26 11 | * @desciption: 12 | */ 13 | 14 | public class DimenUtil { 15 | 16 | public static int getScreenWidth() { 17 | final Resources resources = Latte.getApplicationContext().getResources(); 18 | final DisplayMetrics dm = resources.getDisplayMetrics(); 19 | return dm.widthPixels; 20 | } 21 | 22 | public static int getScreenHeight() { 23 | final Resources resources = Latte.getApplicationContext().getResources(); 24 | final DisplayMetrics dm = resources.getDisplayMetrics(); 25 | return dm.heightPixels; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/log/LatteLogger.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.log; 2 | 3 | import com.orhanobut.logger.Logger; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/11/27 17:12 8 | * @desciption: 9 | */ 10 | 11 | public class LatteLogger { 12 | 13 | private static final int VERBOSE = 1; 14 | private static final int DEBUG = 2; 15 | private static final int INFO = 3; 16 | private static final int WARN = 4; 17 | private static final int ERROR = 5; 18 | private static final int NOTHING = 6; 19 | 20 | //控制log等级 21 | private static int LEVEL = VERBOSE; 22 | 23 | public static void v(String tag, String message) { 24 | if (LEVEL <= VERBOSE) { 25 | Logger.t(tag).v(message); 26 | } 27 | } 28 | 29 | public static void d(String tag, Object message) { 30 | if (LEVEL <= DEBUG) { 31 | Logger.t(tag).d(message); 32 | } 33 | } 34 | 35 | public static void d(Object message) { 36 | if (LEVEL <= DEBUG) { 37 | Logger.d(message); 38 | } 39 | } 40 | 41 | public static void i(String tag, String message) { 42 | if (LEVEL <= INFO) { 43 | Logger.t(tag).i(message); 44 | } 45 | } 46 | 47 | public static void w(String tag, String message) { 48 | if (LEVEL <= WARN) { 49 | Logger.t(tag).w(message); 50 | } 51 | } 52 | 53 | public static void json(String tag, String message) { 54 | if (LEVEL <= WARN) { 55 | Logger.t(tag).json(message); 56 | } 57 | } 58 | 59 | public static void e(String tag, String message) { 60 | if (LEVEL <= ERROR) { 61 | Logger.t(tag).e(message); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/timer/BaseTimerTask.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.timer; 2 | 3 | import java.util.TimerTask; 4 | 5 | /** 6 | * @author: wuchao 7 | * @date: 2017/11/14 22:29 8 | * @desciption: 9 | */ 10 | 11 | public class BaseTimerTask extends TimerTask { 12 | 13 | private ITimerListener mITimerListener; 14 | 15 | public BaseTimerTask(ITimerListener timerListener) { 16 | mITimerListener = timerListener; 17 | } 18 | 19 | @Override 20 | public void run() { 21 | if (mITimerListener != null) { 22 | mITimerListener.onTimer(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/util/timer/ITimerListener.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.util.timer; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/11/15 21:32 6 | * @desciption: 7 | */ 8 | 9 | public interface ITimerListener { 10 | void onTimer(); 11 | } 12 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/BaseWXActivity.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v7.app.AppCompatActivity; 7 | 8 | import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler; 9 | 10 | /** 11 | * @author: wuchao 12 | * @date: 2017/12/28 22:51 13 | * @desciption: 14 | */ 15 | 16 | public abstract class BaseWXActivity extends AppCompatActivity implements IWXAPIEventHandler { 17 | 18 | @Override 19 | protected void onCreate(@Nullable Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | //这个必须写在onCreate()中 22 | LatteWeChat.getInstance().getWXAPI().handleIntent(getIntent(), this); 23 | } 24 | 25 | @Override 26 | protected void onNewIntent(Intent intent) { 27 | super.onNewIntent(intent); 28 | setIntent(intent); 29 | LatteWeChat.getInstance().getWXAPI().handleIntent(getIntent(), this); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/BaseWXPayEntryActivity.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat; 2 | 3 | import com.tencent.mm.opensdk.constants.ConstantsAPI; 4 | import com.tencent.mm.opensdk.modelbase.BaseResp; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2018/1/1 21:32 9 | * @desciption: 10 | */ 11 | 12 | public abstract class BaseWXPayEntryActivity extends BaseWXActivity { 13 | 14 | private static final int WX_PAY_SUCCESS = 0; 15 | private static final int WX_PAY_FAIL = -1; 16 | private static final int WX_PAY_CANCEL = -2; 17 | 18 | protected abstract void onPaySuccess(); 19 | 20 | protected abstract void onPayFail(); 21 | 22 | protected abstract void onPayCancel(); 23 | 24 | @Override 25 | public void onResp(BaseResp baseResp) { 26 | if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) { 27 | switch (baseResp.errCode) { 28 | case WX_PAY_SUCCESS: 29 | onPaySuccess(); 30 | break; 31 | case WX_PAY_FAIL: 32 | onPayFail(); 33 | break; 34 | case WX_PAY_CANCEL: 35 | onPayCancel(); 36 | break; 37 | default: 38 | break; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/LatteWeChat.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat; 2 | 3 | import android.app.Activity; 4 | 5 | import com.tencent.mm.opensdk.modelmsg.SendAuth; 6 | import com.tencent.mm.opensdk.openapi.IWXAPI; 7 | import com.tencent.mm.opensdk.openapi.WXAPIFactory; 8 | import com.wuchao.latte.app.ConfigKeys; 9 | import com.wuchao.latte.app.Latte; 10 | import com.wuchao.latte.wechat.callbacks.IWeChatSignInCallback; 11 | 12 | /** 13 | * @author: wuchao 14 | * @date: 2017/12/28 22:32 15 | * @desciption: 16 | */ 17 | 18 | public class LatteWeChat { 19 | public static final String APP_ID = Latte.getConfiguration(ConfigKeys.WE_CHAT_APP_ID); 20 | public static final String APP_SECRET = Latte.getConfiguration(ConfigKeys.WE_CHAT_APP_SECRET); 21 | private final IWXAPI WXAPI; 22 | 23 | private IWeChatSignInCallback mSignInCallback; 24 | 25 | private static final class Holder { 26 | private static final LatteWeChat INSTANCE = new LatteWeChat(); 27 | } 28 | 29 | public static LatteWeChat getInstance() { 30 | return Holder.INSTANCE; 31 | } 32 | 33 | private LatteWeChat() { 34 | final Activity activity = Latte.getConfiguration(ConfigKeys.ACTIVITY); 35 | WXAPI = WXAPIFactory.createWXAPI(activity, APP_ID, true); 36 | WXAPI.registerApp(APP_ID); 37 | } 38 | 39 | public final IWXAPI getWXAPI() { 40 | return WXAPI; 41 | } 42 | 43 | public LatteWeChat onSignSuccess(IWeChatSignInCallback callback) { 44 | this.mSignInCallback = callback; 45 | return this; 46 | } 47 | 48 | public IWeChatSignInCallback getSignInCallback() { 49 | return mSignInCallback; 50 | } 51 | 52 | public final void signIn() { 53 | final SendAuth.Req req = new SendAuth.Req(); 54 | //应用授权作用域,如获取用户个人信息则填写 55 | req.scope = "snsapi_userinfo"; 56 | //用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击), 57 | // 建议第三方带上该参数,可设置为简单的随机数加session进行校验 58 | req.state = "wechat_sdk_demo_test"; 59 | WXAPI.sendReq(req); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/callbacks/IWeChatSignInCallback.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat.callbacks; 2 | 3 | /** 4 | * @author: wuchao 5 | * @date: 2017/12/29 21:15 6 | * @desciption: 7 | */ 8 | 9 | public interface IWeChatSignInCallback { 10 | void onSignInSuccess(String userInfo); 11 | } 12 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/templates/AppRegisterTemplate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat.templates; 2 | 3 | import com.wuchao.latte.activitys.ProxyActivity; 4 | import com.wuchao.latte.delegates.LatteDelegate; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2017/12/27 23:04 9 | * @desciption: 10 | */ 11 | 12 | public class AppRegisterTemplate extends ProxyActivity{ 13 | @Override 14 | public LatteDelegate setRootDelegate() { 15 | return null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/templates/WXEntryTemplate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat.templates; 2 | 3 | import com.wuchao.latte.wechat.BaseWXEntryActivity; 4 | import com.wuchao.latte.wechat.LatteWeChat; 5 | 6 | /** 7 | * @author: wuchao 8 | * @date: 2017/12/27 23:03 9 | * @desciption: 10 | */ 11 | 12 | public class WXEntryTemplate extends BaseWXEntryActivity { 13 | 14 | @Override 15 | protected void onResume() { 16 | super.onResume(); 17 | finish(); 18 | overridePendingTransition(0, 0); 19 | } 20 | 21 | @Override 22 | protected void onSignInSuccess(String userInfo) { 23 | LatteWeChat.getInstance().getSignInCallback().onSignInSuccess(userInfo); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /latte-core/src/main/java/com/wuchao/latte/wechat/templates/WXPayEntryTemplate.java: -------------------------------------------------------------------------------- 1 | package com.wuchao.latte.wechat.templates; 2 | 3 | import android.widget.Toast; 4 | 5 | import com.tencent.mm.opensdk.modelbase.BaseReq; 6 | import com.wuchao.latte.wechat.BaseWXPayEntryActivity; 7 | 8 | /** 9 | * @author: wuchao 10 | * @date: 2017/12/27 23:04 11 | * @desciption: 12 | */ 13 | 14 | public class WXPayEntryTemplate extends BaseWXPayEntryActivity { 15 | 16 | @Override 17 | protected void onPaySuccess() { 18 | Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show(); 19 | finish(); 20 | overridePendingTransition(0, 0); 21 | } 22 | 23 | @Override 24 | protected void onPayFail() { 25 | Toast.makeText(this, "支付失败", Toast.LENGTH_LONG).show(); 26 | finish(); 27 | overridePendingTransition(0, 0); 28 | } 29 | 30 | @Override 31 | protected void onPayCancel() { 32 | Toast.makeText(this, "支付取消", Toast.LENGTH_LONG).show(); 33 | finish(); 34 | overridePendingTransition(0, 0); 35 | } 36 | 37 | @Override 38 | public void onReq(BaseReq baseReq) { 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /latte-core/src/main/res/anim/push_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | -------------------------------------------------------------------------------- /latte-core/src/main/res/anim/push_bottom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | -------------------------------------------------------------------------------- /latte-core/src/main/res/drawable/border_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /latte-core/src/main/res/drawable/btn_border.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /latte-core/src/main/res/drawable/btn_border_nativephoto.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /latte-core/src/main/res/drawable/btn_border_takephoto.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /latte-core/src/main/res/drawable/dot_focus.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /latte-core/src/main/res/drawable/dot_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /latte-core/src/main/res/layout/bottom_item_icon_text_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 26 | 27 | -------------------------------------------------------------------------------- /latte-core/src/main/res/layout/delegate_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 19 | 20 | -------------------------------------------------------------------------------- /latte-core/src/main/res/layout/dialog_image_click_panel.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 |