├── .gitignore ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── release │ ├── app-release.apk │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wjx │ │ └── android │ │ └── wanandroidmvvm │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── android.json │ │ └── splash │ │ │ ├── img_0.png │ │ │ ├── img_1.png │ │ │ ├── img_10.png │ │ │ ├── img_11.png │ │ │ ├── img_12.png │ │ │ ├── img_13.png │ │ │ ├── img_14.png │ │ │ ├── img_15.png │ │ │ ├── img_16.png │ │ │ ├── img_17.png │ │ │ ├── img_18.png │ │ │ ├── img_19.png │ │ │ ├── img_2.png │ │ │ ├── img_20.png │ │ │ ├── img_21.png │ │ │ ├── img_22.png │ │ │ ├── img_23.png │ │ │ ├── img_24.png │ │ │ ├── img_25.png │ │ │ ├── img_26.png │ │ │ ├── img_27.png │ │ │ ├── img_28.png │ │ │ ├── img_29.png │ │ │ ├── img_3.png │ │ │ ├── img_30.png │ │ │ ├── img_31.png │ │ │ ├── img_32.png │ │ │ ├── img_33.png │ │ │ ├── img_34.png │ │ │ ├── img_35.png │ │ │ ├── img_36.png │ │ │ ├── img_37.png │ │ │ ├── img_38.png │ │ │ ├── img_39.png │ │ │ ├── img_4.png │ │ │ ├── img_40.png │ │ │ ├── img_41.png │ │ │ ├── img_5.png │ │ │ ├── img_6.png │ │ │ ├── img_7.png │ │ │ ├── img_8.png │ │ │ └── img_9.png │ ├── java │ │ └── com │ │ │ └── wjx │ │ │ └── android │ │ │ └── wanandroidmvvm │ │ │ ├── base │ │ │ ├── observer │ │ │ │ └── BaseObserver.kt │ │ │ ├── repository │ │ │ │ ├── ApiRepository.kt │ │ │ │ └── BaseRepository.kt │ │ │ ├── view │ │ │ │ ├── BaseActivity.kt │ │ │ │ ├── BaseApplication.kt │ │ │ │ ├── BaseFragment.kt │ │ │ │ ├── BaseLifeCycleActivity.kt │ │ │ │ └── BaseLifeCycleFragment.kt │ │ │ └── viewmodel │ │ │ │ └── BaseViewModel.kt │ │ │ ├── common │ │ │ ├── callback │ │ │ │ ├── EmptyCallBack.kt │ │ │ │ ├── ErrorCallBack.kt │ │ │ │ └── LoadingCallBack.kt │ │ │ ├── permission │ │ │ │ ├── PermissionFragment.kt │ │ │ │ ├── PermissionResult.kt │ │ │ │ └── Permissions.kt │ │ │ ├── state │ │ │ │ ├── LoginState.kt │ │ │ │ ├── LogoutState.kt │ │ │ │ ├── State.kt │ │ │ │ ├── StateType.kt │ │ │ │ ├── UserInfo.kt │ │ │ │ ├── UserState.kt │ │ │ │ └── callback │ │ │ │ │ ├── CollectListener.kt │ │ │ │ │ ├── LoginSuccessListener.kt │ │ │ │ │ └── LoginSuccessState.kt │ │ │ └── utils │ │ │ │ ├── AppManager.kt │ │ │ │ ├── ChangeThemeEvent.kt │ │ │ │ ├── ColorUtil.kt │ │ │ │ ├── CommonUtil.kt │ │ │ │ ├── Constant.kt │ │ │ │ ├── DataCleanManager.kt │ │ │ │ ├── DateUtil.kt │ │ │ │ ├── DisplayUtil.kt │ │ │ │ ├── GlideImageLoader.kt │ │ │ │ ├── KeyBoardUtil.kt │ │ │ │ ├── Reified.kt │ │ │ │ ├── RevealUtil.kt │ │ │ │ ├── RoomHelper.kt │ │ │ │ ├── SPreference.kt │ │ │ │ ├── SpeedLayoutManager.kt │ │ │ │ └── UpdateManager.kt │ │ │ ├── custom │ │ │ ├── CustomUserAvatar.kt │ │ │ ├── DrawableScaleFadeFactory.kt │ │ │ ├── LikeView.kt │ │ │ ├── behavior │ │ │ │ └── FloatScrollBehavior.kt │ │ │ ├── graylayout │ │ │ │ └── GrayFrameLayout.kt │ │ │ ├── interpolator │ │ │ │ └── CustomScaleInterpolator.kt │ │ │ └── loadingview │ │ │ │ ├── Shape.kt │ │ │ │ ├── ShapeLoadingView.kt │ │ │ │ └── ShapeView.kt │ │ │ ├── module │ │ │ ├── account │ │ │ │ ├── model │ │ │ │ │ ├── LoginResponse.kt │ │ │ │ │ └── RegisterResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── AccountRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── LoginActivity.kt │ │ │ │ │ └── RegisterActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── AccountViewModel.kt │ │ │ ├── activity │ │ │ │ ├── ArticleDetailActivity.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ └── SplashActivity.kt │ │ │ ├── collect │ │ │ │ ├── model │ │ │ │ │ └── CollectResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── CollectRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── AddCollectActivity.kt │ │ │ │ │ └── CollectArticleListActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── CollectViewModel.kt │ │ │ ├── common │ │ │ │ ├── adapter │ │ │ │ │ └── ArticleAdapter.kt │ │ │ │ ├── model │ │ │ │ │ └── Article.kt │ │ │ │ ├── repository │ │ │ │ │ └── ArticleRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── ArticleListActivity.kt │ │ │ │ │ └── ArticleListFragment.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── ArticleViewModel.kt │ │ │ ├── footprint │ │ │ │ ├── model │ │ │ │ │ ├── dao │ │ │ │ │ │ └── FootPrintDao.kt │ │ │ │ │ └── database │ │ │ │ │ │ └── FootPrintDataBase.kt │ │ │ │ ├── repository │ │ │ │ │ └── FootPrintRepository.kt │ │ │ │ ├── view │ │ │ │ │ └── FootPrintActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── FootPrintViewModel.kt │ │ │ ├── home │ │ │ │ ├── model │ │ │ │ │ ├── BannerResponse.kt │ │ │ │ │ └── HomeArticleResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── HomeRepository.kt │ │ │ │ ├── view │ │ │ │ │ └── HomeFragment.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── HomeViewModel.kt │ │ │ ├── meshare │ │ │ │ ├── adapter │ │ │ │ │ └── MeShareAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── MeShareArticleResponse.kt │ │ │ │ │ └── MeShareResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── MeShareRepository.kt │ │ │ │ ├── view │ │ │ │ │ └── MeShareActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── MeShareViewModel.kt │ │ │ ├── navigation │ │ │ │ ├── adapter │ │ │ │ │ ├── NavigationLabelAdapter.kt │ │ │ │ │ └── NavigationTabAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── NavigationLabelResponse.kt │ │ │ │ │ └── NavigationTabNameResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── NavigationRepository.kt │ │ │ │ ├── view │ │ │ │ │ └── NavigationFragment.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── NavigationViewModel.kt │ │ │ ├── project │ │ │ │ ├── adapter │ │ │ │ │ ├── ProjectArticleAdapter.kt │ │ │ │ │ └── ProjectTabAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── Project.kt │ │ │ │ │ ├── ProjectResponse.kt │ │ │ │ │ └── ProjectTabResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── ProjectRespository.kt │ │ │ │ ├── view │ │ │ │ │ ├── ProjectArticleFragment.kt │ │ │ │ │ └── ProjectFragment.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── ProjectViewModel.kt │ │ │ ├── question │ │ │ │ ├── model │ │ │ │ │ └── QuestionResponse.kt │ │ │ │ ├── questionrepository │ │ │ │ │ └── QuestionRepository.kt │ │ │ │ ├── view │ │ │ │ │ └── QuestionArticleListActivity.kt │ │ │ │ └── viewModel │ │ │ │ │ └── QuestionViewModel.kt │ │ │ ├── rank │ │ │ │ ├── adapter │ │ │ │ │ ├── IntegralHistoryAdapter.kt │ │ │ │ │ └── RankAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── IntegralHistoryListResponse.kt │ │ │ │ │ ├── IntegralHistoryResponse.kt │ │ │ │ │ ├── IntegralResponse.kt │ │ │ │ │ └── RankResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── RankRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── IntegralHistoryActivity.kt │ │ │ │ │ └── RankActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── RankViewModel.kt │ │ │ ├── search │ │ │ │ ├── adapter │ │ │ │ │ └── SearchHistoryAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── HotKeyResponse.kt │ │ │ │ │ ├── SearchResultResponse.kt │ │ │ │ │ ├── bean │ │ │ │ │ │ └── SearchHistory.kt │ │ │ │ │ ├── dao │ │ │ │ │ │ └── SearchHistoryDao.kt │ │ │ │ │ └── db │ │ │ │ │ │ └── SearchHistoryDataBase.kt │ │ │ │ ├── repository │ │ │ │ │ └── SearchRepostiory.kt │ │ │ │ ├── view │ │ │ │ │ └── SearchActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── SearchViewModel.kt │ │ │ ├── setting │ │ │ │ ├── SettingActivity.kt │ │ │ │ └── SettingFragment.kt │ │ │ ├── square │ │ │ │ ├── model │ │ │ │ │ └── SquareResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── SquareRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── ShareArticleActivity.kt │ │ │ │ │ └── SquareActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── SquareViewModel.kt │ │ │ ├── system │ │ │ │ ├── adapter │ │ │ │ │ └── SystemAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── SystemArticleResponse.kt │ │ │ │ │ ├── SystemLabelResponse.kt │ │ │ │ │ └── SystemTabNameResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── SystemRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── SystemArticleListActivity.kt │ │ │ │ │ └── SystemFragment.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── SystemViewModel.kt │ │ │ ├── todo │ │ │ │ ├── adapter │ │ │ │ │ └── TodoAdapter.kt │ │ │ │ ├── model │ │ │ │ │ ├── TodoPageResponse.kt │ │ │ │ │ └── TodoResponse.kt │ │ │ │ ├── repository │ │ │ │ │ └── TodoRepository.kt │ │ │ │ ├── view │ │ │ │ │ ├── EditTodoActivity.kt │ │ │ │ │ └── TodoActivity.kt │ │ │ │ └── viewmodel │ │ │ │ │ └── TodoViewModel.kt │ │ │ └── wechat │ │ │ │ ├── adapter │ │ │ │ └── WeChatTabAdapter.kt │ │ │ │ ├── model │ │ │ │ ├── WeChatArticleResponse.kt │ │ │ │ └── WeChatTabNameResponse.kt │ │ │ │ ├── repository │ │ │ │ └── WeChatRepository.kt │ │ │ │ ├── view │ │ │ │ ├── WeChatArticleFragment.kt │ │ │ │ └── WeChatFragment.kt │ │ │ │ └── viewmodel │ │ │ │ └── WeChatViewModel.kt │ │ │ └── network │ │ │ ├── ApiService.kt │ │ │ ├── Ext.kt │ │ │ ├── NetExceptionHandle.kt │ │ │ ├── RetrofitFactory.kt │ │ │ └── response │ │ │ ├── BaseResponse.kt │ │ │ └── EmptyResponse.kt │ └── res │ │ ├── anim │ │ ├── alpha_in.xml │ │ ├── alpha_out.xml │ │ ├── anim_left_out.xml │ │ ├── anim_right_in.xml │ │ ├── animo_alph_close.xml │ │ ├── animo_alph_open.xml │ │ ├── item_animation_fall_down.xml │ │ ├── layout_animator_fall_down.xml │ │ ├── push_bottom_in.xml │ │ ├── push_bottom_out.xml │ │ ├── translate_dialog_in.xml │ │ └── translate_dialog_out.xml │ │ ├── drawable-night-xxxhdpi │ │ ├── empty.png │ │ └── error.png │ │ ├── drawable-night │ │ ├── ic_article_share.png │ │ ├── ic_browser.png │ │ ├── ic_close.png │ │ └── ic_qrcode.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xxxhdpi │ │ ├── empty.png │ │ ├── error.png │ │ ├── ic_add.png │ │ ├── ic_article_share.png │ │ ├── ic_back.png │ │ ├── ic_browser.png │ │ ├── ic_clear_all.png │ │ ├── ic_close.png │ │ ├── ic_delete_share.png │ │ ├── ic_fab.png │ │ ├── ic_footprint.png │ │ ├── ic_help.png │ │ ├── ic_history.png │ │ ├── ic_integral.png │ │ ├── ic_logo.png │ │ ├── ic_logout.png │ │ ├── ic_more.png │ │ ├── ic_qrcode.png │ │ ├── ic_question.png │ │ ├── ic_rank.png │ │ ├── ic_record.png │ │ ├── ic_scan.png │ │ ├── ic_search.png │ │ ├── ic_setting.png │ │ ├── ic_share.png │ │ ├── ic_share_square.png │ │ ├── ic_square.png │ │ ├── ic_theme.png │ │ ├── ic_todo.png │ │ ├── ic_up.png │ │ ├── navigation_home.png │ │ ├── navigation_navigation.png │ │ ├── navigation_project.png │ │ ├── navigation_system.png │ │ ├── navigation_wechat.png │ │ ├── shortcut_search.png │ │ ├── shortcut_wenda.png │ │ ├── todo_done.png │ │ ├── todo_more.png │ │ ├── todo_not_done.png │ │ └── todo_tag.png │ │ ├── drawable │ │ ├── collect_selector.xml │ │ ├── collect_selector_icon.xml │ │ ├── color_cursor.xml │ │ ├── edit_shap.xml │ │ ├── flow_selector.xml │ │ ├── ic_collect.xml │ │ ├── ic_highlight_blue_open_24dp.xml │ │ ├── ic_highlight_white_close_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── loading_shadow.xml │ │ ├── search_edit_background.xml │ │ ├── shape_dialog.xml │ │ ├── text_selector.xml │ │ ├── title_lable_green.xml │ │ ├── title_lable_red.xml │ │ ├── todo_foreground.xml │ │ └── uncollect_selector_icon.xml │ │ ├── layout │ │ ├── activity_add_collect.xml │ │ ├── activity_article_detail.xml │ │ ├── activity_edit_todo.xml │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_rank.xml │ │ ├── activity_register.xml │ │ ├── activity_search.xml │ │ ├── activity_setting.xml │ │ ├── activity_share_article.xml │ │ ├── activity_splash.xml │ │ ├── article_item.xml │ │ ├── custom_bar.xml │ │ ├── custom_search.xml │ │ ├── dialog_edit_todo.xml │ │ ├── dialog_handle_todo.xml │ │ ├── dialog_qrcode.xml │ │ ├── flow_layout.xml │ │ ├── fragment_article_list.xml │ │ ├── fragment_navigation.xml │ │ ├── fragment_project.xml │ │ ├── fragment_wechat.xml │ │ ├── history_foot.xml │ │ ├── integral_header_view.xml │ │ ├── integral_history_item.xml │ │ ├── layout_drawer_header.xml │ │ ├── layout_empty.xml │ │ ├── layout_error.xml │ │ ├── layout_home_headview.xml │ │ ├── layout_loading.xml │ │ ├── layout_popup.xml │ │ ├── layout_toolbar.xml │ │ ├── loading_view.xml │ │ ├── navigation_item.xml │ │ ├── navigation_label_item.xml │ │ ├── project_item.xml │ │ ├── rank_item.xml │ │ ├── search_history_item.xml │ │ ├── system_item.xml │ │ └── todo_item.xml │ │ ├── menu │ │ ├── drawer_menu.xml │ │ ├── navigation_bottom_menu.xml │ │ └── search_menu.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 │ │ ├── navigation │ │ └── nav_graph.xml │ │ ├── values-night │ │ └── colors.xml │ │ ├── values-sw360dp-v13 │ │ └── values-sw360dp-v13.xml │ │ ├── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── network_security_config.xml │ │ ├── setting_fragment.xml │ │ └── shortcuts.xml │ └── test │ └── java │ └── com │ └── wjx │ └── android │ └── wanandroidmvvm │ └── ExampleUnitTest.kt ├── build.gradle ├── config.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── mvvm ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wjx │ │ └── android │ │ └── mvvm │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── wjx │ │ └── android │ │ └── mvvm │ │ ├── BaseApplication.kt │ │ ├── common │ │ ├── permission │ │ │ ├── PermissionFragment.kt │ │ │ ├── PermissionResult.kt │ │ │ └── Permissions.kt │ │ ├── state │ │ │ ├── State.kt │ │ │ └── StateType.kt │ │ └── utils │ │ │ ├── AppManager.kt │ │ │ ├── ColorUtil.kt │ │ │ ├── CommonUtil.kt │ │ │ ├── Constant.kt │ │ │ ├── DateUtil.kt │ │ │ ├── DisplayUtil.kt │ │ │ ├── KeyBoardUtil.kt │ │ │ ├── Reified.kt │ │ │ ├── RevealUtil.kt │ │ │ ├── SPreference.kt │ │ │ └── SpeedLayoutManager.kt │ │ ├── network │ │ ├── ApiService.kt │ │ ├── Ext.kt │ │ ├── NetExceptionHandle.kt │ │ ├── RetrofitFactory.kt │ │ └── response │ │ │ ├── BaseResponse.kt │ │ │ └── EmptyResponse.kt │ │ ├── repository │ │ └── BaseRepository.kt │ │ ├── view │ │ ├── BaseActivity.kt │ │ ├── BaseFragment.kt │ │ ├── BaseLifeCycleActivity.kt │ │ └── BaseLifeCycleFragment.kt │ │ └── viewmodel │ │ └── BaseViewModel.kt │ └── test │ └── java │ └── com │ └── wjx │ └── android │ └── mvvm │ └── ExampleUnitTest.kt └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.aar 3 | *.ap_ 4 | *.aab 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | # Uncomment the following line in case you need and you don't have the release build type files in your app 17 | # release/ 18 | 19 | # Gradle files 20 | .gradle/ 21 | build/ 22 | 23 | # Local configuration file (sdk path, etc) 24 | local.properties 25 | 26 | # Proguard folder generated by Eclipse 27 | proguard/ 28 | 29 | # Log Files 30 | *.log 31 | 32 | # Android Studio Navigation editor temp files 33 | .navigation/ 34 | 35 | # Android Studio captures folder 36 | captures/ 37 | 38 | # IntelliJ 39 | *.iml 40 | .idea/workspace.xml 41 | .idea/tasks.xml 42 | .idea/gradle.xml 43 | .idea/assetWizardSettings.xml 44 | .idea/dictionaries 45 | .idea/libraries 46 | # Android Studio 3 in .gitignore file. 47 | .idea/caches 48 | .idea/modules.xml 49 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 50 | .idea/navEditor.xml 51 | 52 | # Keystore files 53 | # Uncomment the following lines if you do not want to check your keystore files in. 54 | #*.jks 55 | #*.keystore 56 | 57 | # External native build folder generated in Android Studio 2.2 and later 58 | .externalNativeBuild 59 | .cxx/ 60 | 61 | # Google Services (e.g. APIs or Firebase) 62 | # google-services.json 63 | 64 | # Freeline 65 | freeline.py 66 | freeline/ 67 | freeline_project_description.json 68 | 69 | # fastlane 70 | fastlane/report.xml 71 | fastlane/Preview.html 72 | fastlane/screenshots 73 | fastlane/test_output 74 | fastlane/readme.md 75 | 76 | # Version control 77 | vcs.xml 78 | 79 | # lint 80 | lint/intermediates/ 81 | lint/generated/ 82 | lint/outputs/ 83 | lint/tmp/ 84 | # lint/reports/ 85 | 86 | .idea/ 87 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | apply plugin: 'kotlin-kapt' 8 | 9 | def rootAndroidId = rootProject.ext.android 10 | def appId = rootProject.ext.appId 11 | def support = rootProject.ext.dependencies 12 | 13 | android { 14 | compileSdkVersion rootAndroidId.compileSdkVersion 15 | buildToolsVersion rootAndroidId.buildToolsVersion 16 | defaultConfig { 17 | applicationId appId.app 18 | minSdkVersion rootAndroidId.minSdkVersion 19 | targetSdkVersion rootAndroidId.targetSdkVersion 20 | versionCode rootAndroidId.versionCode 21 | versionName rootAndroidId.versionName 22 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 23 | ndk { 24 | //设置支持的SO库架构 25 | abiFilters "armeabi-v7a", "arm64-v8a" 26 | } 27 | } 28 | dataBinding { 29 | enabled = true 30 | } 31 | } 32 | 33 | kapt { 34 | useBuildCache = true 35 | javacOptions { 36 | option("-Xmaxerrs", 500) 37 | } 38 | } 39 | 40 | dependencies { 41 | implementation fileTree(dir: 'libs', include: ['*.jar']) 42 | implementation support.appcompat 43 | kapt "androidx.room:room-compiler:2.2.5" 44 | debugImplementation 'com.amitshekhar.android:debug-db:1.0.6' 45 | support.each { k, v -> implementation v } 46 | implementation project(':mvvm') 47 | testImplementation 'junit:junit:4.12' 48 | androidTestImplementation 'androidx.test.ext:junit:1.1.0' 49 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 50 | } 51 | -------------------------------------------------------------------------------- /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/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "com.wjx.android.wanandroidmvvm", 8 | "variantName": "release", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "properties": [], 14 | "versionCode": 3, 15 | "versionName": "3", 16 | "enabled": true, 17 | "outputFile": "app-release.apk" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /app/src/androidTest/java/com/wjx/android/wanandroidmvvm/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.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.getInstrumentation().targetContext 22 | assertEquals("com.wjx.android.wanandroidmvvm", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_0.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_1.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_10.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_11.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_12.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_13.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_14.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_15.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_16.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_17.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_18.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_19.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_2.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_20.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_21.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_22.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_23.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_24.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_25.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_26.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_27.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_28.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_29.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_3.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_30.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_31.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_32.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_33.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_34.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_35.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_36.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_37.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_38.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_39.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_4.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_40.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_41.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_5.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_6.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_7.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_8.png -------------------------------------------------------------------------------- /app/src/main/assets/splash/img_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/assets/splash/img_9.png -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/base/repository/ApiRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.base.repository 2 | 3 | import com.wjx.android.wanandroidmvvm.network.ApiService 4 | import com.wjx.android.wanandroidmvvm.network.RetrofitFactory 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @date: 2020/02/25 11 | * Time: 20:40 12 | */ 13 | abstract class ApiRepository : BaseRepository() { 14 | protected val apiService: ApiService by lazy { 15 | RetrofitFactory.instance.create(ApiService::class.java) 16 | } 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/base/repository/BaseRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.base.repository 2 | 3 | import io.reactivex.disposables.CompositeDisposable 4 | import io.reactivex.disposables.Disposable 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 仓库对数据订阅事件进行管理 9 | * @author: Wangjianxian 10 | * @date: 2020/02/22 11 | * Time: 14:40 12 | */ 13 | open class BaseRepository { 14 | private val mCompositeDisposable by lazy { CompositeDisposable() } 15 | 16 | fun addSubscribe(disposable: Disposable) = mCompositeDisposable.add(disposable) 17 | 18 | fun unSubscribe() = mCompositeDisposable.dispose() 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/base/view/BaseApplication.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.base.view 2 | 3 | import android.app.Application 4 | import androidx.appcompat.app.AppCompatDelegate 5 | import com.kingja.loadsir.core.LoadSir 6 | import com.wjx.android.wanandroidmvvm.common.callback.EmptyCallBack 7 | import com.wjx.android.wanandroidmvvm.common.callback.ErrorCallBack 8 | import com.wjx.android.wanandroidmvvm.common.callback.LoadingCallBack 9 | import com.wjx.android.wanandroidmvvm.common.utils.Constant 10 | import com.wjx.android.wanandroidmvvm.common.utils.SPreference 11 | 12 | /** 13 | * Created with Android Studio. 14 | * Description: 15 | * @author: Wangjianxian 16 | * @date: 2020/02/22 17 | * Time: 14:27 18 | */ 19 | open class BaseApplication : Application() { 20 | companion object { 21 | lateinit var instance : BaseApplication 22 | } 23 | override fun onCreate() { 24 | super.onCreate() 25 | instance = this 26 | SPreference.setContext(applicationContext) 27 | initMode() 28 | LoadSir.beginBuilder() 29 | .addCallback(ErrorCallBack()) 30 | .addCallback(LoadingCallBack()) 31 | .addCallback(EmptyCallBack()) 32 | .commit() 33 | } 34 | 35 | private fun initMode() { 36 | var isNightMode: Boolean by SPreference(Constant.NIGHT_MODE, false) 37 | AppCompatDelegate.setDefaultNightMode(if (isNightMode) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO) 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/base/viewmodel/BaseViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.base.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.wjx.android.wanandroidmvvm.base.repository.BaseRepository 6 | import com.wjx.android.wanandroidmvvm.common.state.State 7 | import com.wjx.android.wanandroidmvvm.common.utils.CommonUtil 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 使用AndroidViewModel可以直接访问application 12 | * @author: Wangjianxian 13 | * @date: 2020/02/22 14 | * Time: 15:26 15 | */ 16 | 17 | open class BaseViewModel : ViewModel() { 18 | val loadState by lazy { 19 | MutableLiveData() 20 | } 21 | 22 | /** 23 | * 通过反射注入mRepository 24 | */ 25 | val mRepository : T by lazy { 26 | // 获取对应Repository 实例 (有参构造函数) 27 | (CommonUtil.getClass(this)) 28 | // 获取构造函数的构造器,传入参数class 29 | .getDeclaredConstructor(MutableLiveData::class.java) 30 | // 传入加载状态 31 | .newInstance(loadState) 32 | } 33 | 34 | override fun onCleared() { 35 | super.onCleared() 36 | mRepository.unSubscribe() 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/callback/EmptyCallBack.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.callback 2 | 3 | import com.kingja.loadsir.callback.Callback 4 | import com.wjx.android.wanandroidmvvm.R 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @date: 2020/02/25 11 | * Time: 19:26 12 | */ 13 | 14 | class EmptyCallBack : Callback() { 15 | override fun onCreateView(): Int = R.layout.layout_empty 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/callback/ErrorCallBack.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.callback 2 | 3 | import com.kingja.loadsir.callback.Callback 4 | import com.wjx.android.wanandroidmvvm.R 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: 王拣贤 10 | * @date: 2020/02/22 11 | * Time: 14:29 12 | */ 13 | class ErrorCallBack : Callback() { 14 | override fun onCreateView(): Int = R.layout.layout_error 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/callback/LoadingCallBack.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.callback 2 | 3 | import com.kingja.loadsir.callback.Callback 4 | import com.wjx.android.wanandroidmvvm.R 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: 王拣贤 10 | * @date: 2020/02/22 11 | * Time: 14:37 12 | */ 13 | class LoadingCallBack : Callback() { 14 | override fun onCreateView(): Int = R.layout.layout_loading 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/permission/PermissionResult.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.permission 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 密封类实现枚举类型 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/4/27 18:54 8 | */ 9 | sealed class PermissionResult { 10 | object Grant : PermissionResult() 11 | class Deny(val permissions: Array) : PermissionResult() 12 | class Rationale(val permissions: Array) : PermissionResult() 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/permission/Permissions.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.permission 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import androidx.fragment.app.Fragment 5 | import androidx.fragment.app.FragmentManager 6 | import androidx.lifecycle.MutableLiveData 7 | 8 | /** 9 | * Created with Android Studio. 10 | * Description: 11 | * @author: Wangjianxian 12 | * @CreateDate: 2020/4/27 19:04 13 | */ 14 | class Permissions { 15 | 16 | @Volatile 17 | private var permissionFragment: PermissionFragment? = null 18 | 19 | private fun getInstance(fragmentManager: FragmentManager) = 20 | permissionFragment ?: synchronized(this) { 21 | permissionFragment 22 | ?: if (fragmentManager.findFragmentByTag(TAG) == null) PermissionFragment().run { 23 | fragmentManager.beginTransaction().add(this, TAG).commitNow() 24 | this 25 | } else fragmentManager.findFragmentByTag(TAG) as PermissionFragment 26 | } 27 | 28 | companion object { 29 | const val TAG = "permissions" 30 | } 31 | 32 | constructor(activity: AppCompatActivity) { 33 | permissionFragment = getInstance(activity.supportFragmentManager) 34 | } 35 | 36 | constructor(fragment: Fragment) { 37 | permissionFragment = getInstance(fragment.childFragmentManager) 38 | } 39 | 40 | fun request(vararg permissions: String): MutableLiveData { 41 | return this.requestArray(permissions) 42 | } 43 | 44 | fun requestArray(permissions: Array): MutableLiveData { 45 | permissionFragment!!.requestPermissions(permissions) 46 | return permissionFragment!!.liveData 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/LoginState.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state 2 | 3 | import android.content.Context 4 | import com.wjx.android.wanandroidmvvm.common.state.callback.CollectListener 5 | import com.wjx.android.wanandroidmvvm.common.utils.Constant 6 | import com.wjx.android.wanandroidmvvm.common.utils.startActivity 7 | import com.wjx.android.wanandroidmvvm.module.collect.view.CollectArticleListActivity 8 | import com.wjx.android.wanandroidmvvm.module.meshare.view.MeShareActivity 9 | import com.wjx.android.wanandroidmvvm.module.rank.view.RankActivity 10 | import com.wjx.android.wanandroidmvvm.module.square.view.ShareArticleActivity 11 | import com.wjx.android.wanandroidmvvm.module.todo.view.EditTodoActivity 12 | import com.wjx.android.wanandroidmvvm.module.todo.view.TodoActivity 13 | 14 | /** 15 | * Created with Android Studio. 16 | * Description: 17 | * @author: Wangjianxian 18 | * @date: 2020/03/01 19 | * Time: 19:32 20 | */ 21 | class LoginState : UserState { 22 | 23 | override fun collect(context: Context, position: Int, listener: CollectListener) { 24 | listener.collect(position) 25 | } 26 | 27 | override fun login(context: Context) {} 28 | 29 | override fun startRankActivity(context: Context) { 30 | startActivity(context) 31 | } 32 | 33 | override fun startCollectActivity(context: Context) { 34 | startActivity(context) 35 | } 36 | 37 | override fun startShareActivity(context: Context) { 38 | startActivity(context) 39 | } 40 | 41 | override fun startAddShareActivity(context: Context) { 42 | startActivity(context) 43 | } 44 | 45 | override fun startTodoActivity(context: Context) { 46 | startActivity(context) 47 | } 48 | 49 | override fun startEditTodoActivity(context: Context) { 50 | startActivity(context) { 51 | putExtra(Constant.KEY_TODO_HANDLE_TYPE, Constant.ADD_TODO) 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/LogoutState.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state 2 | 3 | import android.content.Context 4 | import com.wjx.android.wanandroidmvvm.R 5 | import com.wjx.android.wanandroidmvvm.common.state.callback.CollectListener 6 | import com.wjx.android.wanandroidmvvm.common.utils.startActivity 7 | import com.wjx.android.wanandroidmvvm.module.account.view.LoginActivity 8 | import org.jetbrains.anko.toast 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/03/01 15 | * Time: 19:39 16 | */ 17 | class LogoutState :UserState { 18 | override fun collect(context: Context, position: Int, listener: CollectListener) { 19 | startLoginActivity(context) 20 | } 21 | 22 | override fun login(context: Context) { 23 | startLoginActivity(context) 24 | } 25 | 26 | override fun startRankActivity(context: Context) { 27 | startLoginActivity(context) 28 | } 29 | 30 | override fun startCollectActivity(context: Context) { 31 | startLoginActivity(context) 32 | } 33 | 34 | override fun startShareActivity(context: Context) { 35 | startLoginActivity(context) 36 | } 37 | 38 | override fun startAddShareActivity(context: Context) { 39 | startLoginActivity(context) 40 | } 41 | 42 | override fun startTodoActivity(context: Context) { 43 | startLoginActivity(context) 44 | } 45 | 46 | private fun startLoginActivity(context: Context) { 47 | context?.let { 48 | it.toast(it.getString(R.string.please_login)) 49 | startActivity(it) 50 | } 51 | } 52 | 53 | override fun startEditTodoActivity(context: Context) { 54 | startLoginActivity(context) 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/State.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state 2 | 3 | import androidx.annotation.StringRes 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 状态类 8 | * @author: Wangjianxian 9 | * @date: 2020/02/22 10 | * Time: 15:28 11 | */ 12 | data class State(var code : StateType, var message : String = "", @StringRes var tip : Int = 0) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/StateType.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state 2 | 3 | /** 4 | * 应用状态 5 | */ 6 | enum class StateType { 7 | SUCCESS, 8 | ERROR, 9 | EMPTY, 10 | NETWORK_ERROR, 11 | LOADING, 12 | TIP, 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/UserState.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state 2 | 3 | import android.content.Context 4 | import com.wjx.android.wanandroidmvvm.common.state.callback.CollectListener 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @date: 2020/03/01 11 | * Time: 19:31 12 | */ 13 | interface UserState { 14 | fun collect(context: Context, position: Int, listener: CollectListener) 15 | 16 | fun login(context: Context) 17 | 18 | fun startRankActivity(context: Context) 19 | 20 | fun startTodoActivity(context: Context) 21 | 22 | fun startCollectActivity(context: Context) 23 | 24 | fun startShareActivity(context: Context) 25 | 26 | fun startAddShareActivity(context: Context) 27 | 28 | fun startEditTodoActivity(context: Context) 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/callback/CollectListener.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state.callback 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/25 8 | * Time: 21:01 9 | */ 10 | interface CollectListener { 11 | fun collect(position : Int) 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/callback/LoginSuccessListener.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state.callback 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/25 8 | * Time: 21:01 9 | */ 10 | interface LoginSuccessListener { 11 | fun loginSuccess(userName : String, userId : String, collectArticleIds : List?) 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/state/callback/LoginSuccessState.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.state.callback 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/26 8 | * Time: 10:33 9 | */ 10 | 11 | object LoginSuccessState { 12 | var listeners = ArrayList() 13 | 14 | fun addListener(listener : LoginSuccessListener) { 15 | listeners.add(listener) 16 | } 17 | 18 | fun removeListener(listener: LoginSuccessListener) { 19 | listeners.remove(listener) 20 | } 21 | 22 | fun notifyLoginState(name : String, userId : String, collectIds : List?) { 23 | for (listener in listeners) { 24 | listener.loginSuccess(name, userId, collectIds) 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/AppManager.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.app.Activity 4 | import android.app.ActivityManager 5 | import android.content.Context 6 | import java.util.* 7 | import kotlin.system.exitProcess 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: Activity管理类 12 | * @author: Wangjianxian 13 | * @date: 2020/02/25 14 | * Time: 19:05 15 | */ 16 | 17 | class AppManager { 18 | private val activityStack : Stack = Stack() 19 | 20 | companion object { 21 | val instance by lazy { 22 | AppManager() 23 | } 24 | } 25 | 26 | fun addActivity(activity: Activity) { 27 | activityStack.add(activity) 28 | } 29 | 30 | fun removeActivity(activity: Activity) { 31 | activityStack.remove(activity) 32 | } 33 | 34 | private fun finishAllActivity() { 35 | for(activity in activityStack) { 36 | activity.finish() 37 | } 38 | activityStack.clear() 39 | } 40 | 41 | fun exitApp(context: Context) { 42 | finishAllActivity() 43 | val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager 44 | activityManager.killBackgroundProcesses(context.packageName) 45 | exitProcess(0) 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/ChangeThemeEvent.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import org.greenrobot.eventbus.EventBus 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/03/27 10 | * Time: 18:46 11 | */ 12 | class ChangeThemeEvent { 13 | fun post() { 14 | EventBus.getDefault().post(this) 15 | } 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/CommonUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.app.Service 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.os.Vibrator 7 | import com.wjx.android.wanandroidmvvm.module.activity.ArticleDetailActivity 8 | import java.lang.reflect.ParameterizedType 9 | 10 | 11 | object CommonUtil { 12 | fun getClass(t: Any): Class { 13 | // 通过反射 获取父类泛型 (T) 对应 Class类 14 | return (t.javaClass.genericSuperclass as ParameterizedType) 15 | .actualTypeArguments[0] 16 | as Class 17 | } 18 | 19 | fun startWebView( 20 | context: Context, 21 | url: String, 22 | title: String 23 | ) { 24 | startActivity(context) { 25 | putExtra("url", url) 26 | putExtra("title", title) 27 | addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 28 | } 29 | } 30 | 31 | /** 32 | * 设置震动 33 | * 34 | * @param context 35 | * @param milliseconds 36 | */ 37 | fun Vibrate(context: Context, milliseconds: Long) { 38 | val vibrator = 39 | context.getSystemService(Service.VIBRATOR_SERVICE) as Vibrator 40 | vibrator.vibrate(milliseconds) 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/Constant.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/24 8 | * Time: 17:36 9 | */ 10 | object Constant { 11 | const val BASE_URL = "https://www.wanandroid.com" 12 | 13 | const val USERNAME_KEY = "username" 14 | const val USERID_KEY = "userid" 15 | const val LOGIN_KEY = "login" 16 | 17 | const val SAVE_USER_LOGIN_KEY = "user/login" 18 | const val SAVE_USER_REGISTER_KEY = "user/register" 19 | const val SET_COOKIE_KEY = "set-cookie" 20 | const val COOKIE_NAME = "Cookie" 21 | 22 | const val NIGHT_MODE = "night_mode" 23 | 24 | const val HOME = 0 25 | const val SYSTEM = 1 26 | const val WECHAT = 2 27 | const val NAVIGATION = 3 28 | const val PROJECT = 4 29 | 30 | const val SUCCESS = 0 31 | const val NOT_LOGIN = -1001 32 | 33 | const val ADD_TODO = 1.toString() + "" 34 | 35 | const val EDIT_TODO = 2.toString() + "" 36 | 37 | const val TODO_WORK = 1 38 | 39 | const val TODO_STUDY = 2 40 | 41 | const val KEY_TODO_TITLE = "todo_title" 42 | 43 | const val KEY_TODO_CONTENT = "todo_content" 44 | 45 | const val KEY_TODO_DATE = "todo_date" 46 | 47 | 48 | const val KEY_TODO_PRIORITY = "todo_priority" 49 | 50 | const val KEY_TODO_ID = "todo_id" 51 | 52 | const val KEY_TODO_TYPE = "todo_type" 53 | 54 | const val KEY_TODO_HANDLE_TYPE = "todo_handle" 55 | 56 | // 二维码扫描 57 | const val REQUEST_CODE_SCAN = 1 58 | 59 | const val CODED_CONTENT = "codedContent" 60 | 61 | const val INTENT_ZXING_CONFIG = "zxingConfig" 62 | 63 | // 应用更新 64 | const val UPDATEAPK = "update_apk" 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/DateUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.annotation.SuppressLint 4 | import java.text.ParseException 5 | import java.text.SimpleDateFormat 6 | import java.util.* 7 | import kotlin.jvm.internal.Intrinsics 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @CreateDate: 2020/4/5 20:24 14 | */ 15 | object DateUtil { 16 | /** 17 | * 获取当前时刻 18 | * 19 | * @return 20 | */ 21 | fun getNowTime(): Date? { 22 | return formatDate("yyyy-MM-dd", Date(Date().time)) 23 | } 24 | 25 | /** 26 | * 日期格式化 27 | * 28 | * @param formatStyle 29 | * @param date 30 | * @return 31 | */ 32 | fun formatDate(formatStyle: String, date: Date?): Date? { 33 | Intrinsics.checkParameterIsNotNull(formatStyle, "formatStyle") 34 | return if (date != null) { 35 | val sdf = SimpleDateFormat(formatStyle) 36 | val formatDate = sdf.format(date) 37 | try { 38 | val var10000 = sdf.parse(formatDate) 39 | Intrinsics.checkExpressionValueIsNotNull(var10000, "sdf.parse(formatDate)") 40 | var10000 41 | } catch (var6: ParseException) { 42 | var6.printStackTrace() 43 | Date() 44 | } 45 | } else { 46 | Date() 47 | } 48 | } 49 | 50 | /** 51 | * 日期格式化 52 | * 53 | * @param formatStyle 54 | * @param date 55 | * @return 56 | */ 57 | @SuppressLint("SimpleDateFormat") 58 | fun formatDate(date: Long): String { 59 | val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") 60 | return sdf.format(Date(date)) 61 | 62 | } 63 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/DisplayUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.animation.ValueAnimator 4 | import android.content.Context 5 | import android.view.animation.DecelerateInterpolator 6 | import android.widget.TextView 7 | 8 | /** 9 | * Created with Android Studio. 10 | * Description: 11 | * @author: Wangjianxian 12 | * @CreateDate: 2020/4/5 20:26 13 | */ 14 | object DisplayUtil{ 15 | /** 16 | * dp与px转换 17 | * 18 | * @param context 19 | * @param dp 20 | * @return 21 | */ 22 | fun dp2Px(context: Context, dp: Int): Int { 23 | val density: Float 24 | density = context.resources.displayMetrics.density 25 | return Math.round(dp.toFloat() * density) 26 | } 27 | 28 | fun startIntegralTextAnim(textView : TextView, value: Int, textType : String) { 29 | val animator = ValueAnimator.ofInt(0, value) 30 | //播放时长 31 | animator.duration = 1500 32 | animator.interpolator = DecelerateInterpolator() 33 | animator.addUpdateListener { animation -> 34 | //获取改变后的值 35 | val currentValue = animation.animatedValue as Int 36 | textView.text = "$textType $currentValue" 37 | } 38 | animator.start() 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/GlideImageLoader.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.content.Context 4 | import android.widget.ImageView 5 | import com.bumptech.glide.Glide 6 | import com.youth.banner.loader.ImageLoader 7 | 8 | /** 9 | * Created with Android Studio. 10 | * Description: 11 | * @author: Wangjianxian 12 | * @date: 2020/02/26 13 | * Time: 11:12 14 | */ 15 | class GlideImageLoader :ImageLoader() { 16 | override fun displayImage(context: Context, path: Any?, imageView: ImageView) { 17 | Glide.with(context).load(path).into(imageView) 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/KeyBoardUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.view.inputmethod.InputMethodManager 6 | 7 | /** 8 | * Created with Android Studio. 9 | * Description: 10 | * @author: Wangjianxian 11 | * @CreateDate: 2020/4/5 20:08 12 | */ 13 | object KeyBoardUtil { 14 | // 关闭软键盘 15 | fun Activity.hideKeyboard() { 16 | // 当前焦点的 View 17 | val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 18 | imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0) 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/Reified.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @CreateDate: 2020/5/1 16:34 11 | */ 12 | 13 | inline fun startActivity(context: Context) { 14 | val intent = Intent(context, T::class.java) 15 | context.startActivity(intent) 16 | } 17 | 18 | inline fun startActivity(context: Context, block: Intent.() -> Unit) { 19 | val intent = Intent(context, T::class.java) 20 | intent.block() 21 | context.startActivity(intent) 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/common/utils/SpeedLayoutManager.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.common.utils 2 | 3 | import android.content.Context 4 | import android.util.DisplayMetrics 5 | import androidx.recyclerview.widget.LinearLayoutManager 6 | import androidx.recyclerview.widget.LinearSmoothScroller 7 | import androidx.recyclerview.widget.RecyclerView 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @date: 2020/02/25 14 | * Time: 22:05 15 | */ 16 | class SpeedLayoutManager(val context: Context?, val speed: Float = 25f) : LinearLayoutManager(context) { 17 | 18 | override fun smoothScrollToPosition(recyclerView: RecyclerView?, state: RecyclerView.State?, position: Int) { 19 | val smoothScroller = object : LinearSmoothScroller(context) { 20 | override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float { 21 | // 返回:滑过1px时经历的时间(ms)。 22 | return speed / (displayMetrics?.densityDpi ?: 1) 23 | } 24 | } 25 | 26 | // 设置要 移动的位置 27 | smoothScroller.targetPosition = position 28 | // 开始移动 29 | startSmoothScroll(smoothScroller) 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/custom/graylayout/GrayFrameLayout.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.custom.graylayout 2 | 3 | import android.content.Context 4 | import android.graphics.Canvas 5 | import android.graphics.ColorMatrix 6 | import android.graphics.ColorMatrixColorFilter 7 | import android.graphics.Paint 8 | import android.util.AttributeSet 9 | import android.widget.FrameLayout 10 | 11 | 12 | /** 13 | * Created with Android Studio. 14 | * Description: 15 | * @author: Wangjianxian 16 | * @CreateDate: 2020/4/5 14:01 17 | */ 18 | class GrayFrameLayout(context: Context, attrs: AttributeSet) : 19 | FrameLayout(context, attrs) { 20 | private val mPaint: Paint = Paint() 21 | override fun dispatchDraw(canvas: Canvas) { 22 | canvas.saveLayer(null, mPaint, Canvas.ALL_SAVE_FLAG) 23 | super.dispatchDraw(canvas) 24 | canvas.restore() 25 | } 26 | 27 | override fun draw(canvas: Canvas) { 28 | canvas.saveLayer(null, mPaint, Canvas.ALL_SAVE_FLAG) 29 | super.draw(canvas) 30 | canvas.restore() 31 | } 32 | 33 | init { 34 | val cm = ColorMatrix() 35 | cm.setSaturation(0f) 36 | mPaint.setColorFilter(ColorMatrixColorFilter(cm)) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/custom/interpolator/CustomScaleInterpolator.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.custom.interpolator 2 | 3 | import android.view.animation.Interpolator 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/02/27 10 | * Time: 20:16 11 | */ 12 | 13 | class CustomScaleInterpolator(elasticFactor: Float) : 14 | Interpolator { 15 | 16 | private val elasticFactor: Float 17 | 18 | override fun getInterpolation(input: Float): Float { 19 | return (Math.pow( 20 | 2.0, 21 | -10 * input.toDouble() 22 | ) * Math.sin((input - elasticFactor / 4) * (2 * Math.PI) / elasticFactor) + 1).toFloat() 23 | } 24 | 25 | init { 26 | this.elasticFactor = elasticFactor 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/custom/loadingview/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.custom.loadingview 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/3/31 13:03 8 | */ 9 | enum class Shapes { 10 | Circle, Square, Triangle; 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/account/model/LoginResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.account.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/03/01 8 | * Time: 19:54 9 | */ 10 | data class LoginResponse( 11 | var icon : String, 12 | var type : String, 13 | var id : Int, 14 | var collectIds : List, 15 | var username : String 16 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/account/model/RegisterResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.account.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/03/01 8 | * Time: 19:57 9 | */ 10 | data class RegisterResponse( 11 | var username : String, 12 | var id : Int, 13 | var icon : String, 14 | var type : Int, 15 | var collectIds : List 16 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/collect/model/CollectResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.collect.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/03/03 10 | * Time: 14:41 11 | */ 12 | data class CollectResponse( 13 | var curPage : Int, 14 | var datas : List
, 15 | var total : Int 16 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/collect/viewmodel/CollectViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.collect.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 5 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 6 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 7 | import com.wjx.android.wanandroidmvvm.module.collect.model.CollectResponse 8 | import com.wjx.android.wanandroidmvvm.module.collect.repository.CollectRepository 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/03/03 15 | * Time: 14:48 16 | */ 17 | class CollectViewModel : 18 | ArticleViewModel() { 19 | val mCollectArticleData: MutableLiveData> = MutableLiveData() 20 | val mAddCollectData: MutableLiveData> = MutableLiveData() 21 | val mUnCollectData: MutableLiveData> = MutableLiveData() 22 | 23 | fun loadCollectArticle(pageNum: Int) { 24 | mRepository.loadCollectArticle(pageNum, mCollectArticleData) 25 | } 26 | 27 | fun addCollectArticle(title: String, author: String, link: String) { 28 | mRepository.addCollectArticle(title, author, link, mAddCollectData) 29 | } 30 | 31 | fun unCollect(id: Int, originId: Int) { 32 | mRepository.unCollect(id, originId, mUnCollectData) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/common/model/Article.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.common.model 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @date: 2020/02/25 11 | * Time: 21:10 12 | */ 13 | @Entity 14 | data class Article( 15 | @PrimaryKey(autoGenerate = true) 16 | var primaryKeyId: Int = 0, 17 | var id: Int = 0, 18 | var author: String = "", 19 | var shareUser: String = "", 20 | var chapterName: String? = "", 21 | var desc: String = "", 22 | var link: String = "", 23 | var originId: Int = 0, 24 | var title: String = "", 25 | var collect: Boolean = false, 26 | var superChapterName: String? = "", 27 | var niceDate: String = "", 28 | var fresh: Boolean = false, 29 | var top: Boolean = false, 30 | var envelopePic: String = "" 31 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/common/viewmodel/ArticleViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.common.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.viewModelScope 5 | import com.wjx.android.wanandroidmvvm.module.common.repository.ArticleRepository 6 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 7 | import com.wjx.android.wanandroidmvvm.base.viewmodel.BaseViewModel 8 | import com.wjx.android.wanandroidmvvm.network.initiateRequest 9 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.withContext 13 | 14 | /** 15 | * Created with Android Studio. 16 | * Description: 17 | * @author: Wangjianxian 18 | * @date: 2020/02/25 19 | * Time: 20:39 20 | */ 21 | 22 | abstract class ArticleViewModel : 23 | BaseViewModel() { 24 | // RxJava2 25 | // var mCollectData: MutableLiveData> = MutableLiveData() 26 | 27 | 28 | // fun collect(id: Int) { 29 | // mRepository.collect(id, mCollectData) 30 | // } 31 | 32 | // fun unCollect(id: Int) { 33 | // mRepository.unCollect(id, mCollectData) 34 | // } 35 | 36 | // 使用协程 + Retrofit2.6以上版本 37 | var mCollectData: MutableLiveData = MutableLiveData() 38 | 39 | fun collectCo(id: Int) { 40 | initiateRequest({ mCollectData.value = mRepository.collectCo(id) }, loadState) 41 | } 42 | 43 | fun unCollectCo(id: Int) { 44 | initiateRequest({ mCollectData.value = mRepository.unCollectCo(id) }, loadState) 45 | } 46 | 47 | fun addFootPrint(article: Article) { 48 | viewModelScope.launch { 49 | withContext(Dispatchers.IO) { 50 | mRepository.insertFootPrint(article) 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/footprint/model/dao/FootPrintDao.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.footprint.model.dao 2 | 3 | import androidx.room.* 4 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @CreateDate: 2020/5/9 15:36 11 | */ 12 | @Dao 13 | interface FootPrintDao { 14 | @Transaction 15 | @Insert(entity = Article::class) 16 | suspend fun insertFootPrint(article: Article): Long 17 | 18 | @Transaction 19 | @Query("SELECT * FROM article") 20 | suspend fun queryAllFootPrint(): List
21 | 22 | @Transaction 23 | @Query("SELECT * FROM article WHERE id = (:id)") 24 | suspend fun queryArticleById(id: Int): Article? 25 | 26 | @Transaction 27 | @Delete(entity = Article::class) 28 | suspend fun deleteArticle(article: Article) : Int 29 | 30 | @Transaction 31 | @Query("DELETE FROM article") 32 | suspend fun deleteAll() 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/footprint/model/database/FootPrintDataBase.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.footprint.model.database 2 | 3 | import android.content.Context 4 | import androidx.room.Database 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 8 | import com.wjx.android.wanandroidmvvm.module.footprint.model.dao.FootPrintDao 9 | 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: WangjianxianA 15 | * @CreateDate: 2020/5/9 15:22 16 | */ 17 | @Database(entities = [Article::class], version = 1, exportSchema = false) 18 | abstract class FootPrintDataBase : RoomDatabase() { 19 | abstract fun footPrintDao(): FootPrintDao 20 | 21 | companion object { 22 | private var INSTANCE: FootPrintDataBase? = null 23 | fun getInstance(context: Context): FootPrintDataBase? { 24 | if (INSTANCE == null) { 25 | synchronized(FootPrintDataBase::class.java) { 26 | if (INSTANCE == null) { 27 | INSTANCE = Room.databaseBuilder( 28 | context, 29 | FootPrintDataBase::class.java, 30 | "database_wanandroid" 31 | ).build() 32 | } 33 | } 34 | } 35 | return INSTANCE 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/footprint/repository/FootPrintRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.footprint.repository 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.common.state.State 5 | import com.wjx.android.wanandroidmvvm.common.utils.RoomHelper 6 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 7 | import com.wjx.android.wanandroidmvvm.module.common.repository.ArticleRepository 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @CreateDate: 2020/5/9 17:05 14 | */ 15 | class FootPrintRepository(loadState: MutableLiveData) : ArticleRepository(loadState) { 16 | suspend fun loadFootPrint() = RoomHelper.queryAllFootPrint(loadState) 17 | suspend fun deleteFootPrint(article: Article) = RoomHelper.deleteFootPrint(article) 18 | suspend fun deleteAll() = RoomHelper.deleteAll() 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/home/model/BannerResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.home.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/26 8 | * Time: 10:55 9 | */ 10 | data class BannerResponse (var id : Int, 11 | var desc : String, 12 | var imagePath : String, 13 | var title : String, 14 | var url : String) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/home/model/HomeArticleResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.home.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/02/26 10 | * Time: 10:58 11 | */ 12 | data class HomeArticleResponse(var curPage: Int, 13 | var datas: List
, 14 | var offset: Int, 15 | var over: Boolean, 16 | var pageCount: Int, 17 | var size: Int, 18 | var total: Int) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/meshare/model/MeShareArticleResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.meshare.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/03/26 10 | * Time: 16:58 11 | */ 12 | data class MeShareArticleResponse( 13 | var curPage :Int, 14 | var datas : List
15 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/meshare/model/MeShareResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.meshare.model 2 | 3 | 4 | /** 5 | * Created with Android Studio. 6 | * Description: 7 | * @author: Wangjianxian 8 | * @date: 2020/03/26 9 | * Time: 16:56 10 | */ 11 | data class MeShareResponse(var shareArticles : T) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/meshare/repository/MeShareRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.meshare.repository 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.repository.ArticleRepository 5 | import com.wjx.android.wanandroidmvvm.base.observer.BaseObserver 6 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 7 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 8 | import com.wjx.android.wanandroidmvvm.common.state.State 9 | import com.wjx.android.wanandroidmvvm.module.meshare.model.MeShareArticleResponse 10 | import com.wjx.android.wanandroidmvvm.module.meshare.model.MeShareResponse 11 | import io.reactivex.android.schedulers.AndroidSchedulers 12 | import io.reactivex.schedulers.Schedulers 13 | 14 | /** 15 | * Created with Android Studio. 16 | * Description: 17 | * @author: Wangjianxian 18 | * @date: 2020/03/26 19 | * Time: 17:34 20 | */ 21 | class MeShareRepository(loadState: MutableLiveData) : ArticleRepository(loadState) { 22 | fun loadShareArticle(pageNum : Int, liveData : MutableLiveData>>) { 23 | apiService.loadMeShareArticle(pageNum) 24 | .subscribeOn(Schedulers.io()) 25 | .observeOn(AndroidSchedulers.mainThread()) 26 | .subscribe( 27 | BaseObserver( 28 | liveData, 29 | loadState, 30 | this 31 | ) 32 | ) 33 | } 34 | 35 | fun deleteShareArticle(id: Int, liveData : MutableLiveData>) { 36 | apiService.deleteShareArticle(id) 37 | .subscribeOn(Schedulers.io()) 38 | .observeOn(AndroidSchedulers.mainThread()) 39 | .subscribe( 40 | BaseObserver( 41 | liveData, 42 | loadState, 43 | this 44 | ) 45 | ) 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/meshare/viewmodel/MeShareViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.meshare.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 5 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 6 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 7 | import com.wjx.android.wanandroidmvvm.module.meshare.model.MeShareArticleResponse 8 | import com.wjx.android.wanandroidmvvm.module.meshare.model.MeShareResponse 9 | import com.wjx.android.wanandroidmvvm.module.meshare.repository.MeShareRepository 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @date: 2020/03/26 16 | * Time: 17:36 17 | */ 18 | class MeShareViewModel : ArticleViewModel() { 19 | var mMeShareData: MutableLiveData>> = 20 | MutableLiveData() 21 | var mDeleteMeShareData: MutableLiveData> = MutableLiveData() 22 | 23 | fun loadMeShareArticle(pageNum: Int) { 24 | mRepository.loadShareArticle(pageNum, mMeShareData) 25 | } 26 | 27 | fun deleteMeShareArticle(id: Int) { 28 | mRepository.deleteShareArticle(id, mDeleteMeShareData) 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/navigation/adapter/NavigationTabAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.navigation.adapter 2 | 3 | import android.animation.AnimatorSet 4 | import android.animation.ObjectAnimator 5 | import com.chad.library.adapter.base.BaseQuickAdapter 6 | import com.chad.library.adapter.base.BaseViewHolder 7 | import com.wjx.android.wanandroidmvvm.custom.interpolator.CustomScaleInterpolator 8 | import com.wjx.android.wanandroidmvvm.R 9 | import com.wjx.android.wanandroidmvvm.common.utils.ColorUtil 10 | import kotlinx.android.synthetic.main.navigation_item.view.* 11 | 12 | /** 13 | * Created with Android Studio. 14 | * Description: 15 | * @author: Wangjianxian 16 | * @date: 2020/02/29 17 | * Time: 20:12 18 | */ 19 | class NavigationTabAdapter (layoutId : Int, listData : MutableList?) 20 | : BaseQuickAdapter(layoutId, listData) { 21 | 22 | var selectedPosition : Int = -1 23 | 24 | override fun convert(viewHolder: BaseViewHolder?, item: String?) { 25 | viewHolder?.let { 26 | with(it) { 27 | addOnClickListener(R.id.circle_imageView) 28 | setText(R.id.nav_tab_name, item) 29 | itemView.circle_imageView.setCircleName(item.toString()) 30 | itemView.circle_imageView.setmBackgroundColor(ColorUtil.getColor(mContext)) 31 | if (adapterPosition == selectedPosition) { 32 | val animatorX = 33 | ObjectAnimator.ofFloat(viewHolder.itemView.circle_imageView, "scaleX", 1.0f, 1.2f, 1.0f) 34 | val animatorY = 35 | ObjectAnimator.ofFloat(viewHolder.itemView.circle_imageView, "scaleY", 1.0f, 1.2f, 1.0f) 36 | val set = AnimatorSet() 37 | set.duration = 1000 38 | set.interpolator = CustomScaleInterpolator(0.4f) 39 | set.playTogether(animatorX, animatorY) 40 | set.start() 41 | } 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/navigation/model/NavigationLabelResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.navigation.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/29 8 | * Time: 20:05 9 | */ 10 | data class NavigationLabelResponse( 11 | val link : String, 12 | val title : String 13 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/navigation/model/NavigationTabNameResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.navigation.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/29 8 | * Time: 20:04 9 | */ 10 | data class NavigationTabNameResponse( 11 | var articles : List, 12 | var name : String 13 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/navigation/repository/NavigationRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.navigation.repository 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.repository.ArticleRepository 5 | import com.wjx.android.wanandroidmvvm.base.observer.BaseObserver 6 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 7 | import com.wjx.android.wanandroidmvvm.common.state.State 8 | import com.wjx.android.wanandroidmvvm.network.dataConvert 9 | import com.wjx.android.wanandroidmvvm.module.navigation.model.NavigationTabNameResponse 10 | import io.reactivex.android.schedulers.AndroidSchedulers 11 | import io.reactivex.schedulers.Schedulers 12 | 13 | /** 14 | * Created with Android Studio. 15 | * Description: 16 | * @author: Wangjianxian 17 | * @date: 2020/02/29 18 | * Time: 19:59 19 | */ 20 | class NavigationRepository(loadState: MutableLiveData) : ArticleRepository(loadState) { 21 | fun loadNavigationTab(liveData: MutableLiveData>>) { 22 | apiService.loadNavigationTab() 23 | .subscribeOn(Schedulers.io()) 24 | .observeOn(AndroidSchedulers.mainThread()) 25 | .subscribe( 26 | BaseObserver( 27 | liveData, 28 | loadState, 29 | this 30 | ) 31 | ) 32 | } 33 | 34 | suspend fun loadNavigationTab(): List { 35 | return apiService.loadNavigationTabCo().dataConvert(loadState) 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/navigation/viewmodel/NavigationViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.navigation.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.base.viewmodel.BaseViewModel 5 | import com.wjx.android.wanandroidmvvm.network.initiateRequest 6 | import com.wjx.android.wanandroidmvvm.module.navigation.model.NavigationTabNameResponse 7 | import com.wjx.android.wanandroidmvvm.module.navigation.repository.NavigationRepository 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @date: 2020/02/29 14 | * Time: 20:10 15 | */ 16 | class NavigationViewModel : 17 | BaseViewModel() { 18 | // val mNavigationTabData : MutableLiveData>> = MutableLiveData() 19 | // 20 | // fun loadNavigationTab() { 21 | // mRepository.loadNavigationTab(mNavigationTabData) 22 | // } 23 | 24 | val mNavigationTabData: MutableLiveData> = MutableLiveData() 25 | 26 | fun loadNavigationTab() { 27 | initiateRequest({mNavigationTabData.value = mRepository.loadNavigationTab()},loadState) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/project/adapter/ProjectTabAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.project.adapter 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.fragment.app.FragmentStatePagerAdapter 6 | 7 | /** 8 | * Created with Android Studio. 9 | * Description: 10 | * @author: Wangjianxian 11 | * @date: 2020/02/28 12 | * Time: 16:45 13 | */ 14 | class ProjectTabAdapter( 15 | fragmentManager: FragmentManager, 16 | val tabs: List, 17 | val fragments: List 18 | ) : FragmentStatePagerAdapter(fragmentManager) { 19 | override fun getItem(position: Int): Fragment = fragments[position] 20 | 21 | override fun getCount(): Int = tabs.size 22 | 23 | override fun getPageTitle(position: Int): CharSequence? = tabs[position] 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/project/model/Project.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.project.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/28 8 | * Time: 15:16 9 | */ 10 | data class Project( 11 | var author : String, 12 | var chapterName : String, 13 | var desc : String, 14 | var envelopePic : String, 15 | var link :String, 16 | var niceDate : String, 17 | var superChapterName : String, 18 | var title : String 19 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/project/model/ProjectResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.project.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/02/28 10 | * Time: 15:19 11 | */ 12 | data class ProjectResponse( 13 | var datas : List
, 14 | var curPage : Int, 15 | var size : Int, 16 | var total : Int, 17 | var pageCount : Int 18 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/project/model/ProjectTabResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.project.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/28 8 | * Time: 15:20 9 | */ 10 | data class ProjectTabResponse( 11 | var name : String, 12 | var id : Int 13 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/project/viewmodel/ProjectViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.project.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.network.initiateRequest 5 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 6 | import com.wjx.android.wanandroidmvvm.module.project.model.ProjectResponse 7 | import com.wjx.android.wanandroidmvvm.module.project.model.ProjectTabResponse 8 | import com.wjx.android.wanandroidmvvm.module.project.repository.ProjectRespository 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/02/28 15 | * Time: 15:48 16 | */ 17 | class ProjectViewModel : 18 | ArticleViewModel() { 19 | // val mProjectTabData : MutableLiveData>> = MutableLiveData() 20 | // val mProjectArticleData : MutableLiveData> = MutableLiveData() 21 | // 22 | // fun loadProjectTab() { 23 | // mRepository.loadProjectTab(mProjectTabData) 24 | // } 25 | // 26 | // fun loadProjectArticle(pageNum : Int, cid : Int) { 27 | // mRepository.loadProjectArticle(pageNum, cid, mProjectArticleData) 28 | // } 29 | 30 | val mProjectTabData: MutableLiveData> = MutableLiveData() 31 | val mProjectArticleData: MutableLiveData = MutableLiveData() 32 | 33 | fun loadProjectTab() { 34 | initiateRequest({ mProjectTabData.value = mRepository.loadProjectTabCo() }, loadState) 35 | } 36 | 37 | fun loadProjectArticle(pageNum: Int, cid: Int) { 38 | initiateRequest({ 39 | mProjectArticleData.value = mRepository.loadProjectArticleCo(pageNum, cid) 40 | }, loadState) 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/question/model/QuestionResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.question.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/03/26 10 | * Time: 15:39 11 | */ 12 | data class QuestionResponse( 13 | var curPage : Int, 14 | var datas : List
15 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/question/questionrepository/QuestionRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.question.questionrepository 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.repository.ArticleRepository 5 | import com.wjx.android.wanandroidmvvm.base.observer.BaseObserver 6 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 7 | import com.wjx.android.wanandroidmvvm.common.state.State 8 | import com.wjx.android.wanandroidmvvm.module.question.model.QuestionResponse 9 | import io.reactivex.android.schedulers.AndroidSchedulers 10 | import io.reactivex.schedulers.Schedulers 11 | 12 | /** 13 | * Created with Android Studio. 14 | * Description: 15 | * @author: Wangjianxian 16 | * @date: 2020/03/26 17 | * Time: 15:42 18 | */ 19 | class QuestionRepository(loadState: MutableLiveData) : ArticleRepository(loadState) { 20 | fun loadQuestionList(pageNum : Int, liveData : MutableLiveData>) { 21 | apiService.loadQuestionList(pageNum) 22 | .subscribeOn(Schedulers.io()) 23 | .observeOn(AndroidSchedulers.mainThread()) 24 | .subscribe( 25 | BaseObserver( 26 | liveData, 27 | loadState, 28 | this 29 | ) 30 | ) 31 | } 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/question/viewModel/QuestionViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.question.viewModel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 5 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 6 | import com.wjx.android.wanandroidmvvm.module.question.questionrepository.QuestionRepository 7 | import com.wjx.android.wanandroidmvvm.module.question.model.QuestionResponse 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @date: 2020/03/26 14 | * Time: 15:41 15 | */ 16 | 17 | class QuestionViewModel : 18 | ArticleViewModel() { 19 | var mQuestionData: MutableLiveData> = MutableLiveData() 20 | 21 | fun loadQuestionList(pageNum: Int) { 22 | mRepository.loadQuestionList(pageNum, mQuestionData) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/adapter/IntegralHistoryAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.adapter 2 | 3 | import com.chad.library.adapter.base.BaseQuickAdapter 4 | import com.chad.library.adapter.base.BaseViewHolder 5 | import com.wjx.android.wanandroidmvvm.R 6 | import com.wjx.android.wanandroidmvvm.common.utils.ColorUtil 7 | import com.wjx.android.wanandroidmvvm.common.utils.DateUtil 8 | import com.wjx.android.wanandroidmvvm.module.rank.model.IntegralHistoryResponse 9 | import kotlinx.android.synthetic.main.integral_history_item.view.* 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @CreateDate: 2020/3/29 19:45 16 | */ 17 | class IntegralHistoryAdapter(layoutId: Int, listData: MutableList?) : 18 | BaseQuickAdapter(layoutId, listData) { 19 | override fun convert(viewHolder: BaseViewHolder, item: IntegralHistoryResponse?) { 20 | viewHolder?.let { holder -> 21 | holder.itemView.integral_material_card.rippleColor = ColorUtil.getOneColorStateList(mContext) 22 | holder.itemView.integral_material_card.strokeColor = ColorUtil.getColor(mContext) 23 | val descStr = if (item!!.desc.contains("积分")) item.desc.subSequence( 24 | item.desc.indexOf("积分"), 25 | item.desc.length 26 | ) else "" 27 | holder.setText(R.id.item_integralhistory_title, item.reason +"" + descStr) 28 | holder.setText(R.id.item_integralhistory_date, DateUtil.formatDate(item.date)) 29 | holder.setText(R.id.item_integralhistory_count, "+(" + item.coinCount+ ")") 30 | holder.setTextColor(R.id.item_integralhistory_count, ColorUtil.getColor(mContext)) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/adapter/RankAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.adapter 2 | 3 | import android.os.Build 4 | import com.chad.library.adapter.base.BaseQuickAdapter 5 | import com.chad.library.adapter.base.BaseViewHolder 6 | import com.wjx.android.wanandroidmvvm.R 7 | import com.wjx.android.wanandroidmvvm.common.utils.ColorUtil 8 | import com.wjx.android.wanandroidmvvm.module.rank.model.IntegralResponse 9 | import kotlinx.android.synthetic.main.rank_item.view.* 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @CreateDate: 2020/3/29 18:30 16 | */ 17 | 18 | class RankAdapter(layoutId: Int, listData: MutableList?) : 19 | BaseQuickAdapter(layoutId, listData) { 20 | override fun convert(viewHolder: BaseViewHolder, integralResponse: IntegralResponse?) { 21 | viewHolder?.let { 22 | holder -> 23 | holder.itemView.rank_material_card.rippleColor = ColorUtil.getOneColorStateList(mContext) 24 | holder.itemView.rank_material_card.strokeColor = ColorUtil.getColor(mContext) 25 | integralResponse?.let { 26 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 27 | holder.setText(R.id.integral_level, "等级:" + integralResponse.level) 28 | .setText(R.id.integral_name, "用户:" + integralResponse.username) 29 | .setText(R.id.integral_count, "积分:" + integralResponse.coinCount) 30 | } 31 | } 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/model/IntegralHistoryListResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/3/29 19:34 8 | */ 9 | data class IntegralHistoryListResponse( 10 | var curPage : Int, 11 | var datas : List 12 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/model/IntegralHistoryResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/3/29 19:35 8 | */ 9 | data class IntegralHistoryResponse( 10 | var coinCount : Int, 11 | var date : Long, 12 | var desc : String, 13 | var reason: String 14 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/model/IntegralResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/3/29 18:04 8 | */ 9 | data class IntegralResponse( 10 | var coinCount: Int, 11 | var level: Int, 12 | var rank: Int, 13 | var username: String 14 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/model/RankResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/3/29 18:01 8 | */ 9 | data class RankResponse( 10 | var curPage: Int, 11 | var datas: List 12 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/rank/viewmodel/RankViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.rank.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.base.viewmodel.BaseViewModel 5 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 6 | import com.wjx.android.wanandroidmvvm.module.rank.model.IntegralHistoryListResponse 7 | import com.wjx.android.wanandroidmvvm.module.rank.model.IntegralResponse 8 | import com.wjx.android.wanandroidmvvm.module.rank.model.RankResponse 9 | import com.wjx.android.wanandroidmvvm.module.rank.repository.RankRepository 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @CreateDate: 2020/3/29 18:13 16 | */ 17 | class RankViewModel : BaseViewModel() { 18 | val mRankListData: MutableLiveData> = MutableLiveData() 19 | val mMeRankInfo: MutableLiveData> = MutableLiveData() 20 | val mIntegralHistoryListData: MutableLiveData> = 21 | MutableLiveData() 22 | 23 | fun loadRankList(pageNum: Int) { 24 | mRepository.loadRankList(pageNum, mRankListData) 25 | } 26 | 27 | fun loadMeRankInfo() { 28 | mRepository.loadMeRankInfo(mMeRankInfo) 29 | } 30 | 31 | fun loadIntegralHistoryList(pageNum: Int) { 32 | mRepository.loadIntegralHistoryList(pageNum, mIntegralHistoryListData) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/search/adapter/SearchHistoryAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.search.adapter 2 | 3 | import com.chad.library.adapter.base.BaseQuickAdapter 4 | import com.chad.library.adapter.base.BaseViewHolder 5 | import com.wjx.android.wanandroidmvvm.R 6 | 7 | /** 8 | * Created with Android Studio. 9 | * Description: 10 | * @author: Wangjianxian 11 | * @date: 2020/03/05 12 | * Time: 18:24 13 | */ 14 | class SearchHistoryAdapter : BaseQuickAdapter(R.layout.search_history_item, null) { 15 | override fun convert(helper: BaseViewHolder?, item: String?) { 16 | helper?.run { 17 | setText(R.id.history_name, item ?: "") 18 | addOnClickListener(R.id.history_delete) 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/search/model/HotKeyResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.search.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/03/05 8 | * Time: 17:24 9 | */ 10 | data class HotKeyResponse( 11 | var name: String 12 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/search/model/SearchResultResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.search.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/03/05 10 | * Time: 17:26 11 | */ 12 | data class SearchResultResponse( 13 | var curPage: Int, 14 | var datas: List
, 15 | var offset: Int, 16 | var over: Boolean, 17 | var pageCount: Int, 18 | var size: Int, 19 | var total: Int 20 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/search/model/bean/SearchHistory.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.search.model.bean 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @CreateDate: 2020/5/17 13:02 11 | */ 12 | @Entity 13 | data class SearchHistory( 14 | var name : String = "" 15 | ) { 16 | @PrimaryKey(autoGenerate = true) 17 | var primaryKeyId: Int = 0 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/search/model/dao/SearchHistoryDao.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.search.model.dao 2 | 3 | import androidx.room.* 4 | import com.wjx.android.wanandroidmvvm.module.search.model.bean.SearchHistory 5 | 6 | 7 | /** 8 | * Created with Android Studio. 9 | * Description: 10 | * @author: Wangjianxian 11 | * @date: 2020/03/05 12 | * Time: 17:36 13 | */ 14 | @Dao 15 | interface SearchHistoryDao { 16 | @Transaction 17 | @Query("SELECT * FROM searchhistory") 18 | suspend fun queryAllSearchHistory(): List 19 | 20 | @Transaction 21 | @Insert(entity = SearchHistory::class) 22 | suspend fun insertSearchHistory(searchHistory: SearchHistory): Long 23 | 24 | @Transaction 25 | @Query("SELECT * FROM searchhistory WHERE name = (:name)") 26 | suspend fun querySearchHistoryByName(name: String): SearchHistory? 27 | 28 | @Transaction 29 | @Delete(entity = SearchHistory::class) 30 | suspend fun deleteSearchHistory(searchHistory: SearchHistory) : Int 31 | 32 | @Transaction 33 | @Query("DELETE FROM searchhistory") 34 | suspend fun deleteAllSearchHistory() : Int 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/search/model/db/SearchHistoryDataBase.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.search.model.db 2 | 3 | import android.content.Context 4 | import androidx.room.Database 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.wjx.android.wanandroidmvvm.module.search.model.bean.SearchHistory 8 | import com.wjx.android.wanandroidmvvm.module.search.model.dao.SearchHistoryDao 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @CreateDate: 2020/5/17 12:57 15 | */ 16 | @Database(entities = [SearchHistory::class], version = 1, exportSchema = false) 17 | abstract class SearchHistoryDataBase : RoomDatabase() { 18 | abstract fun searchHistoryDao(): SearchHistoryDao 19 | 20 | companion object { 21 | private var INSTANCE: SearchHistoryDataBase? = null 22 | fun getInstance(context: Context): SearchHistoryDataBase? { 23 | if (INSTANCE == null) { 24 | synchronized(SearchHistoryDataBase::class.java) { 25 | if (INSTANCE == null) { 26 | INSTANCE = Room.databaseBuilder( 27 | context, 28 | SearchHistoryDataBase::class.java, 29 | "database_search_history" 30 | ).build() 31 | } 32 | } 33 | } 34 | return INSTANCE 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/square/model/SquareResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.square.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/03/26 10 | * Time: 17:01 11 | */ 12 | data class SquareResponse( 13 | var curPage : Int, 14 | var datas : List
15 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/square/repository/SquareRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.square.repository 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.repository.ArticleRepository 5 | import com.wjx.android.wanandroidmvvm.base.observer.BaseObserver 6 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 7 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 8 | import com.wjx.android.wanandroidmvvm.common.state.State 9 | import com.wjx.android.wanandroidmvvm.module.square.model.SquareResponse 10 | import io.reactivex.android.schedulers.AndroidSchedulers 11 | import io.reactivex.schedulers.Schedulers 12 | 13 | /** 14 | * Created with Android Studio. 15 | * Description: 16 | * @author: Wangjianxian 17 | * @date: 2020/03/26 18 | * Time: 17:05 19 | */ 20 | class SquareRepository(loadState: MutableLiveData) : ArticleRepository(loadState) { 21 | fun loadSquareArticle(pageNum : Int, liveData : MutableLiveData>) { 22 | apiService.loadSquareArticle(pageNum) 23 | .subscribeOn(Schedulers.io()) 24 | .observeOn(AndroidSchedulers.mainThread()) 25 | .subscribe( 26 | BaseObserver( 27 | liveData, 28 | loadState, 29 | this 30 | ) 31 | ) 32 | } 33 | 34 | fun addShareArticle(title : String, link : String, liveData: MutableLiveData>) { 35 | apiService.addShareArticle(title, link) 36 | .subscribeOn(Schedulers.io()) 37 | .observeOn(AndroidSchedulers.mainThread()) 38 | .subscribe( 39 | BaseObserver( 40 | liveData, 41 | loadState, 42 | this 43 | ) 44 | ) 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/square/viewmodel/SquareViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.square.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 5 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 6 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 7 | import com.wjx.android.wanandroidmvvm.module.square.model.SquareResponse 8 | import com.wjx.android.wanandroidmvvm.module.square.repository.SquareRepository 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/03/26 15 | * Time: 17:07 16 | */ 17 | class SquareViewModel : 18 | ArticleViewModel() { 19 | var mSquareData: MutableLiveData> = MutableLiveData() 20 | var mAddShareData: MutableLiveData> = MutableLiveData() 21 | 22 | fun loadSquareArticle(pageNum: Int) { 23 | mRepository.loadSquareArticle(pageNum, mSquareData) 24 | } 25 | 26 | fun addShareData(title: String, link: String) { 27 | mRepository.addShareArticle(title, link, mAddShareData) 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/system/model/SystemArticleResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.system.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/02/27 10 | * Time: 17:06 11 | */ 12 | data class SystemArticleResponse( 13 | var curPage: Int, 14 | var datas: List
, 15 | var pageCount: Int, 16 | var total: Int 17 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/system/model/SystemLabelResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.system.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/27 8 | * Time: 17:07 9 | */ 10 | data class SystemLabelResponse( 11 | var name: String, 12 | var id: Int 13 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/system/model/SystemTabNameResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.system.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/27 8 | * Time: 17:06 9 | */ 10 | data class SystemTabNameResponse( 11 | var children : List, 12 | var name : String 13 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/system/viewmodel/SystemViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.system.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.network.initiateRequest 5 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 6 | import com.wjx.android.wanandroidmvvm.module.system.model.SystemArticleResponse 7 | import com.wjx.android.wanandroidmvvm.module.system.model.SystemTabNameResponse 8 | import com.wjx.android.wanandroidmvvm.module.system.repository.SystemRepository 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/02/27 15 | * Time: 17:09 16 | */ 17 | class SystemViewModel : ArticleViewModel() { 18 | // val mSystemTabNameData : MutableLiveData>> = MutableLiveData() 19 | // val mSystemArticleData : MutableLiveData> = MutableLiveData() 20 | // 21 | // fun loadSystemTab() { 22 | // mRepository.loadSystemTab(mSystemTabNameData) 23 | // } 24 | // 25 | // fun loadSystemArticle(pageNum : Int, cid : Int?) { 26 | // mRepository.loadSystemArticle(pageNum, cid, mSystemArticleData) 27 | // } 28 | 29 | val mSystemTabNameData: MutableLiveData> = MutableLiveData() 30 | val mSystemArticleData: MutableLiveData = MutableLiveData() 31 | 32 | fun loadSystemTab() { 33 | initiateRequest({ mSystemTabNameData.value = mRepository.loadSystemTabCo() }, loadState) 34 | } 35 | 36 | fun loadSystemArticle(pageNum: Int, cid: Int?) { 37 | initiateRequest({ 38 | mSystemArticleData.value = mRepository.loadsystemArticleCo(pageNum, cid) 39 | }, loadState) 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/todo/model/TodoPageResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.todo.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/03/04 8 | * Time: 11:53 9 | */ 10 | data class TodoPageResponse( 11 | var curPage: Int, 12 | var datas: List, 13 | var offset: Int, 14 | var over: Boolean, 15 | var pageCount: Int, 16 | var size: Int, 17 | var total: Int 18 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/todo/model/TodoResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.todo.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/03/04 8 | * Time: 11:22 9 | */ 10 | data class TodoResponse( 11 | var completeDate: String, 12 | var content: String, 13 | var date : Long, 14 | var dateStr: String, 15 | var id: Int, 16 | var priority: Int, 17 | var status: Int, 18 | var type: Int, 19 | var title: String 20 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/todo/viewmodel/TodoViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.todo.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.base.viewmodel.BaseViewModel 5 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 6 | import com.wjx.android.wanandroidmvvm.network.response.EmptyResponse 7 | import com.wjx.android.wanandroidmvvm.module.todo.model.TodoPageResponse 8 | import com.wjx.android.wanandroidmvvm.module.todo.repository.TodoRepository 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/03/04 15 | * Time: 15:39 16 | */ 17 | class TodoViewModel : BaseViewModel() { 18 | val mTodoListData: MutableLiveData> = MutableLiveData() 19 | val mTodoAddData: MutableLiveData> = MutableLiveData() 20 | val mTodoUpdateData: MutableLiveData> = MutableLiveData() 21 | val mTodoFinishData: MutableLiveData> = MutableLiveData() 22 | val mTodoDeleteData: MutableLiveData> = MutableLiveData() 23 | 24 | fun loadTodoList(pageNum: Int = 1) { 25 | mRepository.loadTodoList(pageNum, mTodoListData) 26 | } 27 | 28 | fun addTodo(title: String, content: String, date: String, type: Int, priority: Int) { 29 | mRepository.addTodo(title, content, date, type, priority, mTodoAddData) 30 | } 31 | 32 | fun finishTodo(id: Int, status: Int) { 33 | mRepository.finishTodo(id, status, mTodoFinishData) 34 | } 35 | 36 | fun updateTodo( 37 | id: Int?, 38 | title: String, 39 | content: String, 40 | date: String, 41 | type: Int, 42 | priority: Int 43 | ) { 44 | mRepository.updateTodo(id, title, content, date, type, priority, mTodoUpdateData) 45 | } 46 | 47 | fun deleteTodo(id: Int) { 48 | mRepository.deleteTodo(id, mTodoDeleteData) 49 | } 50 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/wechat/adapter/WeChatTabAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.wechat.adapter 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.fragment.app.FragmentStatePagerAdapter 6 | 7 | /** 8 | * Created with Android Studio. 9 | * Description: 10 | * @author: Wangjianxian 11 | * @date: 2020/02/27 12 | * Time: 15:35 13 | */ 14 | 15 | class WeChatTabAdapter( 16 | fragmentManager: FragmentManager, 17 | val tabs: List, 18 | val fragments: List 19 | ) : FragmentStatePagerAdapter(fragmentManager) { 20 | override fun getItem(position: Int): Fragment = fragments[position] 21 | 22 | override fun getCount(): Int = tabs.size 23 | 24 | override fun getPageTitle(position: Int): CharSequence? = tabs[position] 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/wechat/model/WeChatArticleResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.wechat.model 2 | 3 | import com.wjx.android.wanandroidmvvm.module.common.model.Article 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 8 | * @author: Wangjianxian 9 | * @date: 2020/02/27 10 | * Time: 14:44 11 | */ 12 | data class WeChatArticleResponse( 13 | var curPage: Int, 14 | var datas: List
, 15 | var offset: Int, 16 | var over: Boolean, 17 | var pageCount: Int, 18 | var size: Int, 19 | var total: Int 20 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/wechat/model/WeChatTabNameResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.wechat.model 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/27 8 | * Time: 14:46 9 | */ 10 | data class WeChatTabNameResponse( 11 | var courseId : Int, 12 | var name : String, 13 | var id : Int, 14 | var order : Int, 15 | var parentChapterId : Int, 16 | var userControlSetTop : Boolean 17 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/wechat/view/WeChatArticleFragment.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.wechat.view 2 | 3 | import android.os.Bundle 4 | import androidx.fragment.app.Fragment 5 | import androidx.lifecycle.Observer 6 | import com.wjx.android.wanandroidmvvm.module.common.view.ArticleListFragment 7 | import com.wjx.android.wanandroidmvvm.module.wechat.viewmodel.WeChatViewModel 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @date: 2020/02/27 14 | * Time: 15:33 15 | */ 16 | class WeChatArticleFragment : ArticleListFragment() { 17 | private var mCurrentPage = 1 18 | private val mCid: Int by lazy { arguments?.getInt("id") ?: -1 } 19 | 20 | companion object { 21 | fun newInstance(id : Int) : Fragment { 22 | val bundle = Bundle() 23 | bundle.putInt("id", id) 24 | val fragment = WeChatArticleFragment() 25 | fragment.arguments = bundle 26 | return fragment 27 | } 28 | } 29 | 30 | override fun initData() { 31 | super.initData() 32 | mViewModel.loadWeChatArticle(mCid, mCurrentPage) 33 | } 34 | 35 | override fun onRefreshData() { 36 | mCurrentPage = 0 37 | mViewModel.loadWeChatArticle(mCid, mCurrentPage) 38 | } 39 | 40 | override fun onLoadMoreData() { 41 | mViewModel.loadWeChatArticle(mCid, ++mCurrentPage) 42 | } 43 | 44 | override fun initDataObserver() { 45 | super.initDataObserver() 46 | mViewModel.mWeChatArticleData.observe(this, Observer { response -> 47 | response?.let { 48 | addData(it.datas) 49 | } 50 | }) 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/module/wechat/viewmodel/WeChatViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.module.wechat.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.wjx.android.wanandroidmvvm.network.initiateRequest 5 | import com.wjx.android.wanandroidmvvm.module.common.viewmodel.ArticleViewModel 6 | import com.wjx.android.wanandroidmvvm.module.wechat.model.WeChatArticleResponse 7 | import com.wjx.android.wanandroidmvvm.module.wechat.model.WeChatTabNameResponse 8 | import com.wjx.android.wanandroidmvvm.module.wechat.repository.WeChatRepository 9 | 10 | /** 11 | * Created with Android Studio. 12 | * Description: 13 | * @author: Wangjianxian 14 | * @date: 2020/02/27 15 | * Time: 14:39 16 | */ 17 | class WeChatViewModel : 18 | ArticleViewModel() { 19 | // RxJava2 20 | // val mWChatTabData: MutableLiveData>> = 21 | // MutableLiveData() 22 | // var mWeChatArticleData: MutableLiveData> = MutableLiveData() 23 | // 24 | // fun loadWeChatTabName() { 25 | // mRepository.loadWeChatTabName(mWChatTabData) 26 | // } 27 | // 28 | // fun loadWeChatArticle(cid: Int, pageNum: Int) { 29 | // mRepository.loadWeChatArticle(cid, pageNum, mWeChatArticleData) 30 | // } 31 | val mWChatTabData: MutableLiveData> = 32 | MutableLiveData() 33 | var mWeChatArticleData: MutableLiveData = MutableLiveData() 34 | fun loadWeChatTabName() { 35 | initiateRequest({ mWChatTabData.value = mRepository.loadWeChatTabNameCo() }, loadState) 36 | } 37 | 38 | fun loadWeChatArticle(cid: Int, pageNum: Int) { 39 | initiateRequest({ 40 | mWeChatArticleData.value = mRepository.loadWeChatArticleCo(cid, pageNum) 41 | }, loadState) 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/network/Ext.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.network 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.viewModelScope 5 | import com.wjx.android.wanandroidmvvm.base.repository.BaseRepository 6 | import com.wjx.android.wanandroidmvvm.base.viewmodel.BaseViewModel 7 | import com.wjx.android.wanandroidmvvm.common.state.State 8 | import com.wjx.android.wanandroidmvvm.common.state.StateType 9 | import com.wjx.android.wanandroidmvvm.common.state.UserInfo 10 | import com.wjx.android.wanandroidmvvm.common.utils.Constant 11 | import com.wjx.android.wanandroidmvvm.network.response.BaseResponse 12 | import kotlinx.coroutines.launch 13 | 14 | /** 15 | * Created with Android Studio. 16 | * Description:数据解析扩展函数 17 | * @author: Wangjianxian 18 | * @CreateDate: 2020/4/19 17:35 19 | */ 20 | 21 | fun BaseResponse.dataConvert( 22 | loadState: MutableLiveData 23 | ): T { 24 | when (errorCode) { 25 | Constant.SUCCESS -> { 26 | if (data is List<*>) { 27 | if ((data as List<*>).isEmpty()) { 28 | loadState.postValue(State(StateType.EMPTY)) 29 | } 30 | } 31 | loadState.postValue(State(StateType.SUCCESS)) 32 | return data 33 | } 34 | Constant.NOT_LOGIN -> { 35 | UserInfo.instance.logoutSuccess() 36 | loadState.postValue(State(StateType.ERROR, message = "请重新登录")) 37 | return data 38 | } 39 | else -> { 40 | loadState.postValue(State(StateType.ERROR, message = errorMsg)) 41 | return data 42 | } 43 | } 44 | } 45 | 46 | 47 | fun BaseViewModel.initiateRequest( 48 | block: suspend () -> Unit, 49 | loadState: MutableLiveData 50 | ) { 51 | viewModelScope.launch { 52 | runCatching { 53 | block() 54 | }.onSuccess { 55 | }.onFailure { 56 | NetExceptionHandle.handleException(it, loadState) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/network/NetExceptionHandle.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.network 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.google.gson.JsonParseException 5 | import com.wjx.android.wanandroidmvvm.common.state.State 6 | import com.wjx.android.wanandroidmvvm.common.state.StateType 7 | import org.apache.http.conn.ConnectTimeoutException 8 | import retrofit2.HttpException 9 | import java.net.ConnectException 10 | import java.net.UnknownHostException 11 | import kotlin.Exception 12 | 13 | /** 14 | * Created with Android Studio. 15 | * Description: 16 | * @author: Wangjianxian 17 | * @CreateDate: 2020/5/5 11:32 18 | */ 19 | object NetExceptionHandle { 20 | fun handleException(e: Throwable?, loadState: MutableLiveData){ 21 | val ex = Exception() 22 | e?.let { 23 | when (it) { 24 | is HttpException -> { 25 | loadState.postValue(State(StateType.NETWORK_ERROR)) 26 | } 27 | is ConnectException -> { 28 | loadState.postValue(State(StateType.NETWORK_ERROR)) 29 | } 30 | is ConnectTimeoutException -> { 31 | loadState.postValue(State(StateType.NETWORK_ERROR)) 32 | } 33 | is UnknownHostException -> { 34 | loadState.postValue(State(StateType.NETWORK_ERROR)) 35 | } 36 | is JsonParseException -> { 37 | loadState.postValue(State(StateType.NETWORK_ERROR)) 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/network/response/BaseResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.network.response 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 返回数据基类 6 | * @author: Wangjianxian 7 | * @date: 2020/02/24 8 | * Time: 16:04 9 | */ 10 | 11 | open class BaseResponse(var data: T, var errorCode: Int = -1, var errorMsg: String = "") -------------------------------------------------------------------------------- /app/src/main/java/com/wjx/android/wanandroidmvvm/network/response/EmptyResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm.network.response 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/25 8 | * Time: 20:42 9 | */ 10 | class EmptyResponse -------------------------------------------------------------------------------- /app/src/main/res/anim/alpha_in.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/alpha_out.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_left_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/anim/anim_right_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/anim/animo_alph_close.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/animo_alph_open.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/item_animation_fall_down.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 10 | 15 | 16 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/anim/layout_animator_fall_down.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/push_bottom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/anim/translate_dialog_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/translate_dialog_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-night-xxxhdpi/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-night-xxxhdpi/empty.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-night-xxxhdpi/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-night-xxxhdpi/error.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/ic_article_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-night/ic_article_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/ic_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-night/ic_browser.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-night/ic_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-night/ic_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-night/ic_qrcode.png -------------------------------------------------------------------------------- /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/drawable-xxxhdpi/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/empty.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/error.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_article_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_article_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_browser.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_clear_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_clear_all.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_close.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_delete_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_delete_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_fab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_fab.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_footprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_footprint.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_help.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_history.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_integral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_integral.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_logo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_logout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_logout.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_qrcode.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_question.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_rank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_rank.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_record.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_scan.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_setting.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_share_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_share_square.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_square.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_theme.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_todo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_todo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/ic_up.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/navigation_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/navigation_home.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/navigation_navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/navigation_navigation.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/navigation_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/navigation_project.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/navigation_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/navigation_system.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/navigation_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/navigation_wechat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/shortcut_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/shortcut_search.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/shortcut_wenda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/shortcut_wenda.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/todo_done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/todo_done.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/todo_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/todo_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/todo_not_done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/todo_not_done.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/todo_tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/drawable-xxxhdpi/todo_tag.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/collect_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/collect_selector_icon.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/color_cursor.xml: -------------------------------------------------------------------------------- 1 | 2 |   4 | 5 |   6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/edit_shap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/flow_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_collect.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_highlight_blue_open_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_highlight_white_close_24dp.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/loading_shadow.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/search_edit_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/shape_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/text_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/title_lable_green.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/title_lable_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/todo_foreground.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/uncollect_selector_icon.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_article_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_edit_todo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_handle_todo.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 31 | 32 | 44 | -------------------------------------------------------------------------------- /app/src/main/res/layout/flow_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_article_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 15 | 16 | 21 | 22 | 27 | 28 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_project.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 25 | 26 | 31 | 32 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_wechat.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 25 | 26 | 31 | 32 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/history_foot.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_empty.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_home_headview.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/loading_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/navigation_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 22 | 23 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/navigation_label_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | 18 | 21 | 22 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/search_history_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 24 | 25 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/layout/system_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | 20 | 21 | 33 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/menu/drawer_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 15 | 19 | 23 | 24 | 28 | 29 | 33 | 34 | 35 | 36 | 40 | 41 | 45 | 49 | 50 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/menu/navigation_bottom_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 17 | 21 | 22 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/menu/search_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/navigation/nav_graph.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #999999 4 | #999999 5 | #FFFFFF 6 | #999999 7 | #FFFFFF 8 | #999999 9 | #333 10 | #d8d8d8 11 | #FFFFFF 12 | #2196F3 13 | #1976D2 14 | #BBDEFB 15 | #212121 16 | #FFFFFF 17 | #FFFFFF 18 | #06B3ED 19 | #06B3ED 20 | #999999 21 | -------------------------------------------------------------------------------- /app/src/main/res/values-sw360dp-v13/values-sw360dp-v13.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | false 4 | 0dp 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #0091EA 4 | #0091EA 5 | #80000000 6 | #333333 7 | #000000 8 | #85ffffff 9 | #00000000 10 | 11 | #FFFFFF 12 | #FFFFFF 13 | #000000 14 | #333 15 | #666 16 | #333 17 | #80FFFFFF 18 | #d8d8d8 19 | #a0a0a0 20 | #2196F3 21 | #1976D2 22 | #BBDEFB 23 | #212121 24 | #FFFFFF 25 | #F44336 26 | #707070 27 | #06B3ED 28 | #06B3ED 29 | #ff669900 30 | #ffff4444 31 | #333 32 | #FFFFFF 33 | #cb99c5 34 | #70616161 35 | #FFFFFF 36 | #000000 37 | #80FFFFFF 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8dp 4 | 10dp 5 | 8dp 6 | 4dp 7 | 12dp 8 | 48dp 9 | 10dp 10 | 48dp 11 | 16dp 12 | 16dp 13 | -------------------------------------------------------------------------------- /app/src/main/res/xml/network_security_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/xml/setting_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 13 | 16 | 17 | 18 | 21 | 22 | 26 | 27 | 31 | 32 | 36 | 37 | 41 | 42 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/res/xml/shortcuts.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 10 | 14 | 15 | 16 | 21 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/test/java/com/wjx/android/wanandroidmvvm/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.wanandroidmvvm 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 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | apply from: 'config.gradle' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.3.71' 6 | repositories { 7 | google() 8 | jcenter() 9 | } 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:4.0.0' 12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 13 | classpath 'com.novoda:bintray-release:0.9.2' 14 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' // Add this line 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | google() 23 | jcenter() 24 | maven { url 'https://maven.google.com' } 25 | maven { url "https://jitpack.io" } 26 | maven { url "https://raw.githubusercontent.com/Pgyer/mvn_repo_pgyer/master" } 27 | maven { url 'https://dl.bintray.com/novoda-oss/snapshots/' } 28 | } 29 | } 30 | 31 | task clean(type: Delete) { 32 | delete rootProject.buildDir 33 | } 34 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/gradle.properties -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Jun 08 08:08:19 CST 2020 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.1.1-all.zip 7 | -------------------------------------------------------------------------------- /mvvm/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /mvvm/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'com.github.dcendents.android-maven' 5 | 6 | group='com.github.wangjianxiandev' 7 | 8 | android { 9 | compileSdkVersion 29 10 | buildToolsVersion "29.0.2" 11 | 12 | defaultConfig { 13 | minSdkVersion 26 14 | targetSdkVersion 29 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | dataBinding { 21 | enabled = true 22 | } 23 | 24 | } 25 | 26 | dependencies { 27 | api fileTree(dir: 'libs', include: ['*.jar']) 28 | api "androidx.appcompat:appcompat:1.1.0" 29 | api "com.android.support:design:29.0.0" 30 | //kotlin 31 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 32 | api "androidx.core:core-ktx:1.2.0" 33 | // liveData 34 | api "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0" 35 | // viewModel 36 | api "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0" 37 | api "androidx.lifecycle:lifecycle-extensions:2.2.0" 38 | //glide 39 | api 'com.github.bumptech.glide:glide:4.11.0' 40 | //retrofit 41 | api "com.squareup.retrofit2:retrofit:2.6.2" 42 | api "com.squareup.retrofit2:converter-gson:2.6.2" 43 | api "com.squareup.retrofit2:adapter-rxjava2:2.6.2" 44 | } -------------------------------------------------------------------------------- /mvvm/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjianxiandev/WanAndroidMVVM/4960afbc577d6d8001bf9b0ebad45ac62c77207b/mvvm/consumer-rules.pro -------------------------------------------------------------------------------- /mvvm/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 -------------------------------------------------------------------------------- /mvvm/src/androidTest/java/com/wjx/android/mvvm/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.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.getInstrumentation().targetContext 22 | assertEquals("com.wjx.android.mvvm.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /mvvm/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/BaseApplication.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm 2 | 3 | import android.app.Application 4 | import androidx.appcompat.app.AppCompatDelegate 5 | import com.wjx.android.mvvm.common.utils.Constant 6 | import com.wjx.android.mvvm.common.utils.SPreference 7 | 8 | /** 9 | * Created with Android Studio. 10 | * Description: 11 | * @author: Wangjianxian 12 | * @CreateDate: 2020/6/8 8:28 13 | */ 14 | open class BaseApplication : Application() { 15 | companion object { 16 | lateinit var instance : BaseApplication 17 | } 18 | override fun onCreate() { 19 | super.onCreate() 20 | instance = this 21 | SPreference.setContext(applicationContext) 22 | } 23 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/permission/PermissionResult.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.permission 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 密封类实现枚举类型 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/4/27 18:54 8 | */ 9 | sealed class PermissionResult { 10 | object Grant : PermissionResult() 11 | class Deny(val permissions: Array) : PermissionResult() 12 | class Rationale(val permissions: Array) : PermissionResult() 13 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/permission/Permissions.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.permission 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import androidx.fragment.app.Fragment 5 | import androidx.fragment.app.FragmentManager 6 | import androidx.lifecycle.MutableLiveData 7 | 8 | /** 9 | * Created with Android Studio. 10 | * Description: 11 | * @author: Wangjianxian 12 | * @CreateDate: 2020/4/27 19:04 13 | */ 14 | class Permissions { 15 | 16 | @Volatile 17 | private var permissionFragment: PermissionFragment? = null 18 | 19 | private fun getInstance(fragmentManager: FragmentManager) = 20 | permissionFragment ?: synchronized(this) { 21 | permissionFragment 22 | ?: if (fragmentManager.findFragmentByTag(TAG) == null) PermissionFragment().run { 23 | fragmentManager.beginTransaction().add(this, TAG).commitNow() 24 | this 25 | } else fragmentManager.findFragmentByTag(TAG) as PermissionFragment 26 | } 27 | 28 | companion object { 29 | const val TAG = "permissions" 30 | } 31 | 32 | constructor(activity: AppCompatActivity) { 33 | permissionFragment = getInstance(activity.supportFragmentManager) 34 | } 35 | 36 | constructor(fragment: Fragment) { 37 | permissionFragment = getInstance(fragment.childFragmentManager) 38 | } 39 | 40 | fun request(vararg permissions: String): MutableLiveData { 41 | return this.requestArray(permissions) 42 | } 43 | 44 | fun requestArray(permissions: Array): MutableLiveData { 45 | permissionFragment!!.requestPermissions(permissions) 46 | return permissionFragment!!.liveData 47 | } 48 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/state/State.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.state 2 | 3 | import androidx.annotation.StringRes 4 | 5 | /** 6 | * Created with Android Studio. 7 | * Description: 状态类 8 | * @author: Wangjianxian 9 | * @date: 2020/02/22 10 | * Time: 15:28 11 | */ 12 | data class State(var code : StateType, var message : String = "", @StringRes var tip : Int = 0) -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/state/StateType.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.state 2 | 3 | /** 4 | * 应用状态 5 | */ 6 | enum class StateType { 7 | SUCCESS, 8 | ERROR, 9 | EMPTY, 10 | NETWORK_ERROR, 11 | LOADING, 12 | TIP, 13 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/AppManager.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.app.Activity 4 | import android.app.ActivityManager 5 | import android.content.Context 6 | import java.util.* 7 | import kotlin.system.exitProcess 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: Activity管理类 12 | * @author: Wangjianxian 13 | * @date: 2020/02/25 14 | * Time: 19:05 15 | */ 16 | 17 | class AppManager { 18 | private val activityStack : Stack = Stack() 19 | 20 | companion object { 21 | val instance by lazy { 22 | AppManager() 23 | } 24 | } 25 | 26 | fun addActivity(activity: Activity) { 27 | activityStack.add(activity) 28 | } 29 | 30 | fun removeActivity(activity: Activity) { 31 | activityStack.remove(activity) 32 | } 33 | 34 | private fun finishAllActivity() { 35 | for(activity in activityStack) { 36 | activity.finish() 37 | } 38 | activityStack.clear() 39 | } 40 | 41 | fun exitApp(context: Context) { 42 | finishAllActivity() 43 | val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager 44 | activityManager.killBackgroundProcesses(context.packageName) 45 | exitProcess(0) 46 | } 47 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/CommonUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.content.Context 4 | import android.widget.Toast 5 | import java.lang.reflect.ParameterizedType 6 | 7 | 8 | object CommonUtil { 9 | fun getClass(t: Any): Class { 10 | // 通过反射 获取父类泛型 (T) 对应 Class类 11 | return (t.javaClass.genericSuperclass as ParameterizedType) 12 | .actualTypeArguments[0] 13 | as Class 14 | } 15 | 16 | fun showToast(context: Context, string : String) { 17 | Toast.makeText(context, string , Toast.LENGTH_SHORT).show() 18 | } 19 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/Constant.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @CreateDate: 2020/6/3 22:13 8 | */ 9 | object Constant { 10 | const val BASE_URL = "" 11 | const val SUCCESS = 0 12 | const val NOT_LOGIN = -1001 13 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/DateUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.annotation.SuppressLint 4 | import java.text.ParseException 5 | import java.text.SimpleDateFormat 6 | import java.util.* 7 | import kotlin.jvm.internal.Intrinsics 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @CreateDate: 2020/4/5 20:24 14 | */ 15 | object DateUtil { 16 | /** 17 | * 获取当前时刻 18 | * 19 | * @return 20 | */ 21 | fun getNowTime(): Date? { 22 | return formatDate("yyyy-MM-dd", Date(Date().time)) 23 | } 24 | 25 | /** 26 | * 日期格式化 27 | * 28 | * @param formatStyle 29 | * @param date 30 | * @return 31 | */ 32 | fun formatDate(formatStyle: String, date: Date?): Date? { 33 | Intrinsics.checkParameterIsNotNull(formatStyle, "formatStyle") 34 | return if (date != null) { 35 | val sdf = SimpleDateFormat(formatStyle) 36 | val formatDate = sdf.format(date) 37 | try { 38 | val var10000 = sdf.parse(formatDate) 39 | Intrinsics.checkExpressionValueIsNotNull(var10000, "sdf.parse(formatDate)") 40 | var10000 41 | } catch (var6: ParseException) { 42 | var6.printStackTrace() 43 | Date() 44 | } 45 | } else { 46 | Date() 47 | } 48 | } 49 | 50 | /** 51 | * 日期格式化 52 | * 53 | * @param formatStyle 54 | * @param date 55 | * @return 56 | */ 57 | @SuppressLint("SimpleDateFormat") 58 | fun formatDate(date: Long): String { 59 | val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") 60 | return sdf.format(Date(date)) 61 | 62 | } 63 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/DisplayUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.animation.ValueAnimator 4 | import android.content.Context 5 | import android.view.animation.DecelerateInterpolator 6 | import android.widget.TextView 7 | 8 | /** 9 | * Created with Android Studio. 10 | * Description: 11 | * @author: Wangjianxian 12 | * @CreateDate: 2020/4/5 20:26 13 | */ 14 | object DisplayUtil{ 15 | /** 16 | * dp与px转换 17 | * 18 | * @param context 19 | * @param dp 20 | * @return 21 | */ 22 | fun dp2Px(context: Context, dp: Int): Int { 23 | val density: Float 24 | density = context.resources.displayMetrics.density 25 | return Math.round(dp.toFloat() * density) 26 | } 27 | 28 | fun startIntegralTextAnim(textView : TextView, value: Int, textType : String) { 29 | val animator = ValueAnimator.ofInt(0, value) 30 | //播放时长 31 | animator.duration = 1500 32 | animator.interpolator = DecelerateInterpolator() 33 | animator.addUpdateListener { animation -> 34 | //获取改变后的值 35 | val currentValue = animation.animatedValue as Int 36 | textView.text = "$textType $currentValue" 37 | } 38 | animator.start() 39 | } 40 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/KeyBoardUtil.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.view.inputmethod.InputMethodManager 6 | 7 | /** 8 | * Created with Android Studio. 9 | * Description: 10 | * @author: Wangjianxian 11 | * @CreateDate: 2020/4/5 20:08 12 | */ 13 | object KeyBoardUtil { 14 | // 关闭软键盘 15 | fun Activity.hideKeyboard() { 16 | // 当前焦点的 View 17 | val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 18 | imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0) 19 | } 20 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/Reified.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @CreateDate: 2020/5/1 16:34 11 | */ 12 | 13 | inline fun startActivity(context: Context) { 14 | val intent = Intent(context, T::class.java) 15 | context.startActivity(intent) 16 | } 17 | 18 | inline fun startActivity(context: Context, block: Intent.() -> Unit) { 19 | val intent = Intent(context, T::class.java) 20 | intent.block() 21 | context.startActivity(intent) 22 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/common/utils/SpeedLayoutManager.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.common.utils 2 | 3 | import android.content.Context 4 | import android.util.DisplayMetrics 5 | import androidx.recyclerview.widget.LinearLayoutManager 6 | import androidx.recyclerview.widget.LinearSmoothScroller 7 | import androidx.recyclerview.widget.RecyclerView 8 | 9 | /** 10 | * Created with Android Studio. 11 | * Description: 12 | * @author: Wangjianxian 13 | * @date: 2020/02/25 14 | * Time: 22:05 15 | */ 16 | class SpeedLayoutManager(val context: Context?, val speed: Float = 25f) : LinearLayoutManager(context) { 17 | 18 | override fun smoothScrollToPosition(recyclerView: RecyclerView?, state: RecyclerView.State?, position: Int) { 19 | val smoothScroller = object : LinearSmoothScroller(context) { 20 | override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float { 21 | // 返回:滑过1px时经历的时间(ms)。 22 | return speed / (displayMetrics?.densityDpi ?: 1) 23 | } 24 | } 25 | 26 | // 设置要 移动的位置 27 | smoothScroller.targetPosition = position 28 | // 开始移动 29 | startSmoothScroll(smoothScroller) 30 | } 31 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/network/ApiService.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.network 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/25 8 | * Time: 20:41 9 | */ 10 | 11 | interface ApiService { 12 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/network/Ext.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.network 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.viewModelScope 5 | import com.wjx.android.mvvm.common.state.State 6 | import com.wjx.android.mvvm.common.state.StateType 7 | import com.wjx.android.mvvm.common.utils.Constant 8 | import com.wjx.android.mvvm.network.response.BaseResponse 9 | import com.wjx.android.mvvm.repository.BaseRepository 10 | import com.wjx.android.mvvm.viewmodel.BaseViewModel 11 | import kotlinx.coroutines.launch 12 | 13 | /** 14 | * Created with Android Studio. 15 | * Description:数据解析扩展函数 16 | * @author: Wangjianxian 17 | * @CreateDate: 2020/4/19 17:35 18 | */ 19 | 20 | fun BaseResponse.dataConvert( 21 | loadState: MutableLiveData 22 | ): T { 23 | when (errorCode) { 24 | Constant.SUCCESS -> { 25 | if (data is List<*>) { 26 | if ((data as List<*>).isEmpty()) { 27 | loadState.postValue(State(StateType.EMPTY)) 28 | } 29 | } 30 | loadState.postValue(State(StateType.SUCCESS)) 31 | return data 32 | } 33 | Constant.NOT_LOGIN -> { 34 | 35 | loadState.postValue(State(StateType.ERROR, message = "请重新登录")) 36 | return data 37 | } 38 | else -> { 39 | loadState.postValue(State(StateType.ERROR, message = errorMsg)) 40 | return data 41 | } 42 | } 43 | } 44 | 45 | 46 | fun BaseViewModel.initiateRequest( 47 | block: suspend () -> Unit, 48 | loadState: MutableLiveData 49 | ) { 50 | viewModelScope.launch { 51 | runCatching { 52 | block() 53 | }.onSuccess { 54 | }.onFailure { 55 | NetExceptionHandle.handleException(it, loadState) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/network/NetExceptionHandle.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.network 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.google.gson.JsonParseException 5 | import com.wjx.android.mvvm.common.state.State 6 | import com.wjx.android.mvvm.common.state.StateType 7 | import org.apache.http.conn.ConnectTimeoutException 8 | import retrofit2.HttpException 9 | import java.net.ConnectException 10 | import java.net.UnknownHostException 11 | import kotlin.Exception 12 | 13 | /** 14 | * Created with Android Studio. 15 | * Description: 16 | * @author: Wangjianxian 17 | * @CreateDate: 2020/5/5 11:32 18 | */ 19 | object NetExceptionHandle { 20 | fun handleException(e: Throwable?, loadState: MutableLiveData){ 21 | val ex = Exception() 22 | e?.let { 23 | when (it) { 24 | is HttpException -> { 25 | loadState.postValue(State(StateType.NETWORK_ERROR)) 26 | } 27 | is ConnectException -> { 28 | loadState.postValue(State(StateType.NETWORK_ERROR)) 29 | } 30 | is ConnectTimeoutException -> { 31 | loadState.postValue(State(StateType.NETWORK_ERROR)) 32 | } 33 | is UnknownHostException -> { 34 | loadState.postValue(State(StateType.NETWORK_ERROR)) 35 | } 36 | is JsonParseException -> { 37 | loadState.postValue(State(StateType.NETWORK_ERROR)) 38 | } 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/network/response/BaseResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.network.response 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 返回数据基类 6 | * @author: Wangjianxian 7 | * @date: 2020/02/24 8 | * Time: 16:04 9 | */ 10 | 11 | open class BaseResponse(var data: T, var errorCode: Int = -1, var errorMsg: String = "") -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/network/response/EmptyResponse.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.network.response 2 | 3 | /** 4 | * Created with Android Studio. 5 | * Description: 6 | * @author: Wangjianxian 7 | * @date: 2020/02/25 8 | * Time: 20:42 9 | */ 10 | class EmptyResponse -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/repository/BaseRepository.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.repository 2 | 3 | import io.reactivex.disposables.CompositeDisposable 4 | import io.reactivex.disposables.Disposable 5 | 6 | /** 7 | * Created with Android Studio. 8 | * Description: 9 | * @author: Wangjianxian 10 | * @CreateDate: 2020/6/8 8:16 11 | */ 12 | open class BaseRepository { 13 | private val mCompositeDisposable by lazy { CompositeDisposable() } 14 | 15 | fun addSubscribe(disposable: Disposable) = mCompositeDisposable.add(disposable) 16 | 17 | fun unSubscribe() = mCompositeDisposable.dispose() 18 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/view/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.view 2 | 3 | import android.os.Build 4 | import android.os.Bundle 5 | import android.view.View 6 | import androidx.appcompat.app.AppCompatActivity 7 | import androidx.core.content.ContextCompat 8 | import androidx.core.graphics.ColorUtils 9 | import androidx.databinding.DataBindingUtil 10 | import androidx.databinding.ViewDataBinding 11 | import androidx.lifecycle.ViewModelProvider 12 | import com.wjx.android.mvvm.R 13 | import com.wjx.android.mvvm.common.utils.* 14 | import com.wjx.android.mvvm.viewmodel.BaseViewModel 15 | 16 | /** 17 | * Created with Android Studio. 18 | * Description: 19 | * @author: Wangjianxian 20 | * @CreateDate: 2020/6/8 8:15 21 | */ 22 | abstract class BaseActivity, DB : ViewDataBinding> : AppCompatActivity() { 23 | private var mExitTime: Long = 0 24 | 25 | protected lateinit var mViewModel: VM 26 | protected lateinit var mDataBinding: DB 27 | 28 | open fun initView() {} 29 | 30 | open fun initData() {} 31 | 32 | open fun reLoad() {} 33 | 34 | abstract fun getLayoutId(): Int 35 | 36 | override fun onCreate(savedInstanceState: Bundle?) { 37 | super.onCreate(savedInstanceState) 38 | mDataBinding = DataBindingUtil.setContentView(this, getLayoutId()) 39 | mDataBinding.lifecycleOwner = this 40 | AppManager.instance.addActivity(this) 41 | mViewModel = ViewModelProvider(this).get(CommonUtil.getClass(this)) 42 | initView() 43 | initData() 44 | } 45 | 46 | override fun onBackPressed() { 47 | val time = System.currentTimeMillis() 48 | 49 | if (time - mExitTime > 2000) { 50 | CommonUtil.showToast(this, "退出") 51 | mExitTime = time 52 | } else { 53 | AppManager.instance.exitApp(this) 54 | } 55 | } 56 | 57 | override fun onDestroy() { 58 | super.onDestroy() 59 | AppManager.instance.removeActivity(this) 60 | } 61 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/view/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.view 2 | 3 | import android.os.Build 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.databinding.DataBindingUtil 9 | import androidx.databinding.ViewDataBinding 10 | import androidx.fragment.app.Fragment 11 | import androidx.lifecycle.ViewModelProvider 12 | import com.wjx.android.mvvm.common.utils.CommonUtil 13 | import com.wjx.android.mvvm.viewmodel.BaseViewModel 14 | 15 | /** 16 | * Created with Android Studio. 17 | * Description: 18 | * @author: Wangjianxian 19 | * @CreateDate: 2020/6/8 8:28 20 | */ 21 | abstract class BaseFragment, DB : ViewDataBinding> : Fragment() { 22 | protected lateinit var mViewModel: VM 23 | 24 | protected lateinit var mDataBinding: DB 25 | 26 | open fun initView() {} 27 | 28 | open fun initData() {} 29 | 30 | open fun reLoad() = initData() 31 | 32 | abstract fun getLayoutId(): Int 33 | 34 | override fun onCreateView( 35 | inflater: LayoutInflater, 36 | container: ViewGroup?, 37 | savedInstanceState: Bundle? 38 | ): View? { 39 | mViewModel = ViewModelProvider(this).get(CommonUtil.getClass(this)) 40 | mDataBinding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false) 41 | mDataBinding.lifecycleOwner = this 42 | return mDataBinding.root 43 | } 44 | 45 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 46 | initView() 47 | initData() 48 | } 49 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/view/BaseLifeCycleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.view 2 | 3 | import android.text.TextUtils 4 | import android.widget.Toast 5 | import androidx.databinding.ViewDataBinding 6 | import androidx.lifecycle.Observer 7 | import com.wjx.android.mvvm.viewmodel.BaseViewModel 8 | import com.wjx.android.mvvm.common.state.State 9 | import com.wjx.android.mvvm.common.state.StateType 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @CreateDate: 2020/6/8 8:29 16 | */ 17 | abstract class BaseLifeCycleActivity, DB : ViewDataBinding> : 18 | BaseActivity() { 19 | 20 | override fun initView() { 21 | showSuccess() 22 | mViewModel.loadState.observe(this, observer) 23 | initDataObserver() 24 | } 25 | 26 | open fun initDataObserver() {} 27 | 28 | 29 | open fun showLoading() {} 30 | 31 | open fun showSuccess() {} 32 | 33 | open fun showError(msg: String) { 34 | if (!TextUtils.isEmpty(msg)) { 35 | Toast.makeText(this, msg, Toast.LENGTH_SHORT).show() 36 | } 37 | } 38 | 39 | open fun showEmpty() {} 40 | 41 | /** 42 | * 分发应用状态 43 | */ 44 | private val observer by lazy { 45 | Observer { 46 | it?.let { 47 | when (it.code) { 48 | StateType.SUCCESS -> showSuccess() 49 | StateType.LOADING -> showLoading() 50 | StateType.ERROR -> showError("网络出现问题啦") 51 | StateType.NETWORK_ERROR -> showError("网络出现问题啦") 52 | StateType.EMPTY -> showEmpty() 53 | } 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/view/BaseLifeCycleFragment.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.view 2 | 3 | import android.text.TextUtils 4 | import android.widget.Toast 5 | import androidx.databinding.ViewDataBinding 6 | import androidx.lifecycle.Observer 7 | import com.wjx.android.mvvm.viewmodel.BaseViewModel 8 | import com.wjx.android.mvvm.common.state.State 9 | import com.wjx.android.mvvm.common.state.StateType 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @CreateDate: 2020/6/8 8:33 16 | */ 17 | abstract class BaseLifeCycleFragment, DB : ViewDataBinding> : 18 | BaseFragment() { 19 | 20 | override fun initView() { 21 | // showLoading() 22 | showSuccess() 23 | mViewModel.loadState.observe(this, observer) 24 | initDataObserver() 25 | } 26 | 27 | open fun initDataObserver() {} 28 | 29 | open fun showLoading() {} 30 | 31 | open fun showSuccess() {} 32 | 33 | open fun showError(msg: String) { 34 | if (!TextUtils.isEmpty(msg)) { 35 | Toast.makeText(context, msg, Toast.LENGTH_SHORT).show() 36 | } 37 | } 38 | 39 | 40 | open fun showEmpty() {} 41 | 42 | private val observer by lazy { 43 | Observer { 44 | it?.let { 45 | when (it.code) { 46 | StateType.SUCCESS -> showSuccess() 47 | StateType.LOADING -> showLoading() 48 | StateType.ERROR -> showError("网络异常") 49 | StateType.NETWORK_ERROR -> showError("网络异常") 50 | StateType.EMPTY -> showEmpty() 51 | } 52 | } 53 | } 54 | } 55 | 56 | 57 | override fun reLoad() { 58 | showLoading() 59 | super.reLoad() 60 | } 61 | } -------------------------------------------------------------------------------- /mvvm/src/main/java/com/wjx/android/mvvm/viewmodel/BaseViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm.viewmodel 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.AndroidViewModel 5 | import androidx.lifecycle.MutableLiveData 6 | import com.wjx.android.mvvm.repository.BaseRepository 7 | import com.wjx.android.mvvm.common.* 8 | import com.wjx.android.mvvm.common.state.State 9 | import com.wjx.android.mvvm.common.utils.CommonUtil 10 | 11 | /** 12 | * Created with Android Studio. 13 | * Description: 14 | * @author: Wangjianxian 15 | * @CreateDate: 2020/6/8 8:16 16 | */ 17 | open class BaseViewModel(application: Application) : AndroidViewModel( 18 | application 19 | ) { 20 | val loadState by lazy { 21 | MutableLiveData() 22 | } 23 | 24 | val mRepository : T by lazy { 25 | (CommonUtil.getClass(this)) 26 | .getDeclaredConstructor(MutableLiveData::class.java) 27 | .newInstance(loadState) 28 | } 29 | 30 | override fun onCleared() { 31 | super.onCleared() 32 | mRepository.unSubscribe() 33 | } 34 | } -------------------------------------------------------------------------------- /mvvm/src/test/java/com/wjx/android/mvvm/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.wjx.android.mvvm 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 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':mvvm' 2 | include ':app' 3 | rootProject.name='WanAndroidMvvm' 4 | --------------------------------------------------------------------------------