├── .gitignore
├── MvvmModulePatternSample.zip
├── README.md
├── app
├── .gitignore
├── build.gradle
├── mvvm.jks
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mou
│ │ └── mvvmmodule
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── mou
│ │ │ └── mvvmmodule
│ │ │ ├── core
│ │ │ └── App.kt
│ │ │ ├── di
│ │ │ ├── component
│ │ │ │ └── AppComponent.kt
│ │ │ ├── module
│ │ │ │ ├── ActivityModule.kt
│ │ │ │ ├── AppModule.kt
│ │ │ │ └── ViewModelModule.kt
│ │ │ └── mvvm
│ │ │ │ ├── bean
│ │ │ │ └── ArticleBean.kt
│ │ │ │ ├── model
│ │ │ │ └── ApiService.kt
│ │ │ │ ├── view
│ │ │ │ └── MainActivity.kt
│ │ │ │ └── viewmodel
│ │ │ │ └── MainViewModel.kt
│ │ │ └── util
│ │ │ ├── AppUtils.java
│ │ │ └── KtAppUtils.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.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
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── mou
│ └── mvvmmodule
│ └── ExampleUnitTest.kt
├── build.gradle
├── component_build.gradle
├── config.gradle
├── config_build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
├── a.jpg
├── b.jpg
├── c.jpg
├── e.jpg
└── logo.jpg
├── lib_basemvvm
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mou
│ │ └── basemvvm
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── mou
│ │ │ └── basemvvm
│ │ │ ├── android
│ │ │ ├── FactoryModule.kt
│ │ │ └── ViewModelKey.kt
│ │ │ ├── base
│ │ │ ├── BaseActivity.kt
│ │ │ ├── BaseApplication.kt
│ │ │ ├── BaseFragment.kt
│ │ │ ├── BaseViewModel.kt
│ │ │ ├── IActivity.kt
│ │ │ ├── IView.kt
│ │ │ └── ViewModelFactory.kt
│ │ │ ├── helper
│ │ │ ├── annotation
│ │ │ │ ├── PageStateType.java
│ │ │ │ └── RefreshType.java
│ │ │ ├── extens
│ │ │ │ ├── BaseBinds.kt
│ │ │ │ ├── ContextExtens.kt
│ │ │ │ ├── ObservableItemField.kt
│ │ │ │ └── RxJavaExtens.kt
│ │ │ ├── listener
│ │ │ │ ├── ClickPresenter.kt
│ │ │ │ └── RefreshPresenter.kt
│ │ │ └── network
│ │ │ │ ├── ApiException.kt
│ │ │ │ ├── EmptyException.kt
│ │ │ │ ├── NetInterceptor.kt
│ │ │ │ ├── NetMgr.kt
│ │ │ │ ├── NetProvider.kt
│ │ │ │ ├── NullStringToEmptyAdapterFactory.kt
│ │ │ │ └── RequestHandler.kt
│ │ │ ├── integration
│ │ │ ├── AppDelegate.kt
│ │ │ ├── AppLifeCycles.kt
│ │ │ ├── ConfigModule.kt
│ │ │ └── ManifestParser.kt
│ │ │ └── widget
│ │ │ ├── LoadDialog.kt
│ │ │ └── dialog
│ │ │ ├── AlertController.kt
│ │ │ ├── CommonDialog.kt
│ │ │ ├── DialogHelper.kt
│ │ │ └── DialogViewHelper.kt
│ └── res
│ │ ├── anim
│ │ ├── dialog_from_bottom_anim_in.xml
│ │ ├── dialog_from_bottom_anim_out.xml
│ │ ├── dialog_scale_anim_in.xml
│ │ └── dialog_scale_anim_out.xml
│ │ ├── layout
│ │ └── public_dialog_load.xml
│ │ └── values
│ │ ├── strings.xml
│ │ └── style.xml
│ └── test
│ └── java
│ └── com
│ └── mou
│ └── basemvvm
│ └── ExampleUnitTest.java
├── lib_common
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── fortunes
│ │ └── commonsdk
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── fortunes
│ │ │ └── commonsdk
│ │ │ ├── bean
│ │ │ └── UserInfoBean.kt
│ │ │ ├── binds
│ │ │ ├── NormalBinds.kt
│ │ │ └── NormalExtens.kt
│ │ │ ├── core
│ │ │ ├── ActivityLifecycleCallbacksImpl.kt
│ │ │ ├── ApplicationLifeCyclesImpl.kt
│ │ │ ├── FragmentLifecycleCallbacksImpl.kt
│ │ │ ├── GlobalConfiguration.kt
│ │ │ └── RouterConstants.kt
│ │ │ ├── inter
│ │ │ └── MyTextChangeListner.kt
│ │ │ ├── network
│ │ │ ├── HttpException.kt
│ │ │ ├── HttpStatusConstants.kt
│ │ │ ├── HttpUrlConstants.kt
│ │ │ ├── RxHttpExtens.kt
│ │ │ ├── api
│ │ │ │ ├── BaseApiService.kt
│ │ │ │ └── BaseApiServiceManager.kt
│ │ │ ├── bean
│ │ │ │ └── BaseBean.kt
│ │ │ └── provider
│ │ │ │ ├── BaseNetProvider.kt
│ │ │ │ └── NoHeaderNetProvider.kt
│ │ │ ├── utils
│ │ │ ├── HideKeyBoardUtil.kt
│ │ │ ├── ImageUtils.kt
│ │ │ ├── MD5.java
│ │ │ ├── MyToast.kt
│ │ │ ├── NavigationUtils.kt
│ │ │ ├── RxBusUtils.kt
│ │ │ ├── UniqueIdUtils.java
│ │ │ ├── myStartActivity.kt
│ │ │ ├── perimission
│ │ │ │ └── EasyPermissionHelper.kt
│ │ │ └── sp
│ │ │ │ └── EasySharedPreferences.kt
│ │ │ └── view
│ │ │ ├── NoScrollViewPager.kt
│ │ │ ├── filter
│ │ │ ├── ChineseFilter.kt
│ │ │ └── PhoneFilter.kt
│ │ │ ├── photoviewer
│ │ │ ├── BaseLazyFragment.kt
│ │ │ ├── OnLongClickListener.kt
│ │ │ ├── PhotoViewer.kt
│ │ │ ├── PhotoViewerFragment.kt
│ │ │ ├── PhotoViewerPagerAdapter.kt
│ │ │ ├── Utils.kt
│ │ │ ├── ViewPagerFixed.kt
│ │ │ ├── WrapperView.kt
│ │ │ └── photoview
│ │ │ │ ├── Compat.java
│ │ │ │ ├── CustomGestureDetector.java
│ │ │ │ ├── OnGestureListener.java
│ │ │ │ ├── OnMatrixChangedListener.java
│ │ │ │ ├── OnOutsidePhotoTapListener.java
│ │ │ │ ├── OnPhotoTapListener.java
│ │ │ │ ├── OnScaleChangedListener.java
│ │ │ │ ├── OnSingleFlingListener.java
│ │ │ │ ├── OnViewDragListener.java
│ │ │ │ ├── OnViewFingerUpListener.java
│ │ │ │ ├── OnViewTapListener.java
│ │ │ │ ├── PhotoView.java
│ │ │ │ ├── PhotoViewAttacher.java
│ │ │ │ └── Util.java
│ │ │ ├── statusview
│ │ │ └── MultipleStatusView.kt
│ │ │ └── toolbar
│ │ │ └── MyToolBarLayout.kt
│ └── res
│ │ ├── anim
│ │ ├── public_bottomhide.xml
│ │ ├── public_bottomshow.xml
│ │ ├── public_centerhide.xml
│ │ ├── public_centershow.xml
│ │ ├── public_shake_anim.xml
│ │ └── public_shake_cricle.xml
│ │ ├── color
│ │ └── public_text_gray_color.xml
│ │ ├── drawable
│ │ ├── public_login_btn_style.xml
│ │ ├── public_no_selected_dot.xml
│ │ └── public_selected_dot.xml
│ │ ├── layout
│ │ ├── public_activity_photoviewer.xml
│ │ ├── public_dialog_list_item.xml
│ │ ├── public_item_picture.xml
│ │ ├── public_layout_holder.xml
│ │ ├── public_layout_toolbar.xml
│ │ ├── public_status_empty_view.xml
│ │ ├── public_status_error_view.xml
│ │ ├── public_status_loading_view.xml
│ │ ├── public_status_no_network_view.xml
│ │ └── public_title_bar.xml
│ │ ├── mipmap-hdpi
│ │ └── public_ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── public_ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── public_ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ ├── public_back_icon.png
│ │ ├── public_close_icon.png
│ │ ├── public_dialog_close.png
│ │ ├── public_finger_dialog.png
│ │ ├── public_ic_launcher.png
│ │ ├── public_icon_arrow_right.png
│ │ ├── public_icon_back.png
│ │ ├── public_icon_call.png
│ │ ├── public_icon_close.png
│ │ ├── public_icon_complete.png
│ │ ├── public_icon_fail.png
│ │ ├── public_icon_location.png
│ │ ├── public_icon_return.png
│ │ ├── public_icon_search.png
│ │ ├── public_icon_underway.png
│ │ ├── public_icon_wait.png
│ │ ├── public_operator_close.png
│ │ ├── public_status_empty.png
│ │ └── public_status_network.png
│ │ ├── mipmap-xxxhdpi
│ │ └── public_ic_launcher.png
│ │ ├── values
│ │ ├── attr.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── ids.xml
│ │ ├── strings.xml
│ │ ├── styles.xml
│ │ └── view_style.xml
│ │ └── xml
│ │ ├── file_paths_public.xml
│ │ └── network_security_config.xml
│ └── test
│ └── java
│ └── com
│ └── fortunes
│ └── commonsdk
│ └── ExampleUnitTest.java
├── module_login
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mou
│ │ └── login
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── debug
│ │ └── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── mou
│ │ │ └── login
│ │ │ ├── core
│ │ │ ├── App.kt
│ │ │ └── GlobalConfiguration.kt
│ │ │ ├── di
│ │ │ ├── component
│ │ │ │ └── AppComponent.kt
│ │ │ └── module
│ │ │ │ ├── ActivityModule.kt
│ │ │ │ ├── AppModule.kt
│ │ │ │ ├── FragmentModule.kt
│ │ │ │ └── ViewModelModule.kt
│ │ │ └── mvvm
│ │ │ ├── model
│ │ │ ├── data
│ │ │ │ └── LoginBean.kt
│ │ │ └── repository
│ │ │ │ └── ApiService.kt
│ │ │ ├── view
│ │ │ └── LoginActivity.kt
│ │ │ └── viewmodel
│ │ │ └── LoginViewModel.kt
│ ├── release
│ │ └── AndroidManifest.xml
│ └── res
│ │ ├── layout
│ │ └── login_activity_login.xml
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── mou
│ └── login
│ └── ExampleUnitTest.java
├── module_mine
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── mou
│ │ └── mine
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── debug
│ │ └── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── mou
│ │ │ └── mine
│ │ │ ├── core
│ │ │ ├── App.kt
│ │ │ └── GlobalConfiguration.kt
│ │ │ ├── di
│ │ │ ├── component
│ │ │ │ └── AppComponent.kt
│ │ │ └── module
│ │ │ │ ├── ActivityModule.kt
│ │ │ │ ├── AppModule.kt
│ │ │ │ ├── FragmentModule.kt
│ │ │ │ └── ViewModelModule.kt
│ │ │ └── mvvm
│ │ │ ├── model
│ │ │ ├── data
│ │ │ │ └── mineBean.kt
│ │ │ └── repository
│ │ │ │ └── ApiService.kt
│ │ │ ├── view
│ │ │ └── MineActivity.kt
│ │ │ └── viewmodel
│ │ │ └── MineViewModel.kt
│ ├── release
│ │ └── AndroidManifest.xml
│ └── res
│ │ ├── layout
│ │ ├── mine_activity_mine.xml
│ │ └── mine_my_item_order.xml
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── mou
│ └── mine
│ └── ExampleUnitTest.java
├── mvvm.jks
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | /.idea
15 |
--------------------------------------------------------------------------------
/MvvmModulePatternSample.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/MvvmModulePatternSample.zip
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 | ##### 主要技术点
5 |
6 | 1. [**Kotlin**](https://www.kotlincn.net/)
7 | 2. [**MVVM**](https://github.com/Dawish/GoogleArchitectureDemo)
8 | 3. [**Databinding**](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0811/3290.html)
9 | 4. [**Arouter路由**](https://github.com/alibaba/ARouter)
10 | 5. [**Dagger依赖注入**](https://dagger.dev/)
11 | 6. [**Rxjava**](https://github.com/ReactiveX/RxJava)
12 | 7. [**Retrofit**](http://square.github.io/retrofit/)
13 |
14 | #### 项目介绍
15 | [kotlin版本组件化+mvvm项目架构](https://blog.csdn.net/villa_mou/article/details/91862507 "标题")
16 |
17 |
18 | #### 分支
19 |
20 | * master=>有dagger的分支
21 | * noDagger=>去掉dagger的分支
22 | * noDataBinding=>去掉DataBinding和dagger的分支
23 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply from: "../config_build.gradle"
3 |
4 | android {
5 | defaultConfig {
6 | applicationId "com.mou.mvvmmodule"
7 | }
8 |
9 | flavorDimensions "verison"
10 | productFlavors {
11 | //打包assembleVersionDevDebug
12 | versionDev{
13 | dimension "verison"
14 | }
15 | //gradlew clean assembleVersionTestDebug
16 | versionTest {
17 | dimension "verison"
18 | }
19 | // gradlew clean assembleVersionOnlineRelease
20 | versionOnline{
21 | dimension "verison"
22 | }
23 | }
24 |
25 | buildTypes {
26 | release {
27 | minifyEnabled false
28 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
29 | }
30 | }
31 | }
32 |
33 | dependencies {
34 | if (!isBuildModule.toBoolean()) {
35 | implementation project(':module_login')
36 | implementation project(':module_mine')
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/mvvm.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/mvvm.jks
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/mou/mvvmmodule/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.mou.mvvmmodule", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/core/App.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.core
2 |
3 | import com.mou.basemvvm.base.BaseApplication
4 | import com.mou.mvvmmodule.di.component.DaggerAppComponent
5 |
6 |
7 | class App : BaseApplication() {
8 | override fun injectComponent() {
9 | DaggerAppComponent.builder().application(this).build().inject(this)
10 | }
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/component/AppComponent.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.component
2 |
3 | import android.app.Application
4 | import com.mou.basemvvm.android.FactoryModule
5 | import com.mou.mvvmmodule.core.App
6 | import com.mou.mvvmmodule.di.module.AppModule
7 | import dagger.BindsInstance
8 | import dagger.Component
9 | import dagger.android.support.AndroidSupportInjectionModule
10 | import javax.inject.Singleton
11 |
12 |
13 | @Singleton
14 | @Component(
15 | modules = [
16 | AndroidSupportInjectionModule::class,
17 | FactoryModule::class,
18 | AppModule::class,//app模块
19 | com.mou.login.di.module.AppModule::class,//添加登录模块组件
20 | com.mou.mine.di.module.AppModule::class//添加个人中心模块
21 | ]
22 | )
23 | interface AppComponent {
24 | @Component.Builder
25 | interface Builder {
26 | @BindsInstance
27 | fun application(application: Application): Builder
28 |
29 | fun build(): AppComponent
30 | }
31 |
32 | fun inject(application: App)
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/module/ActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.module
2 |
3 | import com.mou.mvvmmodule.di.mvvm.view.MainActivity
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 |
8 |
9 | @Module
10 | abstract class ActivityModule {
11 | @ContributesAndroidInjector
12 | abstract fun contributeMainActivity(): MainActivity
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/module/AppModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.module
2 |
3 | import android.app.Application
4 | import com.fortunes.commonsdk.network.HttpUrlConstants
5 | import com.fortunes.commonsdk.network.provider.BaseNetProvider
6 | import com.mou.basemvvm.helper.network.NetMgr
7 | import com.mou.mvvmmodule.di.mvvm.model.ApiService
8 | import dagger.Module
9 | import dagger.Provides
10 | import javax.inject.Singleton
11 |
12 |
13 |
14 | @Module(includes = [
15 | ActivityModule::class,
16 | ViewModelModule::class])
17 | class AppModule {
18 | @Provides
19 | @Singleton
20 | fun provideService(application: Application) = NetMgr.getRetrofit(HttpUrlConstants.getBaseUrl(),
21 | BaseNetProvider(application)
22 | ).create(
23 | ApiService::class.java)!!
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/module/ViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.module
2 |
3 | import androidx.lifecycle.ViewModel
4 | import com.mou.basemvvm.android.ViewModelKey
5 | import com.mou.mvvmmodule.di.mvvm.viewmodel.MainViewModel
6 | import dagger.Binds
7 | import dagger.Module
8 | import dagger.multibindings.IntoMap
9 |
10 |
11 |
12 | @Module
13 | abstract class ViewModelModule {
14 |
15 | @Binds
16 | @IntoMap
17 | @ViewModelKey(MainViewModel::class)
18 | abstract fun bindMainViewModel(viewModel: MainViewModel): ViewModel
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/mvvm/bean/ArticleBean.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.mvvm.bean
2 |
3 | /**
4 | * @FileName: ArticleBean.java
5 | * @author: villa_mou
6 | * @date: 04-14:43
7 | * @version V1.0 <描述当前版本功能>
8 | * @desc
9 | */
10 |
11 |
12 | data class ArticleBean(
13 | val curPage: Int,
14 | val datas: List,
15 | val offset: Int,
16 | val over: Boolean,
17 | val pageCount: Int,
18 | val size: Int,
19 | val total: Int
20 | )
21 |
22 | data class ArticleData(
23 | val apkLink: String,
24 | val author: String,
25 | val chapterId: Int,
26 | val chapterName: String,
27 | val collect: Boolean,
28 | val courseId: Int,
29 | val desc: String,
30 | val envelopePic: String,
31 | val fresh: Boolean,
32 | val id: Int,
33 | val link: String,
34 | val niceDate: String,
35 | val origin: String,
36 | val prefix: String,
37 | val projectLink: String,
38 | val publishTime: Long,
39 | val superChapterId: Int,
40 | val superChapterName: String,
41 | val tags: List,
42 | val title: String,
43 | val type: Int,
44 | val userId: Int,
45 | val visible: Int,
46 | val zan: Int
47 | )
48 |
49 | data class Tag(
50 | val name: String,
51 | val url: String
52 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/mvvm/model/ApiService.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.mvvm.model
2 |
3 | import com.fortunes.commonsdk.network.bean.BaseBean
4 | import com.mou.mvvmmodule.di.mvvm.bean.ArticleBean
5 | import io.reactivex.Single
6 | import retrofit2.http.GET
7 |
8 | interface ApiService {
9 |
10 |
11 | /**
12 | * 判断是否上线
13 | */
14 | @GET("article/list/1/json")
15 | fun getArticle(): Single>
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/mvvm/view/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.mvvm.view
2 |
3 | import com.alibaba.android.arouter.facade.annotation.Route
4 | import com.fortunes.commonsdk.core.RouterConstants
5 | import com.fortunes.commonsdk.network.onHttpSubscribeNoToast
6 | import com.fortunes.commonsdk.utils.NavigationUtils
7 | import com.mou.basemvvm.base.BaseActivity
8 | import com.mou.basemvvm.helper.extens.bindDialogOrLifeCycle
9 | import com.mou.basemvvm.helper.extens.toast
10 | import com.mou.mvvmmodule.R
11 | import com.mou.mvvmmodule.databinding.ActivityMainBinding
12 | import com.mou.mvvmmodule.di.mvvm.viewmodel.MainViewModel
13 | import dagger.android.DispatchingAndroidInjector
14 | import dagger.android.support.HasSupportFragmentInjector
15 | import kotlinx.android.synthetic.main.activity_main.*
16 | import javax.inject.Inject
17 |
18 |
19 | @Route(path = RouterConstants.MAIN_ACTIVITY)
20 | class MainActivity : BaseActivity() {
21 | override fun getLayoutId() = R.layout.activity_main
22 | private val mViewModel by lazy {
23 | createVM()
24 | }
25 |
26 | override fun initView() {
27 | //设置viewModel
28 | mBinding.apply {
29 | vm=mViewModel
30 | }
31 | btn.setOnClickListener {
32 | mViewModel
33 | .getArticle()
34 | .bindDialogOrLifeCycle(this)
35 | .onHttpSubscribeNoToast(this) {
36 | toast("成功")
37 | }
38 | }
39 | btn_login.setOnClickListener {
40 | NavigationUtils.goLoginActivity()
41 | }
42 |
43 | btn_mine.setOnClickListener {
44 | NavigationUtils.goMineActivity()
45 | }
46 | }
47 |
48 | override fun initData() {
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/mou/mvvmmodule/di/mvvm/viewmodel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule.di.mvvm.viewmodel
2 |
3 | import com.fortunes.commonsdk.network.bean.BaseBean
4 | import com.mou.basemvvm.base.BaseViewModel
5 | import com.mou.basemvvm.helper.extens.ObservableItemField
6 | import com.mou.basemvvm.helper.extens.async
7 | import com.mou.mvvmmodule.di.mvvm.bean.ArticleBean
8 | import com.mou.mvvmmodule.di.mvvm.model.ApiService
9 | import io.reactivex.Single
10 | import timber.log.Timber
11 | import javax.inject.Inject
12 |
13 |
14 | class MainViewModel @Inject constructor(private val apiService: ApiService) : BaseViewModel() {
15 | val chapterName = ObservableItemField()
16 | val link = ObservableItemField()
17 |
18 | fun getArticle(): Single> {
19 | return apiService
20 | .getArticle()
21 | .async()
22 | .doOnSuccess {
23 | chapterName.set(it.data.datas[0].chapterName)
24 | link.set(it.data.datas[0].link)
25 | }
26 | .doOnError {
27 | Timber.d("doOnError")
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
14 |
19 |
20 |
25 |
30 |
31 |
35 |
41 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #D81B60
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MvvmModulePatternSample
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/mou/mvvmmodule/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mvvmmodule
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "config.gradle"
2 | buildscript {
3 | ext.kotlin_version = '1.4.10'
4 | repositories {
5 | google()
6 | jcenter()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.2.2'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | // flatDir {
17 | // dirs project(':module_authentication').file('libs')
18 | // dirs project(':module_home').file('libs')
19 | // dirs project(':mockhome').file('libs')
20 | // }
21 | google()
22 | jcenter()
23 | maven { url "https://jitpack.io" }
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/component_build.gradle:
--------------------------------------------------------------------------------
1 | //通过isBuildModule这个变量来确定每个模块是单独运行还是以Library的形式加载到整个App
2 | if (isBuildModule.toBoolean()) {
3 | apply plugin: 'com.android.application'
4 | } else {
5 | apply plugin: 'com.android.library'
6 | }
7 | apply from: "../config_build.gradle"
8 |
9 | android {
10 | //这里进行设置使用单独运行还是合并运行的Manifest.xml
11 | sourceSets {
12 | main {
13 | jniLibs.srcDirs = ['libs']
14 | if (isBuildModule.toBoolean()) {
15 | manifest.srcFile 'src/main/debug/AndroidManifest.xml'
16 | } else {
17 | manifest.srcFile 'src/main/release/AndroidManifest.xml'
18 | }
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | android.databinding.enableV2=true
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | # Kotlin code style for this project: "official" or "obsolete":
16 | # false ��������������Ŀ true ��ģ������
17 | isBuildModule=false
18 | android.useAndroidX=true
19 | android.enableJetifier=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 12 09:55:08 CST 2019
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-6.7.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/images/a.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/images/a.jpg
--------------------------------------------------------------------------------
/images/b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/images/b.jpg
--------------------------------------------------------------------------------
/images/c.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/images/c.jpg
--------------------------------------------------------------------------------
/images/e.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/images/e.jpg
--------------------------------------------------------------------------------
/images/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/images/logo.jpg
--------------------------------------------------------------------------------
/lib_basemvvm/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lib_basemvvm/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/androidTest/java/com/mou/basemvvm/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm;
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 | * Instrumented 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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.mou.basemvvm.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/android/FactoryModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.android
2 |
3 | import androidx.lifecycle.ViewModelProvider
4 | import com.mou.basemvvm.base.ViewModelFactory
5 | import dagger.Binds
6 | import dagger.Module
7 |
8 |
9 | @Module
10 | abstract class FactoryModule {
11 | @Binds
12 | abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
13 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/android/ViewModelKey.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.android
2 |
3 | import androidx.lifecycle.ViewModel
4 | import dagger.MapKey
5 | import kotlin.reflect.KClass
6 |
7 | /***
8 | *
9 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
10 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
11 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
12 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
13 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
14 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
15 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
16 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
17 | * ░ ░ ░ ░ ░
18 | *
19 | * Created by mou on 2018/8/20.
20 |
21 |
22 | * ViewModel通过Dagger注入的标识注解
23 | * 主要是为了区别不同的ViewModel
24 | */
25 |
26 | @MustBeDocumented
27 | @Target(
28 | AnnotationTarget.FUNCTION,
29 | AnnotationTarget.PROPERTY_GETTER,
30 | AnnotationTarget.PROPERTY_SETTER
31 | )
32 | @Retention(AnnotationRetention.RUNTIME)
33 | @MapKey
34 | annotation class ViewModelKey(val value: KClass)
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/base/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.base
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.databinding.DataBindingUtil
7 | import androidx.databinding.ViewDataBinding
8 | import androidx.lifecycle.ViewModel
9 | import androidx.lifecycle.ViewModelProvider
10 | import androidx.lifecycle.ViewModelProviders
11 | import com.mou.basemvvm.helper.listener.ClickPresenter
12 | import com.mou.basemvvm.widget.LoadDialog
13 | import com.noober.background.BackgroundLibrary
14 | import dagger.Lazy
15 | import dagger.android.AndroidInjection
16 | import javax.inject.Inject
17 |
18 | /***
19 | *
20 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
21 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
22 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
23 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
24 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
25 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
26 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
27 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
28 | * ░ ░ ░ ░ ░
29 | *
30 | * Created by mou on 2018/8/20.
31 | * Activity的父类
32 | */
33 |
34 | abstract class BaseActivity : AppCompatActivity(), IView, IActivity, ClickPresenter {
35 | protected lateinit var mBinding: B
36 |
37 | @Inject
38 | lateinit var factory: Lazy
39 |
40 | private val progressDialog: LoadDialog by lazy {
41 | LoadDialog.create(this)
42 | }
43 |
44 | override fun onCreate(savedInstanceState: Bundle?) {
45 | BackgroundLibrary.inject(this)
46 | AndroidInjection.inject(this)
47 | mBinding = DataBindingUtil.setContentView(this, getLayoutId())
48 | super.onCreate(savedInstanceState)
49 | mBinding.lifecycleOwner = this
50 | initView()
51 | initData()
52 | }
53 |
54 | inline fun < reified T : ViewModel> createVM(): T = ViewModelProviders.of(this, factory.get()).get(T::class.java)
55 |
56 |
57 | override fun onClick(v: View) {
58 |
59 | }
60 |
61 |
62 |
63 | /**
64 | * 显示loading框
65 | */
66 | override fun showLoading(message: String) {
67 | progressDialog.setMessage(message)
68 | progressDialog.show()
69 | }
70 |
71 | /**
72 | * 隐藏loading框
73 | */
74 | override fun hideLoading() {
75 | progressDialog.dismiss()
76 | }
77 |
78 | override fun onDestroy() {
79 | super.onDestroy()
80 | progressDialog.dismiss()
81 | }
82 |
83 |
84 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/base/BaseApplication.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.base
2 |
3 | import android.app.Activity
4 | import android.app.Application
5 | import android.content.Context
6 | import androidx.multidex.MultiDex
7 | import com.mou.basemvvm.integration.AppDelegate
8 | import dagger.android.AndroidInjector
9 | import dagger.android.DispatchingAndroidInjector
10 | import dagger.android.HasActivityInjector
11 | import javax.inject.Inject
12 |
13 |
14 | /***
15 | *
16 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
17 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
18 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
19 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
20 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
21 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
22 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
23 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
24 | * ░ ░ ░ ░ ░
25 | *
26 | * Created by mou on 2018/8/20.
27 |
28 |
29 | * 通用的Application
30 | */
31 |
32 | abstract class BaseApplication : Application() , HasActivityInjector {
33 | private var mAppDelegate: AppDelegate? = null
34 |
35 | companion object {
36 | private var instance: Application? = null
37 | fun instance() = instance ?: throw Throwable("instance 还未初始化完成")
38 | }
39 |
40 | @Inject
41 | lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector
42 |
43 | override fun activityInjector(): AndroidInjector = dispatchingAndroidInjector
44 |
45 | override fun attachBaseContext(base: Context) {
46 | super.attachBaseContext(base)
47 | MultiDex.install(this)
48 | injectComponent()
49 | if (mAppDelegate == null) {
50 | mAppDelegate = AppDelegate(base)
51 | }
52 | mAppDelegate?.attachBaseContext(base)
53 | }
54 |
55 | abstract fun injectComponent()
56 |
57 | override fun onCreate() {
58 | super.onCreate()
59 | instance = this
60 | mAppDelegate?.onCreate(this)
61 |
62 | }
63 |
64 | override fun onTerminate() {
65 | super.onTerminate()
66 | mAppDelegate?.onTerminate(this)
67 | }
68 |
69 |
70 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/base/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.base
2 |
3 | import android.annotation.SuppressLint
4 | import androidx.lifecycle.ViewModel
5 | import com.mou.basemvvm.helper.annotation.PageStateType
6 | import com.mou.basemvvm.helper.annotation.RefreshType
7 | import com.mou.basemvvm.helper.extens.ObservableItemField
8 | import timber.log.Timber
9 |
10 | /***
11 | *
12 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
13 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
14 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
15 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
16 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
17 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
18 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
19 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
20 | * ░ ░ ░ ░ ░
21 | *
22 | * Created by mou on 2018/8/20.
23 | * ViewModel的父类
24 | */
25 |
26 | abstract class BaseViewModel : ViewModel() {
27 | //页面状态
28 | @SuppressLint("SupportAnnotationUsage")
29 | @PageStateType
30 | val pageState = ObservableItemField()
31 | //刷新/加载更多状态
32 | @SuppressLint("SupportAnnotationUsage")
33 | @RefreshType
34 | val listState = ObservableItemField()
35 |
36 | init {
37 | pageState.set(PageStateType.NORMAL)
38 | listState.set(RefreshType.NORMAL)
39 | }
40 |
41 | override fun onCleared() {
42 | super.onCleared()
43 | Timber.i("${javaClass.simpleName}:onCleared()")
44 | }
45 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/base/IActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.base
2 |
3 | import androidx.annotation.LayoutRes
4 |
5 |
6 | /***
7 | *
8 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
9 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
10 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
11 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
12 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
13 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
14 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
15 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
16 | * ░ ░ ░ ░ ░
17 | *
18 | * Created by mou on 2018/8/20.
19 | * Activity/Fragment的接口
20 | */
21 |
22 | interface IActivity {
23 | @LayoutRes
24 | fun getLayoutId(): Int
25 |
26 | fun initView()
27 |
28 | fun initData()
29 |
30 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/base/IView.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.base
2 |
3 | import androidx.lifecycle.LifecycleOwner
4 |
5 |
6 | /***
7 | * You may think you know what the following code does.
8 | * But you dont. Trust me.
9 | * Fiddle with it, and youll spend many a sleepless
10 | * night cursing the moment you thought youd be clever
11 | * enough to "optimize" the code below.
12 | * Now close this file and go play with something else.
13 | */
14 | /***
15 | *
16 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
17 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
18 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
19 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
20 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
21 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
22 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
23 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
24 | * ░ ░ ░ ░ ░
25 | *
26 | * Created by mou on 2018/12/3.
27 | * Activity/Fragment的接口
28 | */
29 | interface IView : LifecycleOwner {
30 | fun showLoading(message: String = "请稍后...")
31 |
32 | fun hideLoading()
33 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/base/ViewModelFactory.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.base
2 |
3 | import androidx.lifecycle.ViewModel
4 | import androidx.lifecycle.ViewModelProvider
5 | import javax.inject.Inject
6 | import javax.inject.Provider
7 |
8 | /***
9 | *
10 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
11 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
12 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
13 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
14 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
15 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
16 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
17 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
18 | * ░ ░ ░ ░ ░
19 | *
20 | * Created by mou on 2018/8/20.
21 | * ViewModel创建的工厂类
22 | */
23 |
24 | class ViewModelFactory @Inject constructor(private val creators: Map, @JvmSuppressWildcards Provider>) : ViewModelProvider.Factory {
25 | override fun create(modelClass: Class): T {
26 | val creator = creators[modelClass] ?: creators.entries.firstOrNull {
27 | modelClass.isAssignableFrom(it.key)
28 | }?.value ?: throw IllegalArgumentException("unknown model class $modelClass")
29 | try {
30 | @Suppress("UNCHECKED_CAST")
31 | return creator.get() as T
32 | } catch (e: Exception) {
33 | throw RuntimeException(e)
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/annotation/PageStateType.java:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.annotation;
2 |
3 | import java.lang.annotation.Retention;
4 | import java.lang.annotation.RetentionPolicy;
5 |
6 | import androidx.annotation.IntDef;
7 |
8 | import static com.mou.basemvvm.helper.annotation.PageStateType.CONTENT;
9 | import static com.mou.basemvvm.helper.annotation.PageStateType.EMPTY;
10 | import static com.mou.basemvvm.helper.annotation.PageStateType.ERROR;
11 | import static com.mou.basemvvm.helper.annotation.PageStateType.LOADING;
12 | import static com.mou.basemvvm.helper.annotation.PageStateType.NORMAL;
13 | import static com.mou.basemvvm.helper.annotation.PageStateType.NOWORK;
14 |
15 |
16 | /***
17 | *
18 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
19 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
20 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
21 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
22 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
23 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
24 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
25 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
26 | * ░ ░ ░ ░ ░
27 | *
28 | * Created by mou on 2018/8/20.
29 | * 页面状态标识类
30 | */
31 |
32 | @IntDef({LOADING, EMPTY, ERROR, NOWORK, NORMAL, CONTENT})
33 | @Retention(RetentionPolicy.SOURCE)
34 | public @interface PageStateType {
35 | int NOWORK = -4;
36 | //加载中
37 | int LOADING = -3;
38 | //暂无数据
39 | int EMPTY = -2;
40 | //加载失败
41 | int ERROR = -1;
42 | //初始化状态
43 | int NORMAL = 0;
44 | //显示内容布局
45 | int CONTENT = 1;
46 | }
47 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/annotation/RefreshType.java:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.annotation;
2 |
3 |
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 |
7 | import androidx.annotation.IntDef;
8 |
9 | import static com.mou.basemvvm.helper.annotation.RefreshType.LOADMORE;
10 | import static com.mou.basemvvm.helper.annotation.RefreshType.LOADMOREFAIL;
11 | import static com.mou.basemvvm.helper.annotation.RefreshType.NORMAL;
12 | import static com.mou.basemvvm.helper.annotation.RefreshType.NOTMORE;
13 | import static com.mou.basemvvm.helper.annotation.RefreshType.REFRESH;
14 | import static com.mou.basemvvm.helper.annotation.RefreshType.REFRESHFAIL;
15 |
16 |
17 | /***
18 | *
19 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
20 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
21 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
22 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
23 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
24 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
25 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
26 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
27 | * ░ ░ ░ ░ ░
28 | *
29 | * Created by mou on 2018/8/20.
30 | * 下拉刷新/上拉加载的标识类
31 | */
32 |
33 | @IntDef({REFRESH, LOADMORE, REFRESHFAIL, LOADMOREFAIL, NOTMORE, NORMAL})
34 | @Retention(RetentionPolicy.SOURCE)
35 | public @interface RefreshType {
36 | //下拉刷新结束
37 | int REFRESH = -5;
38 | //加载更多结束
39 | int LOADMORE = -4;
40 | //下拉刷新失败
41 | int REFRESHFAIL = -3;
42 | //加载更多失败
43 | int LOADMOREFAIL = -2;
44 | //没有更多数据
45 | int NOTMORE = -1;
46 | //初始化状态
47 | int NORMAL = 0;
48 | }
49 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/extens/BaseBinds.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.extens
2 |
3 | import android.view.View
4 | import androidx.databinding.BindingAdapter
5 |
6 | /***
7 | *
8 | * Created by mou on 2018/8/20.
9 | * 通用的bindingAdapter类
10 | */
11 |
12 | /**
13 | * view的显示隐藏
14 | * bind:visibility="@{true/false}"
15 | * true:显示
16 | * false:隐藏
17 | */
18 | @BindingAdapter(value = ["visibility"])
19 | fun bindVisibility(v: View, visibility: Boolean?) {
20 | v.visibility = if (visibility == true) View.VISIBLE else View.GONE
21 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/extens/ContextExtens.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.extens
2 |
3 | import android.content.Context
4 | import androidx.core.content.ContextCompat
5 | import android.widget.Toast
6 | import androidx.annotation.ColorRes
7 | import com.mou.basemvvm.base.BaseApplication
8 |
9 |
10 | /***
11 | * Created by mou on 2018/12/3.
12 | * Context的扩展类
13 | */
14 |
15 | /**
16 | * Context的扩展toast方法
17 | */
18 | fun Context.toast(msg: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
19 | if (msg.isEmpty()) return
20 | Toast.makeText(BaseApplication.instance(), msg, Toast.LENGTH_SHORT).show()
21 | }
22 |
23 | /**
24 | * Context的扩展获取color资源
25 | */
26 | fun Context.getCompactColor(@ColorRes colorRes: Int): Int = ContextCompat.getColor(this, colorRes)
27 |
28 | /**
29 | * Context的扩展dp转px
30 | */
31 | fun Context.dpTo2Px(dpValue: Int): Float {
32 | val scale = this.resources.displayMetrics.density//获得当前屏幕密度
33 | return dpValue * scale + 0.5f
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/extens/ObservableItemField.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.extens
2 |
3 | import androidx.lifecycle.MutableLiveData
4 |
5 |
6 | /***
7 | * You may think you know what the following code does.
8 | * But you dont. Trust me.
9 | * Fiddle with it, and youll spend many a sleepless
10 | * night cursing the moment you thought youd be clever
11 | * enough to "optimize" the code below.
12 | * Now close this file and go play with something else.
13 | */
14 | /***
15 | *
16 | * Created by mou on 2018/12/6.
17 | */
18 | class ObservableItemField : MutableLiveData() {
19 |
20 | fun set(value: T) {
21 | setValue(value)
22 | }
23 |
24 | fun get(): T? {
25 | return super.getValue()
26 | }
27 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/listener/ClickPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.listener
2 |
3 | import android.view.View
4 |
5 | /***
6 | *
7 | * Created by mou on 2018/8/20.
8 | * view的点击事件接口类
9 | */
10 |
11 | interface ClickPresenter : View.OnClickListener {
12 | override fun onClick(v: View)
13 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/listener/RefreshPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.listener
2 |
3 | /***
4 | *
5 | * Created by mou on 2018/8/20.
6 | * 下拉刷新/上拉加载的接口类
7 | */
8 |
9 | interface RefreshPresenter {
10 | /**
11 | * 加载数据
12 | * isRefresh:true 下拉刷新,false 上拉加载更多
13 | */
14 | fun loadData(isRefresh: Boolean)
15 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/network/ApiException.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.network
2 |
3 | import java.io.IOException
4 |
5 | /***
6 | *
7 | * Created by mou on 2018/8/20.
8 | * 网络请求错误异常类
9 | */
10 |
11 | open class ApiException(message: String) : IOException(message)
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/network/EmptyException.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.network
2 |
3 | import java.io.IOException
4 |
5 | /***
6 | * You may think you know what the following code does.
7 | * But you dont. Trust me.
8 | * Fiddle with it, and youll spend many a sleepless
9 | * night cursing the moment you thought youd be clever
10 | * enough to "optimize" the code below.
11 | * Now close this file and go play with something else.
12 | */
13 | /***
14 | *
15 | * Created by mou on 2018/9/21.
16 |
17 |
18 | * 暂无数据异常类
19 | */
20 | class EmptyException(message: String = "暂无数据") : IOException()
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/network/NetInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.network
2 |
3 | import okhttp3.Interceptor
4 | import okhttp3.Response
5 | import java.io.IOException
6 |
7 | /***
8 | * Created by mou on 2018/8/20.
9 | * 网络拦截器
10 | */
11 |
12 | class NetInterceptor(private val handler: RequestHandler?) : Interceptor {
13 | /**
14 | * 网络请求拦截方法
15 | */
16 | @Throws(IOException::class)
17 | override fun intercept(chain: Interceptor.Chain): Response {
18 | var request = chain.request()
19 | if (handler != null) {
20 | request = handler.onBeforeRequest(request, chain)
21 | }
22 | val response = chain.proceed(request)
23 | if (handler != null) {
24 | return handler.onAfterRequest(response, chain)
25 | }
26 |
27 | return response
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/network/NetProvider.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.network
2 |
3 | import okhttp3.CookieJar
4 | import okhttp3.Interceptor
5 | import okhttp3.OkHttpClient
6 |
7 | /***
8 | *
9 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
10 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
11 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
12 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
13 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
14 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
15 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
16 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
17 | * ░ ░ ░ ░ ░
18 | *
19 | * Created by mou on 2018/8/20.
20 |
21 |
22 | */
23 |
24 | interface NetProvider {
25 | /**
26 | * 添加网络请求拦截器
27 | */
28 | fun configInterceptors(): Array?
29 |
30 | /**
31 | * 添加https请求拦截器
32 | */
33 | fun configHttps(builder: OkHttpClient.Builder)
34 |
35 | /**
36 | * 添加cookie持久化拦截器
37 | */
38 | fun configCookie(): CookieJar?
39 |
40 | /**
41 | * 添加拦截器
42 | */
43 | fun configHandler(): RequestHandler
44 |
45 | /**
46 | * 链接超时时间
47 | */
48 | fun configConnectTimeoutSecs(): Long
49 |
50 | /**
51 | * 读取超时时间
52 | */
53 | fun configReadTimeoutSecs(): Long
54 |
55 | /**
56 | * 写入超时时间
57 | */
58 | fun configWriteTimeoutSecs(): Long
59 |
60 | /**
61 | * 是否开启log打印日志
62 | */
63 | fun configLogEnable(): Boolean
64 | }
65 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/network/NullStringToEmptyAdapterFactory.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.network
2 |
3 | import com.google.gson.Gson
4 | import com.google.gson.TypeAdapter
5 | import com.google.gson.TypeAdapterFactory
6 | import com.google.gson.reflect.TypeToken
7 | import com.google.gson.stream.JsonReader
8 | import com.google.gson.stream.JsonToken
9 | import com.google.gson.stream.JsonWriter
10 | import java.io.IOException
11 |
12 | /***
13 | * You may think you know what the following code does.
14 | * But you dont. Trust me.
15 | * Fiddle with it, and youll spend many a sleepless
16 | * night cursing the moment you thought youd be clever
17 | * enough to "optimize" the code below.
18 | * Now close this file and go play with something else.
19 | */
20 | /***
21 | *
22 | * Created by mou on 2019/1/2.
23 | */
24 | class NullStringToEmptyAdapterFactory : TypeAdapterFactory {
25 | override fun create(gson: Gson, type: TypeToken): TypeAdapter? {
26 | val rawType = type.rawType as Class
27 | return if (rawType != String::class.java) {
28 | null
29 | } else StringNullAdapter() as TypeAdapter
30 | }
31 | }
32 |
33 | internal class StringNullAdapter : TypeAdapter() {
34 | @Throws(IOException::class)
35 | override fun read(reader: JsonReader): String {
36 | if (reader.peek() == JsonToken.NULL) {
37 | reader.nextNull()
38 | return ""
39 | }
40 | return reader.nextString()
41 | }
42 |
43 | @Throws(IOException::class)
44 | override fun write(writer: JsonWriter, value: String?) {
45 | if (value == null) {
46 | writer.nullValue()
47 | return
48 | }
49 | writer.value(value)
50 | }
51 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/helper/network/RequestHandler.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.helper.network
2 |
3 | import okhttp3.Interceptor
4 | import okhttp3.Request
5 | import okhttp3.Response
6 | import java.io.IOException
7 |
8 | /***
9 | *
10 | * Created by mou on 2018/8/20.
11 | * 网络请求拦截器
12 | */
13 |
14 | interface RequestHandler {
15 | /**
16 | * 发起请求拦截方法
17 | */
18 | fun onBeforeRequest(request: Request, chain: Interceptor.Chain): Request
19 |
20 | /**
21 | * 请求结果拦截方法
22 | */
23 | @Throws(IOException::class)
24 | fun onAfterRequest(response: Response, chain: Interceptor.Chain): Response
25 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/integration/AppDelegate.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.integration
2 |
3 | import android.app.Activity
4 | import android.app.Application
5 | import android.content.Context
6 | import android.os.Bundle
7 | import androidx.fragment.app.FragmentActivity
8 | import androidx.fragment.app.FragmentManager
9 |
10 | /***
11 | *
12 | * Created by mou on 2018/8/20.
13 | * 关于Application/Activity/Fragment的生命周期处理类
14 | */
15 |
16 | class AppDelegate(context: Context) : AppLifeCycles {
17 | private var mApplication: Application? = null
18 | private var mModules: List? = null
19 | private var mAppLifeCycles: MutableList = arrayListOf()
20 | private var mActivityLifeCycles: MutableList = arrayListOf()
21 | private var mFragmentLifeCycles: MutableList = arrayListOf()
22 |
23 | override fun attachBaseContext(base: Context) {
24 | mAppLifeCycles.forEach {
25 | it.attachBaseContext(base)
26 | }
27 | }
28 |
29 | override fun onCreate(application: Application) {
30 | mApplication = application
31 | mApplication?.registerActivityLifecycleCallbacks(FragmentLifecycleCallbacks())
32 | mActivityLifeCycles.forEach {
33 | mApplication?.registerActivityLifecycleCallbacks(it)
34 | }
35 | mAppLifeCycles.forEach {
36 | if (mApplication != null) {
37 | it.onCreate(mApplication!!)
38 | }
39 | }
40 |
41 | }
42 |
43 | override fun onTerminate(application: Application) {
44 | mActivityLifeCycles.forEach {
45 | mApplication?.unregisterActivityLifecycleCallbacks(it)
46 | }
47 | mAppLifeCycles.forEach {
48 | if (mApplication != null) {
49 | it.onTerminate(mApplication!!)
50 | }
51 | }
52 | }
53 |
54 | private inner class FragmentLifecycleCallbacks : Application.ActivityLifecycleCallbacks {
55 | override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
56 | if (activity is FragmentActivity) {
57 | mFragmentLifeCycles.forEach {
58 | activity.supportFragmentManager
59 | .registerFragmentLifecycleCallbacks(it, true)
60 | }
61 | }
62 | }
63 |
64 | override fun onActivityPaused(activity: Activity?) {
65 | }
66 |
67 | override fun onActivityResumed(activity: Activity?) {
68 | }
69 |
70 | override fun onActivityStarted(activity: Activity?) {
71 | }
72 |
73 | override fun onActivityDestroyed(activity: Activity?) {
74 | }
75 |
76 | override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
77 | }
78 |
79 | override fun onActivityStopped(activity: Activity?) {
80 | }
81 |
82 | }
83 |
84 | init {
85 | mModules = ManifestParser(context).parse()
86 | mModules?.forEach {
87 | it.injectAppLifecycle(context, mAppLifeCycles)
88 | it.injectActivityLifecycle(context, mActivityLifeCycles)
89 | it.injectFragmentLifecycle(context, mFragmentLifeCycles)
90 | }
91 | }
92 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/integration/AppLifeCycles.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.integration
2 |
3 | import android.app.Application
4 | import android.content.Context
5 |
6 | /***
7 | *
8 | * Created by mou on 2018/8/20.
9 | * Application生命周期接口
10 | */
11 |
12 | interface AppLifeCycles {
13 |
14 | fun attachBaseContext(base: Context)
15 |
16 | fun onCreate(application: Application)
17 |
18 | fun onTerminate(application: Application)
19 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/integration/ConfigModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.integration
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import androidx.fragment.app.FragmentManager
6 |
7 | /***
8 | *
9 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
10 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
11 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
12 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
13 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
14 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
15 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
16 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
17 | * ░ ░ ░ ░ ░
18 | *
19 | * Created by mou on 2018/8/20.
20 | * 框架整体的生命周期注入类
21 | */
22 |
23 | interface ConfigModule {
24 | /**
25 | * 使用[AppLifeCycles]在Application的生命周期中注入一些操作
26 | */
27 | fun injectAppLifecycle(context: Context, lifeCycles: MutableList)
28 |
29 | /**
30 | * 使用[Application.ActivityLifecycleCallbacks]在Activity的生命周期中注入一些操作
31 | */
32 | fun injectActivityLifecycle(context: Context, lifeCycles: MutableList)
33 |
34 |
35 | /**
36 | * 使用[FragmentManager.FragmentLifecycleCallbacks]在Fragment的生命周期中注入一些操作
37 | */
38 | fun injectFragmentLifecycle(context: Context, lifeCycles: MutableList)
39 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/integration/ManifestParser.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.integration
2 |
3 | import android.content.Context
4 | import android.content.pm.PackageManager
5 | import java.util.*
6 |
7 | /***
8 | *
9 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
10 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
11 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
12 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
13 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
14 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
15 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
16 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
17 | * ░ ░ ░ ░ ░
18 | *
19 | * Created by mou on 2018/8/20.
20 | * 关于在Manifest中获取ConfigModule配置处理类
21 | */
22 |
23 | class ManifestParser constructor(val context: Context) {
24 | private val MODULE_VALUE = "ConfigModule"
25 |
26 | fun parse(): List {
27 | val modules = ArrayList()
28 | try {
29 | val appInfo = context.packageManager.getApplicationInfo(
30 | context.packageName, PackageManager.GET_META_DATA)
31 | if (appInfo.metaData != null) {
32 | for (key in appInfo.metaData.keySet()) {
33 | if (MODULE_VALUE == appInfo.metaData.get(key)) {
34 | modules.add(parseModule(key))
35 | }
36 | }
37 | }
38 | } catch (e: PackageManager.NameNotFoundException) {
39 | throw RuntimeException("Unable to find metadata to parse ConfigModule", e)
40 | }
41 |
42 | return modules
43 | }
44 |
45 | private fun parseModule(className: String): ConfigModule {
46 | val clazz: Class<*>
47 | try {
48 | clazz = Class.forName(className)
49 | } catch (e: ClassNotFoundException) {
50 | throw IllegalArgumentException("Unable to find ConfigModule implementation", e)
51 | }
52 |
53 | val module: Any
54 | try {
55 | module = clazz.newInstance()
56 | } catch (e: InstantiationException) {
57 | throw RuntimeException("Unable to instantiate ConfigModule implementation for $clazz", e)
58 | } catch (e: IllegalAccessException) {
59 | throw RuntimeException("Unable to instantiate ConfigModule implementation for $clazz", e)
60 | }
61 |
62 | if (module !is ConfigModule) {
63 | throw RuntimeException("Expected instanceof ConfigModule, but found: $module")
64 | }
65 | return module
66 | }
67 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/widget/LoadDialog.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.widget
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.view.LayoutInflater
6 | import android.widget.TextView
7 | import com.mou.basemvvm.widget.dialog.CommonDialog
8 | import com.mou.easymvvm.R
9 |
10 | /***
11 | * You may think you know what the following code does.
12 | * But you dont. Trust me.
13 | * Fiddle with it, and youll spend many a sleepless
14 | * night cursing the moment you thought youd be clever
15 | * enough to "optimize" the code below.
16 | * Now close this file and go play with something else.
17 | */
18 | /***
19 | *
20 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
21 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
22 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
23 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
24 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
25 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
26 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
27 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
28 | * ░ ░ ░ ░ ░
29 | *
30 | * Created by mou on 2018/12/22.
31 | */
32 | @SuppressLint("InflateParams")
33 | class LoadDialog private constructor(private val context: Context) {
34 | private val mCommonDialog by lazy {
35 | CommonDialog.Builder(context)
36 | .setContentView(contentView)
37 | .setCancelableOnTouchOutside(false)
38 | .create()
39 | }
40 |
41 | private val contentView by lazy {
42 | LayoutInflater.from(context).inflate(R.layout.public_dialog_load, null)
43 | }
44 |
45 | private val titleTv by lazy {
46 | contentView.findViewById(R.id.dialog_tv)
47 | }
48 |
49 | fun show() {
50 | if (mCommonDialog.isShowing) return
51 | mCommonDialog.show()
52 | }
53 |
54 | fun setMessage(message: String) {
55 | titleTv.text = message
56 | }
57 |
58 | fun dismiss() {
59 | if (!mCommonDialog.isShowing) return
60 | mCommonDialog.dismiss()
61 | }
62 |
63 | companion object {
64 | fun create(context: Context): LoadDialog {
65 | return LoadDialog(context)
66 | }
67 | }
68 | }
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/widget/dialog/DialogHelper.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.widget.dialog
2 |
3 | /***
4 | * You may think you know what the following code does.
5 | * But you dont. Trust me.
6 | * Fiddle with it, and youll spend many a sleepless
7 | * night cursing the moment you thought youd be clever
8 | * enough to "optimize" the code below.
9 | * Now close this file and go play with something else.
10 | */
11 |
12 |
13 | import androidx.appcompat.app.AlertDialog
14 | import com.blankj.utilcode.util.ActivityUtils
15 | import com.blankj.utilcode.util.PermissionUtils
16 | import com.mou.easymvvm.R
17 |
18 | /***
19 | *
20 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
21 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
22 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
23 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
24 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
25 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
26 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
27 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
28 | * ░ ░ ░ ░ ░
29 | *
30 | * Created by mou on 2018/11/16.
31 | * 关于用户权限的dialog
32 | */
33 | object DialogHelper {
34 |
35 | /**
36 | * tips:提示用户权限信息
37 | * 显示用户拒绝权限提示
38 | */
39 | fun showRationaleDialog(tips: String, shouldRequest: PermissionUtils.OnRationaleListener.ShouldRequest) {
40 | val topActivity = ActivityUtils.getTopActivity() ?: return
41 | AlertDialog.Builder(topActivity, R.style.BDAlertDialog)
42 | .setTitle("提示")
43 | .setMessage(tips)
44 | .setPositiveButton(android.R.string.ok) { _, _ ->
45 | //继续申请权限
46 | shouldRequest.again(true)
47 | }
48 | .setNegativeButton(android.R.string.cancel) { _, _ ->
49 | //取消权限申请
50 | shouldRequest.again(false)
51 | }
52 | .setCancelable(false)
53 | .create()
54 | .show()
55 |
56 | }
57 |
58 | /**
59 | * 打开系统设置弹窗
60 | */
61 | fun showOpenAppSettingDialog(tips: String) {
62 | val topActivity = ActivityUtils.getTopActivity() ?: return
63 | AlertDialog.Builder(topActivity, R.style.BDAlertDialog)
64 | .setTitle("提示")
65 | .setMessage(tips)
66 | .setPositiveButton(android.R.string.ok) { _, _ ->
67 | //跳转系统设置界面
68 | PermissionUtils.launchAppDetailsSettings()
69 | }
70 | .setNegativeButton(android.R.string.cancel) { _, _ -> }
71 | .setCancelable(false)
72 | .create()
73 | .show()
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/java/com/mou/basemvvm/widget/dialog/DialogViewHelper.kt:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm.widget.dialog
2 |
3 | import android.content.Context
4 | import android.util.SparseArray
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.widget.TextView
8 |
9 | import java.lang.ref.WeakReference
10 |
11 | /**
12 | * Created by mou on 2017/12/3.
13 | */
14 |
15 | internal class DialogViewHelper() {
16 | var contentView: View? = null
17 | private val mViews: SparseArray> = SparseArray()
18 |
19 | constructor(context: Context, layoutResId: Int) : this() {
20 | contentView = LayoutInflater.from(context).inflate(layoutResId, null)
21 | }
22 |
23 |
24 | /**
25 | * 设置文本
26 | *
27 | * @param viewId
28 | * @param text
29 | */
30 | fun setText(viewId: Int, text: CharSequence) {
31 | val tv = getView(viewId)
32 | if (tv != null) {
33 | tv.text = text
34 | }
35 | }
36 |
37 |
38 | @Suppress("UNCHECKED_CAST")
39 | fun getView(viewId: Int): T? {
40 | val viewReference = mViews.get(viewId)
41 | var view: View? = null
42 | if (viewReference != null) {
43 | view = viewReference.get()
44 | }
45 |
46 | if (view == null) {
47 | view = contentView!!.findViewById(viewId)
48 | if (view != null) {
49 | mViews.put(viewId, WeakReference(view))
50 | }
51 | }
52 | return view as T?
53 | }
54 |
55 | /**
56 | * 设置点击事件
57 | *
58 | * @param viewId
59 | * @param listener
60 | */
61 | fun setOnclickListener(viewId: Int, listener: View.OnClickListener) {
62 | val view = getView(viewId)
63 | view?.setOnClickListener(listener)
64 | }
65 |
66 | fun setGone(viewId: Int, visibility: Int) {
67 | val view = getView(viewId)
68 | if (view != null) {
69 | view.visibility = visibility
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/anim/dialog_from_bottom_anim_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/anim/dialog_from_bottom_anim_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/anim/dialog_scale_anim_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
20 |
29 |
34 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/anim/dialog_scale_anim_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
16 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/layout/public_dialog_load.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
22 |
23 |
33 |
34 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | basemvvm
3 |
4 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/main/res/values/style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
21 |
22 |
26 |
27 |
28 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/lib_basemvvm/src/test/java/com/mou/basemvvm/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mou.basemvvm;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/lib_common/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lib_common/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | id 'kotlin-android'
4 | id 'kotlin-kapt'
5 | id 'kotlin-android-extensions'
6 | }
7 | android {
8 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
9 | buildToolsVersion rootProject.ext.android["buildToolsVersion"]
10 |
11 | compileOptions {
12 | targetCompatibility JavaVersion.VERSION_1_8
13 | sourceCompatibility JavaVersion.VERSION_1_8
14 | }
15 |
16 | defaultConfig {
17 | minSdkVersion rootProject.ext.android["minSdkVersion"]
18 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
19 | versionCode rootProject.ext.android["versionCode"]
20 | versionName rootProject.ext.android["versionName"]
21 |
22 | buildConfigField "boolean","VERSION_ONLINE", "false"
23 | buildConfigField "boolean","VERSION_TEST", "false"
24 | }
25 |
26 | flavorDimensions "verison"
27 | productFlavors {
28 | //打包assembleVersionDevDebug
29 | versionDev{
30 | dimension "verison"
31 | buildConfigField "boolean","VERSION_ONLINE", "false"
32 | buildConfigField "boolean","VERSION_TEST", "false"
33 | // manifestPlaceholders = rootProject.ext.debugPlaceholders
34 | }
35 | //gradlew clean assembleVersionTestDebug
36 | versionTest {
37 | dimension "verison"
38 | buildConfigField "boolean","VERSION_ONLINE", "false"
39 | buildConfigField "boolean","VERSION_TEST", "true"
40 | // manifestPlaceholders = rootProject.ext.debugPlaceholders
41 | }
42 | // gradlew clean assembleVersionOnlineRelease
43 | versionOnline{
44 | dimension "verison"
45 | buildConfigField "boolean","VERSION_ONLINE", "true"
46 | buildConfigField "boolean","VERSION_TEST", "true"
47 | // manifestPlaceholders = rootProject.ext.releasePlaceholders
48 | }
49 | }
50 | buildTypes {
51 | release {
52 | minifyEnabled false
53 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
54 | }
55 | }
56 |
57 | //支持@Parcelize来实现Parcelable序列化
58 | androidExtensions {
59 | experimental = true
60 | }
61 |
62 | dataBinding {
63 | enabled = true
64 | }
65 | }
66 |
67 | dependencies {
68 | api fileTree(include: ['*.jar'], dir: 'libs')
69 | implementation rootProject.ext.dependencies["kotlin"]
70 | api(rootProject.ext.dependencies["arouter"]) {
71 | exclude module: 'support-v4'
72 | exclude module: 'support-annotations'
73 | }
74 | implementation rootProject.ext.dependencies["kotlin"]
75 | api project(':lib_basemvvm')
76 | api(rootProject.ext.dependencies["cardview"]) {
77 | exclude module: 'support-annotations'
78 | }
79 | api rootProject.ext.dependencies["SmartRefreshLayout"]
80 | api rootProject.ext.dependencies["FlycoTabLayout"]
81 | api rootProject.ext.dependencies["immersionbar"]
82 | api rootProject.ext.dependencies["RecyclerViewBindingAdapter"]
83 | api rootProject.ext.dependencies["PickerView"]
84 | api(rootProject.ext.dependencies["PictureSelector"]) {
85 | exclude module: 'glide'
86 | }
87 | api(rootProject.ext.dependencies["lottie"]) {
88 | exclude module: 'support'
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/lib_common/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/lib_common/src/androidTest/java/com/fortunes/commonsdk/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk;
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 | * Instrumented 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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.fortunes.commonsdk.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib_common/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
46 |
47 |
48 |
53 |
56 |
57 |
60 |
61 |
64 |
65 |
68 |
71 |
72 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/bean/UserInfoBean.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.bean
2 |
3 | import android.os.Parcelable
4 | import com.google.gson.annotations.SerializedName
5 | import kotlinx.android.parcel.Parcelize
6 |
7 | /**
8 | * @auther:MR-Cheng
9 | * @date: 2019/1/2
10 | * @description: 统一查询个人信息 common/userInfo/queryUserInfo
11 | * @parameter:
12 | */
13 | @Parcelize
14 | data class UserInfoBean(
15 | @SerializedName("mobile") val mobile: String = "",
16 | @SerializedName("name") val name: String = ""
17 | ) : Parcelable
18 |
19 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/binds/NormalExtens.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.binds
2 |
3 | import android.app.Dialog
4 | import android.view.Gravity
5 | import android.view.ViewGroup
6 | import android.widget.FrameLayout
7 | import com.bigkoo.pickerview.builder.TimePickerBuilder
8 | import com.bigkoo.pickerview.view.TimePickerView
9 | import java.util.*
10 |
11 | /***
12 | * You may think you know what the following code does.
13 | * But you dont. Trust me.
14 | * Fiddle with it, and youll spend many a sleepless
15 | * night cursing the moment you thought youd be clever
16 | * enough to "optimize" the code below.
17 | * Now close this file and go play with something else.
18 | */
19 | /***
20 | *
21 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
22 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
23 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
24 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
25 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
26 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
27 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
28 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
29 | * ░ ░ ░ ░ ░
30 | *
31 | * Created by mou on 2018/10/27.
32 |
33 |
34 | */
35 |
36 | /**
37 | * 简化时间选择dialog的build代码
38 | */
39 | fun TimePickerBuilder.buildBottom(showDay: Boolean = false,year:Int = 2008,month:Int = 0 ,day:Int = 1): TimePickerView {
40 | val startDate = Calendar.getInstance()
41 | val endDate = Calendar.getInstance()
42 | //设置选择起始日期
43 | startDate.set(year, month, day)
44 |
45 | //设置选择结束日期
46 | endDate.set(endDate.get(Calendar.YEAR), endDate.get(Calendar.MONTH), endDate.get(Calendar.DATE))
47 | val timePickerView = this
48 | //设置是否显示年/月/日/时/分/秒
49 | .setType(booleanArrayOf(true, true, showDay, false, false, false))
50 | //是否显示为对话框样式
51 | .isDialog(true)
52 | //设置两横线之间的间隔倍数
53 | .setLineSpacingMultiplier(2.0f)
54 | //起始终止年月日设定
55 | .setRangDate(startDate, endDate)
56 | .build()
57 | return timePickerView.setShowBottom()
58 | }
59 |
60 | /**
61 | * 时间选择dialog从底部弹出
62 | */
63 | fun TimePickerView.setShowBottom(): TimePickerView {
64 | val mDialog: Dialog = this.dialog
65 | val params = FrameLayout.LayoutParams(
66 | ViewGroup.LayoutParams.MATCH_PARENT,
67 | ViewGroup.LayoutParams.WRAP_CONTENT,
68 | Gravity.BOTTOM)
69 | params.leftMargin = 0
70 | params.rightMargin = 0
71 | this.dialogContainerLayout.layoutParams = params
72 | val dialogWindow = mDialog.window
73 | dialogWindow?.setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim)//修改动画样式
74 | dialogWindow?.setGravity(Gravity.BOTTOM)//改成Bottom,底部显示
75 | return this
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/core/ActivityLifecycleCallbacksImpl.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.core
2 |
3 | import android.app.Activity
4 | import android.app.Application
5 | import android.os.Build
6 | import android.os.Bundle
7 | import android.widget.RelativeLayout
8 | import android.widget.TextView
9 | import androidx.appcompat.app.AppCompatActivity
10 | import androidx.appcompat.widget.Toolbar
11 | import com.fortunes.commonsdk.R
12 | import com.gyf.barlibrary.ImmersionBar
13 | import timber.log.Timber
14 |
15 | /***
16 | * You may think you know what the following code does.
17 | * But you dont. Trust me.
18 | * Fiddle with it, and youll spend many a sleepless
19 | * night cursing the moment you thought youd be clever
20 | * enough to "optimize" the code below.
21 | * Now close this file and go play with something else.
22 | */
23 | /***
24 | *
25 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
26 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
27 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
28 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
29 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
30 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
31 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
32 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
33 | * ░ ░ ░ ░ ░
34 | *
35 | * Created by mou on 2018/9/11.
36 | */
37 | class ActivityLifecycleCallbacksImpl : Application.ActivityLifecycleCallbacks {
38 | override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
39 | Timber.i("${activity.javaClass.simpleName} onActivityCreated")
40 | ImmersionBar.with(activity)
41 | .statusBarDarkFont(true)
42 | .init()
43 | val toolbar: Toolbar? = activity.findViewById(R.id.toolbar)
44 | toolbar?.run {
45 | ImmersionBar.setTitleBar(activity, this)
46 | if (activity is AppCompatActivity) {
47 | activity.setSupportActionBar(activity.findViewById(R.id.toolbar))
48 | activity.supportActionBar?.setDisplayShowTitleEnabled(false)
49 | } else {
50 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
51 | activity.setActionBar(activity.findViewById(R.id.toolbar))
52 | activity.actionBar?.setDisplayShowTitleEnabled(false)
53 | } else {
54 |
55 | }
56 | }
57 | }
58 | //设置title
59 | activity.findViewById(R.id.toolbar_title)?.text = activity.title
60 | //设置左边点击事件
61 | activity.findViewById(R.id.public_rl_back)?.setOnClickListener {
62 | activity.onBackPressed()
63 | }
64 | }
65 |
66 | override fun onActivityStarted(activity: Activity) {
67 | }
68 |
69 | override fun onActivityPaused(activity: Activity) {
70 | }
71 |
72 | override fun onActivityResumed(activity: Activity) {
73 | }
74 |
75 | override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle?) {
76 | }
77 |
78 | override fun onActivityStopped(activity: Activity) {
79 | }
80 |
81 | override fun onActivityDestroyed(activity: Activity) {
82 | ImmersionBar.with(activity).destroy()
83 | }
84 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/core/ApplicationLifeCyclesImpl.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.core
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import com.alibaba.android.arouter.launcher.ARouter
6 | import com.fortunes.commonsdk.BuildConfig
7 | import com.mou.basemvvm.integration.AppLifeCycles
8 |
9 | import timber.log.Timber
10 |
11 | /***
12 | * You may think you know what the following code does.
13 | * But you dont. Trust me.
14 | * Fiddle with it, and youll spend many a sleepless
15 | * night cursing the moment you thought youd be clever
16 | * enough to "optimize" the code below.
17 | * Now close this file and go play with something else.
18 | */
19 | /***
20 | *
21 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
22 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
23 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
24 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
25 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
26 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
27 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
28 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
29 | * ░ ░ ░ ░ ░
30 | *
31 | * Created by mou on 2018/9/11.
32 |
33 |
34 | */
35 | class ApplicationLifeCyclesImpl : AppLifeCycles {
36 | override fun attachBaseContext(base: Context) {
37 | Timber.i("Application attachBaseContext")
38 | }
39 |
40 | override fun onCreate(application: Application) {
41 | if (BuildConfig.DEBUG) {//debug模式下初始化
42 | Timber.plant(Timber.DebugTree())
43 | ARouter.openLog() // 打印日志
44 | ARouter.openDebug() // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
45 | }
46 | ARouter.init(application) // 尽可能早,推荐在Application中初始化
47 |
48 | }
49 |
50 | override fun onTerminate(application: Application) {
51 | Timber.i("${application.javaClass.simpleName} onCreate")
52 | }
53 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/core/FragmentLifecycleCallbacksImpl.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.core
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.Fragment
5 | import androidx.fragment.app.FragmentManager
6 | import timber.log.Timber
7 |
8 |
9 | /***
10 | *
11 | * Created by mou on 2018/9/11.
12 | */
13 | class FragmentLifecycleCallbacksImpl : FragmentManager.FragmentLifecycleCallbacks() {
14 | override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
15 | super.onFragmentCreated(fm, f, savedInstanceState)
16 | Timber.i("${f.javaClass.simpleName} onFragmentCreated")
17 |
18 | }
19 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/core/GlobalConfiguration.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.core
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import androidx.fragment.app.FragmentManager
6 | import com.fortunes.commonsdk.R
7 | import com.mou.basemvvm.integration.AppLifeCycles
8 | import com.mou.basemvvm.integration.ConfigModule
9 | import com.scwang.smartrefresh.layout.SmartRefreshLayout
10 | import com.scwang.smartrefresh.layout.footer.ClassicsFooter
11 | import com.scwang.smartrefresh.layout.header.ClassicsHeader
12 |
13 | /***
14 | *
15 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
16 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
17 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
18 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
19 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
20 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
21 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
22 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
23 | * ░ ░ ░ ░ ░
24 | *
25 | * Created by mou on 2018/8/22.
26 | */
27 |
28 | class GlobalConfiguration : ConfigModule {
29 | init {
30 | //
31 | SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
32 | layout.setPrimaryColorsId(R.color.public_backgroundColor)//全局设置主题颜色
33 | ClassicsHeader(context)//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header,默认是 贝塞尔雷达Header
34 | }
35 | SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ ->
36 | //指定为经典Footer,默认是 BallPulseFooter
37 | ClassicsFooter(context).setDrawableSize(20f)
38 | }
39 | }
40 |
41 | override fun injectAppLifecycle(context :Context, lifeCycles: MutableList) {
42 | lifeCycles.add(ApplicationLifeCyclesImpl())
43 | }
44 |
45 | override fun injectActivityLifecycle(context: Context, lifeCycles: MutableList) {
46 | lifeCycles.add(ActivityLifecycleCallbacksImpl())
47 | }
48 |
49 | override fun injectFragmentLifecycle(context: Context, lifeCycles: MutableList) {
50 | lifeCycles.add(FragmentLifecycleCallbacksImpl())
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/core/RouterConstants.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.core
2 |
3 | /***
4 | * You may think you know what the following code does.
5 | * But you dont. Trust me.
6 | * Fiddle with it, and youll spend many a sleepless
7 | * night cursing the moment you thought youd be clever
8 | * enough to "optimize" the code below.
9 | * Now close this file and go play with something else.
10 | */
11 | /***
12 | *
13 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
14 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
15 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
16 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
17 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
18 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
19 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
20 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
21 | * ░ ░ ░ ░ ░
22 | *
23 | * Created by mou on 2018/9/13.
24 | */
25 | object RouterConstants {
26 | private const val HOME = "/home"
27 | private const val LOGIN = "/login"
28 | private const val MINE = "/mine"
29 | private const val WEB = "/web"
30 | /**
31 | * 主界面
32 | */
33 | const val MAIN_ACTIVITY = "$HOME/MainActivity"
34 | /**
35 | * 登录
36 | */
37 | const val LOGIN_ACTIVITY = "$LOGIN/loginActivity"
38 | /**
39 | * web页面
40 | */
41 | const val WEB_ACTIVITY = "$WEB/WebActivity"
42 |
43 | /**
44 | * 个人中心
45 | */
46 | const val MINE_ACTIVITY = "$MINE/MineActivity"
47 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/inter/MyTextChangeListner.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.inter
2 |
3 | import android.text.Editable
4 | import android.text.TextWatcher
5 |
6 | /**
7 | * @FileName: MyTextChangeListner.java
8 | * @author: villa_mou
9 | * @date: 04-11:14
10 | * @version V1.0 <描述当前版本功能>
11 | * @desc
12 | */
13 | abstract class MyTextChangeListner: TextWatcher {
14 | override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
15 | }
16 | override fun afterTextChanged(s: Editable?) {
17 | }
18 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/HttpException.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network
2 |
3 | import com.fortunes.commonsdk.network.bean.BaseBean
4 | import com.mou.basemvvm.helper.network.ApiException
5 |
6 | /**
7 | * @auther:MR-Cheng
8 | * @date: 2018/12/7
9 | * @description: 网络错误 状态
10 | * @parameter:
11 | */
12 |
13 | class HttpException(val baseBean: BaseBean) : ApiException(baseBean.errorMsg)
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/HttpStatusConstants.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network
2 |
3 | /**
4 | * @auther:MR-Cheng
5 | * @date: 2018/12/4
6 | * @description: 网络请求code对照表
7 | * @parameter:
8 | */
9 |
10 | object HttpStatusConstants {
11 | const val SUCCESS = 0
12 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/HttpUrlConstants.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network
2 |
3 | import com.fortunes.commonsdk.BuildConfig
4 |
5 | /***
6 | *
7 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
8 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
9 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
10 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
11 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
12 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
13 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
14 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
15 | * ░ ░ ░ ░ ░
16 | *
17 | * Created by mou on 2018/8/22.
18 | */
19 |
20 | object HttpUrlConstants {
21 | //开发环境
22 | private const val DEV_BASE_URL = "https://wanandroid.com/"
23 | //测试环境
24 | private const val TEST_BASE_URL = "https://wanandroid.com/"
25 | //正式环境
26 | private const val RELIASE_BASE_URL = "https://wanandroid.com/"
27 |
28 | /**
29 | * 根据不同的打包命令自动查找对应的base_url
30 | * 1,开发环境打包 gradlew clean assembleVersionDevDebug或者gradlew clean assembleVersionDevRealease
31 | * 2,测试环境打包 gradlew clean assembleVersionTestDebug或者gradlew clean assembleVersionTestRealease
32 | * 3,正式环境打包 gradlew clean assembleVersionOnlineRelease
33 | */
34 | fun getBaseUrl(): String = if (BuildConfig.VERSION_ONLINE) RELIASE_BASE_URL else{
35 | if (BuildConfig.VERSION_TEST) TEST_BASE_URL else DEV_BASE_URL
36 | }
37 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/RxHttpExtens.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network
2 |
3 | import android.content.Context
4 | import com.google.gson.JsonParseException
5 | import com.mou.basemvvm.helper.extens.toast
6 | import com.mou.basemvvm.helper.network.ApiException
7 | import com.mou.easymvvm.BuildConfig
8 | import com.uber.autodispose.SingleSubscribeProxy
9 | import org.json.JSONException
10 | import java.net.ConnectException
11 | import java.net.SocketTimeoutException
12 | import java.net.UnknownHostException
13 |
14 | /**
15 | * @auther:MR-Cheng
16 | * @date: 2018/12/5
17 | * @description:
18 | * @parameter:
19 | */
20 |
21 | /**
22 | * 关于Http请求结果的统一处理类
23 | */
24 | fun SingleSubscribeProxy.onHttpSubscribe(context: Context, subErr: ((Throwable) -> Unit)? = null, success: ((T) -> Unit)? = null) {
25 | this.subscribe({
26 | success?.invoke(it)
27 | }, {
28 | //处理登录过期,或者强制升级操作
29 | // if (it is HttpException) {
30 | // when (it.baseBean.errorCode) {
31 | // HttpStatusConstants.RESULT_STATE_UPDATE -> {
32 | //// UpdateDialog(context, true, it.baseBean.sysData.version).showDialog()
33 | // }
34 | // }
35 | // when (it.baseBean.code) {
36 | // HttpStatusConstants.CODE_S0018 -> {
37 | // LoginUtils.clearUserInfo()
38 | // EasySharedPreferences.load(FingerAndGestureInfo::class.java).clearAllData()
39 | // NavigationUtils.goLoginActivity()
40 | // }
41 | // }
42 | // }
43 | context.toastHttpFail(it)
44 | subErr?.invoke(it)
45 | })
46 | }
47 |
48 | fun SingleSubscribeProxy.onHttpSubscribeNoToast(context: Context, subErr: ((Throwable) -> Unit)? = null, success: ((T) -> Unit)? = null) {
49 | this.subscribe({
50 | success?.invoke(it)
51 | }, {
52 | // if (it is HttpException) {
53 | // when (it.baseBean.state) {
54 | // HttpStatusConstants.RESULT_STATE_UPDATE -> {
55 | //// UpdateDialog(context, true, it.baseBean.sysData.version).showDialog()
56 | // }
57 | // }
58 | // when (it.baseBean.errorCode) {
59 | // HttpStatusConstants.CODE_S0018 -> {
60 | // LoginUtils.clearUserInfo()
61 | // EasySharedPreferences.load(FingerAndGestureInfo::class.java).clearAllData()
62 | // NavigationUtils.goLoginActivity()
63 | // }
64 | // }
65 | // }
66 | if (it is ApiException) {
67 | it.message?.let {
68 | context.toast(it)
69 | }
70 | }
71 | subErr?.invoke(it)
72 | })
73 | }
74 |
75 |
76 | /**
77 | * 网络失败失败的toast
78 | */
79 | fun Context.toastHttpFail(error: Throwable?) {
80 | error?.let { throwable ->
81 | if (BuildConfig.DEBUG) {
82 | throwable.printStackTrace()
83 | }
84 | if (throwable is ApiException) {
85 | throwable.message?.let { toast(it) }
86 | } else if (throwable is SocketTimeoutException) {
87 | toast("网络连接超时")
88 | } else if (throwable is UnknownHostException || throwable is ConnectException) {
89 | toast("网络未连接")
90 | } else if (throwable is JSONException || throwable is JsonParseException) {
91 | toast("数据解析错误")
92 | } else {
93 | toast("网络连接失败")
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/api/BaseApiService.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network.api
2 |
3 | import com.fortunes.commonsdk.bean.UserInfoBean
4 | import com.fortunes.commonsdk.network.bean.BaseBean
5 | import io.reactivex.Single
6 | import retrofit2.http.POST
7 |
8 | /***
9 | * You may think you know what the following code does.
10 | * But you dont. Trust me.
11 | * Fiddle with it, and youll spend many a sleepless
12 | * night cursing the moment you thought youd be clever
13 | * enough to "optimize" the code below.
14 | * Now close this file and go play with something else.
15 | */
16 | /***
17 | *
18 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
19 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
20 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
21 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
22 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
23 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
24 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
25 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
26 | * ░ ░ ░ ░ ░
27 | *
28 | * Created by mou on 2018/12/17.
29 | * 项目通用的接口
30 | */
31 | interface BaseApiService {
32 | @POST("common/userInfo/queryUserInfo")
33 | fun queryUserInfo(): Single>
34 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/api/BaseApiServiceManager.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network.api
2 |
3 | import com.fortunes.commonsdk.bean.UserInfoBean
4 | import com.fortunes.commonsdk.network.HttpUrlConstants
5 | import com.fortunes.commonsdk.network.bean.BaseBean
6 | import com.fortunes.commonsdk.network.provider.BaseNetProvider
7 | import com.mou.basemvvm.base.BaseApplication
8 | import com.mou.basemvvm.helper.extens.async
9 | import com.mou.basemvvm.helper.network.NetMgr
10 | import io.reactivex.Single
11 |
12 | /***
13 | * You may think you know what the following code does.
14 | * But you dont. Trust me.
15 | * Fiddle with it, and youll spend many a sleepless
16 | * night cursing the moment you thought youd be clever
17 | * enough to "optimize" the code below.
18 | * Now close this file and go play with something else.
19 | */
20 | /***
21 | *
22 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
23 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
24 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
25 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
26 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
27 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
28 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
29 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
30 | * ░ ░ ░ ░ ░
31 | *
32 | * Created by mou on 2018/12/17.
33 | * 项目通用的接口请求类
34 | */
35 | object BaseApiServiceManager {
36 | private val apiService by lazy {
37 | NetMgr.getRetrofit(
38 | HttpUrlConstants.getBaseUrl(),
39 | BaseNetProvider(BaseApplication.instance())
40 | ).create(BaseApiService::class.java)
41 | }
42 |
43 | /**
44 | * 获取用户信息
45 | */
46 | fun getUserInfo(): Single> =
47 | apiService.queryUserInfo()
48 | .async()
49 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/bean/BaseBean.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network.bean
2 |
3 | /***
4 | * You may think you know what the following code does.
5 | * But you dont. Trust me.
6 | * Fiddle with it, and youll spend many a sleepless
7 | * night cursing the moment you thought youd be clever
8 | * enough to "optimize" the code below.
9 | * Now close this file and go play with something else.
10 | */
11 | /***
12 | *
13 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
14 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
15 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
16 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
17 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
18 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
19 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
20 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
21 | * ░ ░ ░ ░ ░
22 | *
23 | * Created by mou on 2018/11/12.
24 |
25 |
26 | */
27 | data class BaseBean constructor(var data: T, var errorCode: Int, var errorMsg: String)
28 | class EmptyBean
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/network/provider/NoHeaderNetProvider.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.network.provider
2 |
3 | import android.content.Context
4 | import com.fortunes.commonsdk.BuildConfig
5 | import com.franmontiel.persistentcookiejar.PersistentCookieJar
6 | import com.franmontiel.persistentcookiejar.cache.SetCookieCache
7 | import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
8 | import com.mou.basemvvm.helper.network.NetProvider
9 | import com.mou.basemvvm.helper.network.RequestHandler
10 | import okhttp3.*
11 |
12 | /***
13 | *
14 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
15 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
16 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
17 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
18 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
19 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
20 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
21 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
22 | * ░ ░ ░ ░ ░
23 | *
24 | * Created by mou on 2018/8/22.
25 | */
26 |
27 | class NoHeaderNetProvider(private val context: Context) : NetProvider {
28 | companion object {
29 | const val CONNECT_TIME_OUT: Long = 30
30 | const val READ_TIME_OUT: Long = 30
31 | const val WRITE_TIME_OUT: Long = 30
32 | }
33 |
34 | override fun configInterceptors(): Array? = null
35 |
36 | override fun configHttps(builder: OkHttpClient.Builder) {
37 | }
38 |
39 | override fun configCookie(): CookieJar? =
40 | PersistentCookieJar(SetCookieCache(), SharedPrefsCookiePersistor(context))
41 |
42 | override fun configHandler(): RequestHandler = HeaderHandler()
43 |
44 |
45 | override fun configConnectTimeoutSecs(): Long =
46 | CONNECT_TIME_OUT
47 |
48 | override fun configReadTimeoutSecs(): Long =
49 | READ_TIME_OUT
50 |
51 | override fun configWriteTimeoutSecs(): Long =
52 | WRITE_TIME_OUT
53 |
54 | override fun configLogEnable(): Boolean = BuildConfig.DEBUG
55 |
56 | inner class HeaderHandler : RequestHandler {
57 | override fun onBeforeRequest(request: Request, chain: Interceptor.Chain): Request {
58 | return request
59 | }
60 |
61 | override fun onAfterRequest(response: Response, chain: Interceptor.Chain): Response {
62 | return response
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/HideKeyBoardUtil.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils
2 |
3 | import android.view.MotionEvent
4 | import android.view.View
5 | import android.widget.EditText
6 | import com.blankj.utilcode.util.KeyboardUtils
7 |
8 | /**
9 | * @auther:MR-Cheng
10 | * @date: 2018/11/22
11 | * @description:
12 | * @parameter:隐藏键盘工具类
13 | */
14 | object HideKeyBoardUtil {
15 |
16 | private fun isShouldHideKeyboard(v: View?, event: MotionEvent): Boolean {
17 | if (v != null && v is EditText) {
18 | val l = intArrayOf(0, 0)
19 | v.getLocationInWindow(l)
20 | val left = l[0]
21 | val top = l[1]
22 | val bottom = top + v.height
23 | val right = left + v.width
24 | return !(event.x > left && event.x < right
25 | && event.y > top && event.y < bottom)
26 | }
27 | // 如果焦点不是EditText则忽略,这个发生在视图刚绘制完,第一个焦点不在EditText上,和用户用轨迹球选择其他的焦点
28 | return false
29 | }
30 |
31 |
32 | fun hideKeyboard(v: View?, event: MotionEvent) {
33 | if (event.action == MotionEvent.ACTION_DOWN) {
34 | if (isShouldHideKeyboard(v, event)) {
35 | KeyboardUtils.hideSoftInput(v)
36 | }
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/ImageUtils.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.graphics.drawable.Drawable
6 | import android.widget.ImageView
7 | import com.bumptech.glide.Glide
8 | import com.bumptech.glide.request.RequestOptions
9 | import com.mou.basemvvm.base.BaseApplication
10 |
11 |
12 | /***
13 | *
14 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
15 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
16 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
17 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
18 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
19 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
20 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
21 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
22 | * ░ ░ ░ ░ ░
23 | *
24 | * Created by mou on 2018/8/22.
25 |
26 |
27 | * 加载图片工具类
28 | */
29 |
30 | object ImageUtils {
31 | @SuppressLint("CheckResult")
32 | fun load(context: Context?, url: String?, imageView: ImageView, placeholderImg: Drawable? = null, errRes: Int = 0) {
33 | val options = RequestOptions()
34 | // val drawableCrossFadeFactory = DrawableCrossFadeFactory.Builder(300).setCrossFadeEnabled(true).build()
35 | if (errRes != 0) {
36 | options.placeholder(errRes)
37 | .error(errRes)
38 | } else if (placeholderImg != null) {
39 | options.placeholder(placeholderImg)
40 | .error(placeholderImg)
41 | }
42 | Glide.with(context ?: BaseApplication.instance())
43 | .load(url)
44 | .apply(options)
45 | // .transition(DrawableTransitionOptions.with(drawableCrossFadeFactory))
46 | .into(imageView)
47 | }
48 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/MyToast.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils
2 |
3 | import android.widget.Toast
4 | import com.mou.basemvvm.base.BaseApplication
5 |
6 | /**
7 | * 解决小米吐司带app名称问题
8 | */
9 | object MyToast {
10 | private var toast: Toast? = null
11 | fun showToast(desc: String) {
12 | if (toast == null) {
13 | toast = Toast.makeText(BaseApplication.instance(), null, Toast.LENGTH_SHORT)
14 | toast?.setText(desc)
15 | } else {
16 | toast?.setText(desc)
17 | toast?.duration = Toast.LENGTH_SHORT
18 | }
19 | toast?.show()
20 | }
21 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/NavigationUtils.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils
2 |
3 | import com.alibaba.android.arouter.launcher.ARouter
4 | import com.fortunes.commonsdk.core.RouterConstants
5 |
6 | /***
7 | * You may think you know what the following code does.
8 | * But you dont. Trust me.
9 | * Fiddle with it, and youll spend many a sleepless
10 | * night cursing the moment you thought youd be clever
11 | * enough to "optimize" the code below.
12 | * Now close this file and go play with something else.
13 | */
14 | /***
15 | *
16 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
17 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
18 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
19 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
20 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
21 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
22 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
23 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
24 | * ░ ░ ░ ░ ░
25 | *
26 | * Created by mou on 2018/9/19.
27 | * 关于所有ARouter路由跳转的类
28 | */
29 | object NavigationUtils {
30 |
31 | /**
32 | * 去往登录页面
33 | */
34 | fun goLoginActivity() {
35 | ARouter.getInstance().build(RouterConstants.LOGIN_ACTIVITY).navigation()
36 | }
37 |
38 | /**
39 | * 去往首页
40 | */
41 | fun goMainActivity() {
42 | ARouter.getInstance().build(RouterConstants.MAIN_ACTIVITY).navigation()
43 | }
44 |
45 | /**
46 | *去个人中心
47 | */
48 | fun goMineActivity(){
49 | ARouter.getInstance().build(RouterConstants.MINE_ACTIVITY).navigation()
50 | }
51 |
52 |
53 | /**
54 | * 去往WebView页面
55 | * url:加载的网址
56 | * title:加载的标题
57 | */
58 | const val WEB_URL = "url"
59 | const val WEB_TITLE = "title"
60 | fun goWebActivity(url: String, title: String) {
61 | ARouter.getInstance().build(RouterConstants.WEB_ACTIVITY)
62 | .withString(WEB_URL, url)
63 | .withString(WEB_TITLE, title)
64 | .navigation()
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/RxBusUtils.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils
2 |
3 | import com.blankj.rxbus.RxBus
4 |
5 | /***
6 | * You may think you know what the following code does.
7 | * But you dont. Trust me.
8 | * Fiddle with it, and youll spend many a sleepless
9 | * night cursing the moment you thought youd be clever
10 | * enough to "optimize" the code below.
11 | * Now close this file and go play with something else.
12 | */
13 | /***
14 | *
15 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
16 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
17 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
18 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
19 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
20 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
21 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
22 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
23 | * ░ ░ ░ ░ ░
24 | *
25 | * Created by mou on 2018/12/7.
26 | * RxBus注册监听类
27 | */
28 | object RxBusUtils {
29 |
30 | /**
31 | * 取消RxBus的监听
32 | */
33 | fun cancelSubscriber(subscriber: Any) {
34 | RxBus.getDefault().unregister(subscriber)
35 | }
36 |
37 | private const val HOME_REFRESH = "home_refresh"
38 | /**
39 | * 发送首页刷新
40 | */
41 | fun postHomeRefresh(refresh: Boolean) {
42 | RxBus.getDefault().post(refresh, HOME_REFRESH)
43 | }
44 | /**
45 | * 监听首页刷新
46 | */
47 | fun subscribeHomeRefresh(subscriber: Any, callback: (Boolean) -> Unit) {
48 | RxBus.getDefault().subscribe(subscriber, HOME_REFRESH, object : RxBus.Callback() {
49 | override fun onEvent(isLoginSuccess: Boolean?) {
50 | isLoginSuccess?.let(callback)
51 | }
52 | })
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/UniqueIdUtils.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils;
2 |
3 | import android.os.Build;
4 |
5 | import java.util.UUID;
6 |
7 | /**
8 | * Created by MR-Cheng on 2017/12/25.
9 | */
10 |
11 | public class UniqueIdUtils {
12 |
13 | /**
14 | * 生成设备唯一id
15 | *
16 | * @return
17 | */
18 | public static String getUniquePsuedoID() {
19 | String serial = null;
20 | String m_szDevIDShort = "35"
21 | + Build.BOARD.length() % 10
22 | + Build.BRAND.length() % 10
23 | + Build.CPU_ABI.length() % 10
24 | + Build.DEVICE.length() % 10
25 | + Build.DISPLAY.length() % 10
26 | + Build.HOST.length() % 10
27 | + Build.ID.length() % 10
28 | + Build.MANUFACTURER.length() % 10
29 | + Build.MODEL.length() % 10
30 | + Build.PRODUCT.length() % 10
31 | + Build.TAGS.length() % 10
32 | + Build.TYPE.length() % 10
33 | + Build.USER.length() % 10; //13 位
34 | try {
35 | serial = android.os.Build.class.getField("SERIAL").get(null).toString();//API>=9 使用serial号
36 | String str = new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
37 | return MD5.getMD5(str);
38 | } catch (Exception exception) {
39 | //serial需要一个初始化
40 | serial = "serial"; // 随便一个初始化
41 | }
42 | String str = new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
43 |
44 | return MD5.getMD5(str);
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/utils/myStartActivity.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.utils
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 |
6 | inline fun Activity.myStartActivity(vararg args: Pair, requestCode: Int = -1) {
7 | val intent = Intent(this, A::class.java)
8 | for (arg in args) {
9 | if (arg.second is Boolean) {
10 | intent.putExtra(arg.first, arg.second as Boolean)
11 | } else if (arg.second is Int) {
12 | intent.putExtra(arg.first, arg.second as Int)
13 | } else {
14 | intent.putExtra(arg.first, arg.second.toString())
15 | }
16 |
17 | }
18 | if (requestCode > 0) {
19 | this.startActivityForResult(intent, requestCode)
20 | } else {
21 | this.startActivity(intent)
22 | }
23 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/NoScrollViewPager.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.util.AttributeSet
6 | import android.view.MotionEvent
7 | import androidx.viewpager.widget.ViewPager
8 |
9 | /***
10 | *
11 | * █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗
12 | * ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝
13 | * ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗
14 | * ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║
15 | * ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝
16 | * ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝
17 | * ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░
18 | * ░ ░ ░░░ ░ ░ ░ ░ ░░ ░
19 | * ░ ░ ░ ░ ░
20 | *
21 | * Created by mou on 2018/8/20.
22 |
23 |
24 | * 不能滚动的viewpager
25 | */
26 |
27 | class NoScrollViewPager : ViewPager {
28 | private var noScroll = true
29 |
30 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
31 |
32 | constructor(context: Context) : super(context)
33 |
34 | @SuppressLint("ClickableViewAccessibility")
35 | override fun onTouchEvent(arg0: MotionEvent): Boolean {
36 | return !noScroll && super.onTouchEvent(arg0)
37 | }
38 |
39 | override fun onInterceptTouchEvent(arg0: MotionEvent): Boolean {
40 | return !noScroll && super.onInterceptTouchEvent(arg0)
41 | }
42 |
43 | override fun setCurrentItem(item: Int) {
44 | super.setCurrentItem(item, !noScroll)
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/filter/ChineseFilter.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.filter
2 |
3 | import android.text.InputFilter
4 | import android.text.Spanned
5 | import java.util.regex.Pattern
6 |
7 |
8 | /**
9 | * @auther:MR-Cheng
10 | * @date: 2018/12/24
11 | * @description: 限制输入框不能输入特殊符号
12 | * @parameter:
13 | */
14 |
15 | class ChineseFilter : InputFilter{
16 | override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int): CharSequence? {
17 |
18 | val regex = "[`~!@#_$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()— +|{}【】‘;:”“’。,、?]"
19 | val p = Pattern.compile(regex)
20 | val m = p.matcher(source.toString())
21 | return if (m.find()) "" else null
22 |
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/filter/PhoneFilter.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.filter
2 |
3 | import android.text.InputFilter
4 | import android.text.Spanned
5 | import java.util.regex.Pattern
6 |
7 | /**
8 | * @auther:MR-Cheng
9 | * @date: 2018/12/24
10 | * @description:限制输入框只能输入1开头的数字
11 | * @parameter:
12 | */
13 |
14 | class PhoneFilter : InputFilter{
15 | override fun filter(source: CharSequence, p1: Int, p2: Int, p3: Spanned, p4: Int, p5: Int): CharSequence? {
16 | val regex = "[1]"
17 | val p = Pattern.compile(regex)
18 | return if (source.isNotEmpty() && p4 == 0){
19 | val s = source.toString().substring(0,1)
20 | val m = p.matcher(s)
21 | if (m.matches()) null else ""
22 | }else{
23 | null
24 | }
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/BaseLazyFragment.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer
2 |
3 | import android.os.Bundle
4 | import androidx.annotation.UiThread
5 | import androidx.fragment.app.Fragment
6 |
7 | abstract class BaseLazyFragment : Fragment() {
8 | /**
9 | * 懒加载过
10 | */
11 | private var isLazyLoaded: Boolean = false
12 |
13 | private var isPrepared: Boolean = false
14 |
15 | override fun onActivityCreated(savedInstanceState: Bundle?) {
16 | super.onActivityCreated(savedInstanceState)
17 | isPrepared = true
18 | //只有Fragment onCreateView好了,
19 | //另外这里调用一次lazyLoad()
20 | lazyLoad()
21 | }
22 |
23 | override fun setUserVisibleHint(isVisibleToUser: Boolean) {
24 | super.setUserVisibleHint(isVisibleToUser)
25 | lazyLoad()
26 | }
27 |
28 | /**
29 | * 调用懒加载
30 | */
31 | private fun lazyLoad() {
32 | if (userVisibleHint && isPrepared && !isLazyLoaded) {
33 | onLazyLoad()
34 | isLazyLoaded = true
35 | }
36 | }
37 |
38 | @UiThread
39 | abstract fun onLazyLoad()
40 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/OnLongClickListener.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer
2 |
3 | import android.view.View
4 |
5 |
6 | interface OnLongClickListener{
7 | fun onLongClick(view: View)
8 | }
9 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/PhotoViewerPagerAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer
2 |
3 | import androidx.fragment.app.Fragment
4 | import androidx.fragment.app.FragmentManager
5 | import androidx.fragment.app.FragmentStatePagerAdapter
6 |
7 |
8 | class PhotoViewerPagerAdapter(private var mData: MutableList, fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
9 | override fun getItem(position: Int): Fragment {
10 | return mData[position]
11 | }
12 |
13 | override fun getCount(): Int {
14 | return mData.size
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/Utils.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer
2 |
3 | import android.content.Context
4 | import android.util.TypedValue
5 |
6 | object Utils{
7 | fun dp2px(context: Context, dipValue: Int): Int {
8 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
9 | dipValue.toFloat(), context.resources.displayMetrics).toInt()
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/ViewPagerFixed.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.MotionEvent
6 | import androidx.viewpager.widget.ViewPager
7 |
8 | /**
9 | * 不能滚动的ViewPager
10 | */
11 | class ViewPagerFixed : ViewPager {
12 |
13 | constructor(context: Context) : super(context)
14 |
15 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
16 |
17 | override fun onTouchEvent(ev: MotionEvent): Boolean {
18 | try {
19 | return super.onTouchEvent(ev)
20 | } catch (ex: IllegalArgumentException) {
21 | ex.printStackTrace()
22 | }
23 |
24 | return false
25 | }
26 |
27 | override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
28 | try {
29 | return super.onInterceptTouchEvent(ev)
30 | } catch (ex: IllegalArgumentException) {
31 | ex.printStackTrace()
32 | }
33 |
34 | return false
35 | }
36 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/WrapperView.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer
2 |
3 | import android.view.View
4 |
5 | class WrapperView(private val mTarget: View) {
6 |
7 |
8 | fun getWidth(): Int {
9 | return mTarget.layoutParams.width
10 | }
11 |
12 | fun setWidth(width: Int) {
13 | mTarget.layoutParams.width = width
14 | mTarget.requestLayout()
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/Compat.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.fortunes.commonsdk.view.photoviewer.photoview;
17 |
18 | import android.annotation.TargetApi;
19 | import android.os.Build.VERSION;
20 | import android.os.Build.VERSION_CODES;
21 | import android.view.View;
22 |
23 | class Compat {
24 |
25 | private static final int SIXTY_FPS_INTERVAL = 1000 / 60;
26 |
27 | public static void postOnAnimation(View view, Runnable runnable) {
28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
29 | postOnAnimationJellyBean(view, runnable);
30 | } else {
31 | view.postDelayed(runnable, SIXTY_FPS_INTERVAL);
32 | }
33 | }
34 |
35 | @TargetApi(16)
36 | private static void postOnAnimationJellyBean(View view, Runnable runnable) {
37 | view.postOnAnimation(runnable);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnGestureListener.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.fortunes.commonsdk.view.photoviewer.photoview;
17 |
18 | interface OnGestureListener {
19 |
20 | void onDrag(float dx, float dy);
21 |
22 | void onFling(float startX, float startY, float velocityX,
23 | float velocityY);
24 |
25 | void onScale(float scaleFactor, float focusX, float focusY);
26 |
27 | }
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnMatrixChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for
7 | * this View.
8 | */
9 | public interface OnMatrixChangedListener {
10 |
11 | /**
12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because
13 | * the View's bounds have changed, or the user has zoomed.
14 | *
15 | * @param rect - Rectangle displaying the Drawable's new bounds.
16 | */
17 | void onMatrixChanged(RectF rect);
18 | }
19 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnOutsidePhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Callback when the user tapped outside of the photo
7 | */
8 | public interface OnOutsidePhotoTapListener {
9 |
10 | /**
11 | * The outside of the photo has been tapped
12 | */
13 | void onOutsidePhotoTap(ImageView imageView);
14 | }
15 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnPhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * A callback to be invoked when the Photo is tapped with a single
7 | * tap.
8 | */
9 | public interface OnPhotoTapListener {
10 |
11 | /**
12 | * A callback to receive where the user taps on a photo. You will only receive a callback if
13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored.
14 | *
15 | * @param view ImageView the user tapped.
16 | * @param x where the user tapped from the of the Drawable, as percentage of the
17 | * Drawable width.
18 | * @param y where the user tapped from the top of the Drawable, as percentage of the
19 | * Drawable height.
20 | */
21 | void onPhotoTap(ImageView view, float x, float y);
22 | }
23 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnScaleChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 |
4 | /**
5 | * Interface definition for callback to be invoked when attached ImageView scale changes
6 | */
7 | public interface OnScaleChangedListener {
8 |
9 | /**
10 | * Callback for when the scale changes
11 | *
12 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in)
13 | * @param focusX focal point X position
14 | * @param focusY focal point Y position
15 | */
16 | void onScaleChange(float scaleFactor, float focusX, float focusY);
17 | }
18 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnSingleFlingListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | import android.view.MotionEvent;
4 |
5 | /**
6 | * A callback to be invoked when the ImageView is flung with a single
7 | * touch
8 | */
9 | public interface OnSingleFlingListener {
10 |
11 | /**
12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if
13 | * the user flings anywhere on the view.
14 | *
15 | * @param e1 MotionEvent the user first touch.
16 | * @param e2 MotionEvent the user last touch.
17 | * @param velocityX distance of user's horizontal fling.
18 | * @param velocityY distance of user's vertical fling.
19 | */
20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
21 | }
22 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnViewDragListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | /**
4 | * Interface definition for a callback to be invoked when the photo is experiencing a drag event
5 | */
6 | public interface OnViewDragListener {
7 |
8 | /**
9 | * Callback for when the photo is experiencing a drag event. This cannot be invoked when the
10 | * user is scaling.
11 | *
12 | * @param dx The change of the coordinates in the x-direction
13 | * @param dy The change of the coordinates in the y-direction
14 | */
15 | void onDrag(float dx, float dy);
16 | }
17 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnViewFingerUpListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | /**
4 | * Created by WangLu on 2018/7/15.
5 | */
6 |
7 | public interface OnViewFingerUpListener {
8 | void onViewFingerUp();
9 | }
10 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/OnViewTapListener.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | import android.view.View;
4 |
5 | public interface OnViewTapListener {
6 |
7 | /**
8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if
9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored.
10 | *
11 | * @param view - View the user tapped.
12 | * @param x - where the user tapped from the left of the View.
13 | * @param y - where the user tapped from the top of the View.
14 | */
15 | void onViewTap(View view, float x, float y);
16 | }
17 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/photoviewer/photoview/Util.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.photoviewer.photoview;
2 |
3 | import android.view.MotionEvent;
4 | import android.widget.ImageView;
5 |
6 | class Util {
7 |
8 | static void checkZoomLevels(float minZoom, float midZoom,
9 | float maxZoom) {
10 | if (minZoom >= midZoom) {
11 | throw new IllegalArgumentException(
12 | "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value");
13 | } else if (midZoom >= maxZoom) {
14 | throw new IllegalArgumentException(
15 | "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value");
16 | }
17 | }
18 |
19 | static boolean hasDrawable(ImageView imageView) {
20 | return imageView.getDrawable() != null;
21 | }
22 |
23 | static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) {
24 | if (scaleType == null) {
25 | return false;
26 | }
27 | switch (scaleType) {
28 | case MATRIX:
29 | throw new IllegalStateException("Matrix scale type is not supported");
30 | }
31 | return true;
32 | }
33 |
34 | static int getPointerIndex(int action) {
35 | return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/lib_common/src/main/java/com/fortunes/commonsdk/view/toolbar/MyToolBarLayout.kt:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk.view.toolbar
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Context
5 | import android.util.AttributeSet
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.widget.ImageView
9 | import android.widget.LinearLayout
10 | import android.widget.RelativeLayout
11 | import android.widget.TextView
12 | import com.fortunes.commonsdk.R
13 |
14 | /**
15 | * 通用的标题栏ToolBar
16 | */
17 |
18 | class MyToolBarLayout(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
19 | private var backIcon: Int = R.mipmap.public_back_icon
20 | private var toolTitle: String? = null
21 | private var toolRight: String? = null
22 | private var iconVisible: Boolean = true
23 |
24 | private var titleTv: TextView
25 | private var ivBack: ImageView
26 | private var rlBack: RelativeLayout
27 | private var rlRight: RelativeLayout
28 | private var tvRight: TextView
29 |
30 | init {
31 | @SuppressLint("CustomViewStyleable")
32 | val array = context.obtainStyledAttributes(attrs, R.styleable.public_toolbar)
33 | backIcon = array.getResourceId(R.styleable.public_toolbar_public_toolbar_res, R.mipmap.public_back_icon)
34 | toolTitle = array.getString(R.styleable.public_toolbar_public_toolbar_title)
35 | toolRight = array.getString(R.styleable.public_toolbar_public_toolbar_tv_right)
36 | iconVisible = array.getBoolean(R.styleable.public_toolbar_public_toolbar_img, true)
37 | array.recycle()
38 | val view = LayoutInflater.from(context).inflate(R.layout.public_layout_toolbar, this, false)
39 | addView(view, 0)
40 | ivBack = view.findViewById(R.id.public_iv_back)
41 | rlBack = view.findViewById(R.id.public_rl_back)
42 | rlRight = view.findViewById(R.id.public_rl_right)
43 | tvRight = view.findViewById(R.id.public_tv_right)
44 | ivBack.setImageResource(backIcon)
45 | ivBack.visibility = if (iconVisible) View.VISIBLE else View.GONE
46 | rlBack.visibility = if (iconVisible) View.VISIBLE else View.GONE
47 | titleTv = view.findViewById(R.id.public_toolbar_title)
48 | titleTv.text = toolTitle
49 | tvRight.text = toolRight
50 |
51 | }
52 |
53 | fun setOnRightClickListner(click: (() -> Unit)? = null) {
54 | rlRight.setOnClickListener {
55 | click?.invoke()
56 | }
57 | }
58 |
59 | /**
60 | * 设置标题
61 | */
62 | fun setTitle(title: String) {
63 | titleTv.text = title
64 | }
65 |
66 | fun setTvRightVisible(visibility: Boolean) {
67 | if (visibility) rlRight.visibility = View.VISIBLE else rlRight.visibility = View.GONE
68 | }
69 |
70 |
71 | /**
72 | * 设置左边图片
73 | */
74 | fun leftIconRes(res: Int) {
75 | ivBack.setImageResource(res)
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/lib_common/src/main/res/anim/public_bottomhide.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
14 |
15 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/anim/public_bottomshow.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
9 |
13 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/anim/public_centerhide.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/anim/public_centershow.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/anim/public_shake_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/anim/public_shake_cricle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/color/public_text_gray_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/drawable/public_login_btn_style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 | -
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/drawable/public_no_selected_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/drawable/public_selected_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_activity_photoviewer.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_dialog_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
15 |
16 |
19 |
20 |
21 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_item_picture.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
15 |
16 |
21 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_layout_holder.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
12 |
15 |
16 |
19 |
20 |
24 |
28 |
29 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_layout_toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
16 |
17 |
21 |
22 |
29 |
30 |
38 |
39 |
44 |
45 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_status_empty_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
23 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_status_error_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
22 |
23 |
30 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_status_loading_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
19 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_status_no_network_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
18 |
19 |
24 |
25 |
30 |
31 |
36 |
37 |
46 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/layout/public_title_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-hdpi/public_ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-hdpi/public_ic_launcher.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-mdpi/public_ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-mdpi/public_ic_launcher.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xhdpi/public_ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xhdpi/public_ic_launcher.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_back_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_back_icon.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_close_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_close_icon.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_dialog_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_dialog_close.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_finger_dialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_finger_dialog.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_ic_launcher.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_arrow_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_arrow_right.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_back.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_call.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_call.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_close.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_complete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_complete.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_fail.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_location.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_return.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_search.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_underway.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_underway.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_icon_wait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_icon_wait.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_operator_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_operator_close.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_status_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_status_empty.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxhdpi/public_status_network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxhdpi/public_status_network.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/mipmap-xxxhdpi/public_ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/lib_common/src/main/res/mipmap-xxxhdpi/public_ic_launcher.png
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #F7F7F7
4 | #FF3D14
5 | #D73411
6 | #70A4CD
7 | #333333
8 | #666666
9 | #999999
10 | #DDDDDD
11 | #BBBBBB
12 | #CCCCCC
13 | #000000
14 | #fff7f7
15 |
16 | #FFFFFF
17 | #F8F8F8
18 | #10000000
19 | #10C219
20 | #FFBD1F
21 | #EEEEEE
22 | #333333
23 |
24 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 44dp
4 | 50dp
5 | 32sp
6 | 22sp
7 | 18sp
8 | 16sp
9 | 14sp
10 | 12sp
11 | 6dp
12 |
13 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | commonsdk
3 | mvvm模块化
4 |
5 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/values/view_style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/xml/file_paths_public.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/lib_common/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/lib_common/src/test/java/com/fortunes/commonsdk/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.fortunes.commonsdk;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/module_login/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/module_login/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../component_build.gradle"
2 |
3 | android {
4 | resourcePrefix "login_" //给 Module 内的资源名增加前缀, 避免资源名冲突
5 | flavorDimensions "verison"
6 |
7 | productFlavors {
8 | //打包assembleVersionDevDebug
9 | versionDev{
10 | dimension "verison"
11 | }
12 | //gradlew clean assembleVersionTestDebug
13 | versionTest {
14 | dimension "verison"
15 | }
16 | // gradlew clean assembleVersionOnlineRelease
17 | versionOnline{
18 | dimension "verison"
19 | }
20 | }
21 | }
22 |
23 | dependencies {
24 | implementation fileTree(include: ['*.jar'], dir: 'libs')
25 | }
26 |
--------------------------------------------------------------------------------
/module_login/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/module_login/src/androidTest/java/com/mou/login/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mou.login;
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 | * Instrumented 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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.mou.module_login.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/module_login/src/main/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
10 |
13 |
16 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/core/App.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.core
2 |
3 | import com.mou.basemvvm.base.BaseApplication
4 | import com.mou.login.di.component.DaggerAppComponent
5 |
6 | /***
7 | * 该类是module单独运行时候需要的Application类,这里我们不需要实现第三方的实例逻辑,只需要注入AppComponent就好
8 | * 注入代码已经用模版实现,所以这个类不用动
9 | **/
10 |
11 | class App : BaseApplication() {
12 | override fun injectComponent() {
13 | DaggerAppComponent.builder().application(this).build().inject(this)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/core/GlobalConfiguration.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.core
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import androidx.fragment.app.FragmentManager
6 | import com.mou.basemvvm.integration.AppLifeCycles
7 | import com.mou.basemvvm.integration.ConfigModule
8 |
9 | /***
10 | * 该类是整个module可以对整个App的Application/Activity/Fragment的生命周期进行逻辑注入
11 | * 例如我们平时的第三方代码就可以在这里去进行实现
12 | **/
13 |
14 | class GlobalConfiguration : ConfigModule {
15 | override fun injectAppLifecycle(context: Context, lifeCycles: MutableList) {
16 | }
17 |
18 | override fun injectActivityLifecycle(context: Context, lifeCycles: MutableList) {
19 | }
20 |
21 | override fun injectFragmentLifecycle(context: Context, lifeCycles: MutableList) {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/di/component/AppComponent.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.di.component
2 |
3 | import android.app.Application
4 | import com.mou.basemvvm.android.FactoryModule
5 | import com.mou.login.core.App
6 | import com.mou.login.di.module.AppModule
7 | import dagger.BindsInstance
8 | import dagger.Component
9 | import dagger.android.support.AndroidSupportInjectionModule
10 | import javax.inject.Singleton
11 |
12 | /***
13 | * 该类是整个module的dagger需要注入的Conponent
14 | * 相对应的注入实例注入到对应的Module.class中去就好
15 | * Activity/Fragment/ViewModel的实例全在AppModule中include,方便主程序注入
16 | * 这个类也不用动
17 | **/
18 | @Singleton
19 | @Component(modules = [
20 | AndroidSupportInjectionModule::class,
21 | FactoryModule::class,
22 | AppModule::class])
23 | interface AppComponent {
24 | @Component.Builder
25 | interface Builder {
26 | @BindsInstance
27 | fun application(application: Application): Builder
28 |
29 | fun build(): AppComponent
30 | }
31 |
32 | fun inject(application: App){
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/di/module/ActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.di.module
2 |
3 | import com.mou.login.mvvm.view.LoginActivity
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 | /***
8 | * 这里存放module中的Dagger需要注入的Activity的实例
9 | * 例如:
10 | * @ContributesAndroidInjector
11 | * abstract fun contributeXXActivity(): XXActivity
12 | */
13 |
14 | @Module
15 | abstract class ActivityModule {
16 | @ContributesAndroidInjector
17 | abstract fun contributeLoginActivity(): LoginActivity
18 |
19 |
20 |
21 | }
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/di/module/AppModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.di.module
2 |
3 | import android.app.Application
4 | import com.fortunes.commonsdk.network.HttpUrlConstants
5 | import com.fortunes.commonsdk.network.provider.BaseNetProvider
6 | import com.mou.basemvvm.helper.network.NetMgr
7 | import com.mou.login.mvvm.model.repository.ApiService
8 | import dagger.Module
9 | import dagger.Provides
10 | import javax.inject.Singleton
11 |
12 | /***
13 | * 该类提供整个module需要的实例,比如网络请求,数据库等等(记得加上@Provide,@Single注解)
14 | * includes的module提供Activity/Fragment/ViewModel的实例
15 | **/
16 |
17 | @Module(includes = [
18 | ActivityModule::class,
19 | FragmentModule::class,
20 | ViewModelModule::class])
21 | class AppModule {
22 |
23 | @Provides
24 | @Singleton
25 | fun provideService(application: Application) = NetMgr.getRetrofit(HttpUrlConstants.getBaseUrl(), BaseNetProvider(application)).create(
26 | ApiService::class.java)
27 | }
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/di/module/FragmentModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.di.module
2 |
3 | import dagger.Module
4 |
5 | /***
6 | * 该类提供整个module中fragment的实例(这里需要注意所拥有该Fragment的Activity必须实现HasSupportFragmentInjector接口)
7 | * 例如:
8 | * @ContributesAndroidInjector
9 | * abstract fun contributeXXFragment(): XXFragment
10 | */
11 |
12 | @Module
13 | abstract class FragmentModule {
14 | }
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/di/module/ViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.di.module
2 |
3 | import androidx.lifecycle.ViewModel
4 | import com.mou.basemvvm.android.ViewModelKey
5 | import com.mou.login.mvvm.viewmodel.LoginViewModel
6 | import dagger.Binds
7 | import dagger.Module
8 | import dagger.multibindings.IntoMap
9 |
10 | /***
11 | * 该类主要提供整个module的ViewModel的实例
12 | * 例如:
13 | * @Binds
14 | * @IntoMap
15 | * @ViewModelKey(HomeViewModel::class)
16 | * abstract fun bindHomeViewModel(viewModel: HomeViewModel): ViewModel
17 | **/
18 |
19 | @Module
20 | abstract class ViewModelModule {
21 |
22 | @Binds
23 | @IntoMap
24 | @ViewModelKey(LoginViewModel::class)
25 | abstract fun bindLoginViewModel(viewModel: LoginViewModel): ViewModel
26 | }
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/mvvm/model/data/LoginBean.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.mvvm.model.data
2 |
3 | /**
4 | * @FileName: LoginBean.java
5 | * @author: villa_mou
6 | * @date: 06-16:19
7 | * @version V1.0 <描述当前版本功能>
8 | * @desc
9 | */
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/mvvm/model/repository/ApiService.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.mvvm.model.repository
2 |
3 | /**
4 | */
5 |
6 | interface ApiService {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/mvvm/view/LoginActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.mvvm.view
2 |
3 | import com.alibaba.android.arouter.facade.annotation.Route
4 | import com.fortunes.commonsdk.core.RouterConstants
5 | import com.mou.basemvvm.base.BaseActivity
6 | import com.mou.login.R
7 | import com.mou.login.databinding.LoginActivityLoginBinding
8 | import com.mou.login.mvvm.viewmodel.LoginViewModel
9 |
10 | /**
11 | * @FileName: LoginActivity.java
12 | * @author: villa_mou
13 | * @date: 06-16:18
14 | * @version V1.0 <描述当前版本功能>
15 | * @desc
16 | */
17 | @Route(path = RouterConstants.LOGIN_ACTIVITY)
18 | class LoginActivity: BaseActivity() {
19 |
20 | private val mViewModel by lazy {
21 | createVM()
22 | }
23 | override fun getLayoutId()= R.layout.login_activity_login
24 |
25 | override fun initView() {
26 | }
27 |
28 | override fun initData() {
29 | }
30 | }
--------------------------------------------------------------------------------
/module_login/src/main/java/com/mou/login/mvvm/viewmodel/LoginViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.mou.login.mvvm.viewmodel
2 |
3 | import com.mou.basemvvm.base.BaseViewModel
4 | import com.mou.login.mvvm.model.repository.ApiService
5 | import javax.inject.Inject
6 |
7 | /**
8 | * @FileName: LoginViewModel.java
9 | * @author: villa_mou
10 | * @date: 06-16:19
11 | * @version V1.0 <描述当前版本功能>
12 | * @desc
13 | */
14 | class LoginViewModel @Inject constructor(private val apiService: ApiService) : BaseViewModel() {
15 |
16 | }
--------------------------------------------------------------------------------
/module_login/src/main/release/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/module_login/src/main/res/layout/login_activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
17 |
21 |
25 |
26 |
--------------------------------------------------------------------------------
/module_login/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 登录模块
3 |
4 |
--------------------------------------------------------------------------------
/module_login/src/test/java/com/mou/login/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mou.login;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/module_mine/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/module_mine/build.gradle:
--------------------------------------------------------------------------------
1 | apply from: "../component_build.gradle"
2 |
3 | android {
4 | resourcePrefix "mine_" //给 Module 内的资源名增加前缀, 避免资源名冲突
5 | flavorDimensions "verison"
6 | productFlavors {
7 | //打包assembleVersionDevDebug
8 | versionDev{
9 | dimension "verison"
10 | }
11 | //gradlew clean assembleVersionTestDebug
12 | versionTest {
13 | dimension "verison"
14 | }
15 | // gradlew clean assembleVersionOnlineRelease
16 | versionOnline{
17 | dimension "verison"
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation fileTree(include: ['*.jar'], dir: 'libs')
24 | }
25 |
--------------------------------------------------------------------------------
/module_mine/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/module_mine/src/androidTest/java/com/mou/mine/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.mou.mine;
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 | * Instrumented 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() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.mou.module_mine.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/module_mine/src/main/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
10 |
13 |
16 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/core/App.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.core
2 |
3 | import com.mou.basemvvm.base.BaseApplication
4 | import com.mou.mine.di.component.DaggerAppComponent
5 |
6 | /***
7 | * 该类是module单独运行时候需要的Application类,这里我们不需要实现第三方的实例逻辑,只需要注入AppComponent就好
8 | * 注入代码已经用模版实现,所以这个类不用动
9 | **/
10 |
11 | class App : BaseApplication() {
12 | override fun injectComponent() {
13 | DaggerAppComponent.builder().application(this).build().inject(this)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/core/GlobalConfiguration.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.core
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import androidx.fragment.app.FragmentManager
6 | import com.mou.basemvvm.integration.AppLifeCycles
7 | import com.mou.basemvvm.integration.ConfigModule
8 |
9 | /***
10 | * 该类是整个module可以对整个App的Application/Activity/Fragment的生命周期进行逻辑注入
11 | * 例如我们平时的第三方代码就可以在这里去进行实现
12 | **/
13 |
14 | class GlobalConfiguration : ConfigModule {
15 | override fun injectAppLifecycle(context: Context, lifeCycles: MutableList) {
16 | }
17 |
18 | override fun injectActivityLifecycle(context: Context, lifeCycles: MutableList) {
19 | }
20 |
21 | override fun injectFragmentLifecycle(context: Context, lifeCycles: MutableList) {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/di/component/AppComponent.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.di.component
2 |
3 | import android.app.Application
4 | import com.mou.basemvvm.android.FactoryModule
5 | import com.mou.mine.core.App
6 | import com.mou.mine.di.module.AppModule
7 | import dagger.BindsInstance
8 | import dagger.Component
9 | import dagger.android.support.AndroidSupportInjectionModule
10 | import javax.inject.Singleton
11 |
12 | /***
13 | * 该类是整个module的dagger需要注入的Conponent
14 | * 相对应的注入实例注入到对应的Module.class中去就好
15 | * Activity/Fragment/ViewModel的实例全在AppModule中include,方便主程序注入
16 | * 这个类也不用动
17 | **/
18 | @Singleton
19 | @Component(modules = [
20 | AndroidSupportInjectionModule::class,
21 | FactoryModule::class,
22 | AppModule::class])
23 | interface AppComponent {
24 | @Component.Builder
25 | interface Builder {
26 | @BindsInstance
27 | fun application(application: Application): Builder
28 |
29 | fun build(): AppComponent
30 | }
31 |
32 | fun inject(application: App){
33 |
34 | }
35 | }
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/di/module/ActivityModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.di.module
2 |
3 | import com.mou.mine.mvvm.view.MineActivity
4 | import dagger.Module
5 | import dagger.android.ContributesAndroidInjector
6 |
7 | /***
8 | * 这里存放module中的Dagger需要注入的Activity的实例
9 | * 例如:
10 | * @ContributesAndroidInjector
11 | * abstract fun contributeXXActivity(): XXActivity
12 | */
13 |
14 | @Module
15 | abstract class ActivityModule {
16 | @ContributesAndroidInjector
17 | abstract fun contributeMineActivity(): MineActivity
18 |
19 | }
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/di/module/AppModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.di.module
2 |
3 | import android.app.Application
4 | import com.fortunes.commonsdk.network.HttpUrlConstants
5 | import com.fortunes.commonsdk.network.provider.BaseNetProvider
6 | import com.mou.basemvvm.helper.network.NetMgr
7 | import com.mou.mine.mvvm.model.repository.ApiService
8 | import dagger.Module
9 | import dagger.Provides
10 | import javax.inject.Singleton
11 |
12 | /***
13 | * 该类提供整个module需要的实例,比如网络请求,数据库等等(记得加上@Provide,@Single注解)
14 | * includes的module提供Activity/Fragment/ViewModel的实例
15 | **/
16 |
17 | @Module(includes = [
18 | ActivityModule::class,
19 | FragmentModule::class,
20 | ViewModelModule::class])
21 | class AppModule {
22 |
23 | @Provides
24 | @Singleton
25 | fun provideService(application: Application) = NetMgr.getRetrofit(HttpUrlConstants.getBaseUrl(), BaseNetProvider(application)).create(
26 | ApiService::class.java)
27 | }
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/di/module/FragmentModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.di.module
2 |
3 | import dagger.Module
4 |
5 | /***
6 | * 该类提供整个module中fragment的实例(这里需要注意所拥有该Fragment的Activity必须实现HasSupportFragmentInjector接口)
7 | * 例如:
8 | * @ContributesAndroidInjector
9 | * abstract fun contributeXXFragment(): XXFragment
10 | */
11 |
12 | @Module
13 | abstract class FragmentModule {
14 | }
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/di/module/ViewModelModule.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.di.module
2 |
3 | import androidx.lifecycle.ViewModel
4 | import com.mou.basemvvm.android.ViewModelKey
5 | import com.mou.mine.mvvm.viewmodel.MineViewModel
6 | import dagger.Binds
7 | import dagger.Module
8 | import dagger.multibindings.IntoMap
9 |
10 | /***
11 | * 该类主要提供整个module的ViewModel的实例
12 | * 例如:
13 | * @Binds
14 | * @IntoMap
15 | * @ViewModelKey(HomeViewModel::class)
16 | * abstract fun bindHomeViewModel(viewModel: HomeViewModel): ViewModel
17 | **/
18 |
19 | @Module
20 | abstract class ViewModelModule {
21 |
22 | @Binds
23 | @IntoMap
24 | @ViewModelKey(MineViewModel::class)
25 | abstract fun bindMineViewModel(viewModel: MineViewModel): ViewModel
26 | }
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/mvvm/model/data/mineBean.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.mvvm.model.data
2 |
3 | /**
4 | * @FileName: LoginBean.java
5 | * @author: villa_mou
6 | * @date: 06-16:19
7 | * @version V1.0 <描述当前版本功能>
8 | * @desc
9 | */
10 |
11 | data class MineBean(
12 | val curPage: Int,
13 | val datas: List,
14 | val offset: Int,
15 | val over: Boolean,
16 | val pageCount: Int,
17 | val size: Int,
18 | val total: Int
19 | )
20 |
21 | data class SubData(
22 | val apkLink: String,
23 | val author: String,
24 | val chapterId: Int,
25 | val chapterName: String,
26 | val collect: Boolean,
27 | val courseId: Int,
28 | val desc: String,
29 | val envelopePic: String,
30 | val fresh: Boolean,
31 | val id: Int,
32 | val link: String,
33 | val niceDate: String,
34 | val origin: String,
35 | val prefix: String,
36 | val projectLink: String,
37 | val publishTime: Long,
38 | val superChapterId: Int,
39 | val superChapterName: String,
40 | val title: String,
41 | val type: Int,
42 | val userId: Int,
43 | val visible: Int,
44 | val zan: Int
45 | )
46 |
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/mvvm/model/repository/ApiService.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.mvvm.model.repository
2 |
3 | import com.fortunes.commonsdk.network.bean.BaseBean
4 | import com.mou.mine.mvvm.model.data.MineBean
5 | import io.reactivex.Single
6 | import retrofit2.http.GET
7 | import retrofit2.http.Path
8 | import retrofit2.http.Query
9 |
10 | /**
11 | */
12 |
13 | interface ApiService {
14 | @GET("project/list/{pageNum}/json")
15 | fun getProjectList(@Path("pageNum") pageNum: Int, @Query("cid") cid: Int):Single>
16 | }
17 |
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/mvvm/view/MineActivity.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.mvvm.view
2 |
3 | import android.view.View
4 | import com.alibaba.android.arouter.facade.annotation.Route
5 | import com.fortunes.commonsdk.core.RouterConstants
6 | import com.fortunes.commonsdk.network.onHttpSubscribeNoToast
7 | import com.guoyang.recyclerviewbindingadapter.ItemClickPresenter
8 | import com.guoyang.recyclerviewbindingadapter.adapter.SingleTypeAdapter
9 | import com.mou.basemvvm.base.BaseActivity
10 | import com.mou.basemvvm.helper.extens.bindStatusOrLifeCycle
11 | import com.mou.basemvvm.helper.extens.toast
12 | import com.mou.basemvvm.helper.listener.RefreshPresenter
13 | import com.mou.mine.R
14 | import com.mou.mine.databinding.MineActivityMineBinding
15 | import com.mou.mine.mvvm.viewmodel.MineItemViewModel
16 | import com.mou.mine.mvvm.viewmodel.MineViewModel
17 | import kotlinx.android.synthetic.main.mine_activity_mine.*
18 |
19 | /**
20 | * @FileName: LoginActivity.java
21 | * @author: villa_mou
22 | * @date: 06-16:18
23 | * @version V1.0 <描述当前版本功能>
24 | * @desc
25 | */
26 | @Route(path = RouterConstants.MINE_ACTIVITY)
27 | class MineActivity : BaseActivity(), RefreshPresenter, ItemClickPresenter {
28 | override fun getLayoutId() = R.layout.mine_activity_mine
29 | override fun loadData(isRefresh: Boolean) = loadVMData(isRefresh)
30 | override fun initData() = loadVMData(true)
31 | private val mViewModel by lazy {
32 | createVM()
33 | }
34 | private val mAdapter by lazy {
35 | SingleTypeAdapter(this, R.layout.mine_my_item_order, mViewModel.observableList)
36 | .apply { this.itemPresenter = this@MineActivity }
37 | }
38 |
39 | override fun initView() {
40 | mBinding.apply {
41 | viewModel = mViewModel
42 | this.refreshPresenter = this@MineActivity
43 | recyclerView.adapter = mAdapter
44 | }
45 | }
46 |
47 | override fun onItemClick(v: View, position: Int, item: MineItemViewModel) {
48 | toast("position=" + position)
49 | }
50 |
51 | private fun loadVMData(isRefresh: Boolean) =
52 | mViewModel.getProjectList(isRefresh, 294)
53 | .bindStatusOrLifeCycle(isRefresh, viewModel = mViewModel, owner = this@MineActivity)
54 | .onHttpSubscribeNoToast(this@MineActivity) {
55 | }
56 | }
--------------------------------------------------------------------------------
/module_mine/src/main/java/com/mou/mine/mvvm/viewmodel/MineViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.mou.mine.mvvm.viewmodel
2 |
3 | import com.fortunes.commonsdk.network.bean.BaseBean
4 | import com.guoyang.recyclerviewbindingadapter.observable.ObservableAdapterList
5 | import com.mou.basemvvm.base.BaseViewModel
6 | import com.mou.basemvvm.helper.extens.ObservableItemField
7 | import com.mou.basemvvm.helper.extens.async
8 | import com.mou.basemvvm.helper.network.EmptyException
9 | import com.mou.mine.mvvm.model.data.MineBean
10 | import com.mou.mine.mvvm.model.data.SubData
11 | import com.mou.mine.mvvm.model.repository.ApiService
12 | import io.reactivex.Single
13 | import javax.inject.Inject
14 |
15 | /**
16 | * @FileName: MineViewModel.java
17 | * @author: villa_mou
18 | * @date: 06-16:19
19 | * @version V1.0 <描述当前版本功能>
20 | * @desc
21 | */
22 | class MineViewModel @Inject constructor(private val apiService: ApiService) : BaseViewModel() {
23 | private var page = 1
24 | val observableList = ObservableAdapterList()
25 | fun getProjectList(isRefresh: Boolean, cid: Int): Single> {
26 | return apiService
27 | .getProjectList(
28 | if (isRefresh) {
29 | page = 1
30 | page
31 | } else page, cid
32 | )
33 | .async()
34 | .doOnSuccess {
35 | if (it.data.datas.isNotEmpty()) {
36 | val list = mutableListOf()
37 | it.data.datas.forEach { orderBean: SubData ->
38 | list.add(MineItemViewModel(orderBean))
39 | }
40 | page++
41 | if (isRefresh) {
42 | observableList.setNewData(list)
43 | } else {
44 | observableList.addAll(list)
45 | }
46 | } else {
47 | throw EmptyException()
48 | }
49 | }
50 | }
51 | }
52 |
53 | class MineItemViewModel(bean: SubData) {
54 | val chapterName = ObservableItemField()
55 | val desc = ObservableItemField()
56 | val data = bean
57 |
58 | init {
59 | chapterName.set(bean.chapterName)
60 | desc.set(bean.desc)
61 | }
62 | }
--------------------------------------------------------------------------------
/module_mine/src/main/release/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/module_mine/src/main/res/layout/mine_activity_mine.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
16 |
17 |
18 |
23 |
24 |
29 |
30 |
35 |
36 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/module_mine/src/main/res/layout/mine_my_item_order.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
15 |
16 |
19 |
20 |
21 |
22 |
33 |
34 |
40 |
41 |
48 |
49 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/module_mine/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 个人中心模块
3 |
4 |
--------------------------------------------------------------------------------
/module_mine/src/test/java/com/mou/mine/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.mou.mine;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/mvvm.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mouxuefei/MvvmModulePatternSample/fcec4d40e882dbd209bb6bc59ba84f3aee1f71ce/mvvm.jks
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':lib_basemvvm', ':lib_common', ':module_login', ':module_mine'
2 |
--------------------------------------------------------------------------------